裁剪图片踩的坑

之前的项目中有个需求:将一个比较长的列表页(用的UITableView)截图然后分享到微信。贴出实现方法:

- (UIImage *)captureScrollView:(UIScrollView *)scrollView {
    UIImage* image = nil;
    UIGraphicsBeginImageContext(scrollView.contentSize);
    {
        CGSize s = scrollView.contentSize;
        //第一个参数表示区域大小。第二个参数表示是否是非透明的。如果需要显示半透明效果,需要传NO,否则传YES。第三个参数就是屏幕密度了,关键就是第三个参数。
        UIGraphicsBeginImageContextWithOptions(s, NO, [UIScreen mainScreen].scale);
        CGPoint savedContentOffset = scrollView.contentOffset;
        CGRect savedFrame = scrollView.frame;
        scrollView.contentOffset = CGPointZero;
        scrollView.frame = CGRectMake(0, 0, SCREEN_WIDTH, scrollView.contentSize.height);
        
        [scrollView.layer renderInContext: UIGraphicsGetCurrentContext()];
        image = UIGraphicsGetImageFromCurrentImageContext();
        
        scrollView.contentOffset = savedContentOffset;
        scrollView.frame = savedFrame;
    }
    UIGraphicsEndImageContext();
    
    if (image != nil) {
        return image;
    }
    return nil;
}

所截的图如下:



这个方法能顺利将tableView截成长图,但是突然有天需求变了:

手续费那一栏不能分享出去,What?

然后我的思路是截两次,第一次把手续费以上的部分截下来,第二次把手续费以下的部分截出来,然后两张图片合成一张图片。思路有了,操起键盘就是一梭子代码:

/**
 Description 从图片中按指定的位置大小截取图片的一部分
 @param image 原始的图片
 @param rect 要截取的区域
 @return 截取出的图片
 */
- (UIImage *)imageFromImage:(UIImage *)image inRect:(CGRect)rect{
    CGImageRef sourceImageRef = [image CGImage];//将UIImage转换成CGImageRef
    /**以下为错误写法*/
    CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height));//按照给定的矩形区域进行剪裁
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];//将CGImageRef转换成UIImage
    return newImage;//返回剪裁后的图片
}

/**
 Description 图片上下拼接
 @param topImage 上图片
 @param bottomImage 下图片
 @return 拼接后的图片
 */
- (UIImage *)composeImgWithTopImage:(UIImage *)topImage bottomImage:(UIImage *)bottomImage {
    if (bottomImage == nil) {
        return topImage;
    }
    CGFloat topImageH = topImage.size.height;
    CGFloat topImageW = topImage.size.width;
    CGFloat bottomImageH = bottomImage.size.height;
    CGFloat bottomImageW = bottomImage.size.width;
    
    CGFloat totalHeight = SCREEN_WIDTH*topImageH/topImageW + SCREEN_WIDTH*bottomImageH/bottomImageW;
    CGSize offScreenSize = CGSizeMake(SCREEN_WIDTH, totalHeight);
    UIGraphicsBeginImageContextWithOptions(offScreenSize, NO, [UIScreen mainScreen].scale);
    CGRect rectTop = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_WIDTH*topImageH/topImageW);
    [topImage drawInRect:rectTop];
    CGRect rectBottom = CGRectMake(0, SCREEN_WIDTH*topImageH/topImageW, SCREEN_WIDTH, SCREEN_WIDTH*bottomImageH/bottomImageW);
    [bottomImage drawInRect:rectBottom];
    UIImage* imagez = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return imagez;
}

然后我两次调用截图传的rect是

CGRect headerClipRect = CGRectMake(0, 0, image.size.width, [self.tableView rectForSection:2].origin.y);
CGRect footerClipRect = CGRectMake(0, [self.tableView rectForSection:3].origin.y, image.size.width, self.tableView.contentSize.height - [self.tableView rectForSection:3].origin.y);

准备就绪,来看看截出来的图是什么样子的:


image.png

what,我到底哪里错了?一脸惊恐

然后反复查找发现- (UIImage *)captureScrollView:(UIScrollView *)scrollView这个方法截出的长图的大小并不是传入的scrollView的contentSize,而是长宽各自乘以手机分辨率[UIScreen mainScreen].scale,所以对长图进行切割的时候,按照给定的矩形区域进行剪裁应该这样传值

CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, CGRectMake(rect.origin.x*[UIScreen mainScreen].scale, rect.origin.y*[UIScreen mainScreen].scale, rect.size.width*[UIScreen mainScreen].scale, rect.size.height*[UIScreen mainScreen].scale));//按照给定的矩形区域进行剪裁

最后的截图合成之后应该是这样的:


image.png

你可能感兴趣的:(裁剪图片踩的坑)