IOS从屏幕截图并裁剪压缩到指定宽高

时间:2022-09-26 15:24:18

Author:baohonglai
Email:baohonglai@gmail.com
版权所有。转载本BLOG内任何文章,请以超链接形式注明出处。

前段时间处理了一个问题,从指定view上截取图片并按照指定宽高输出。网上找了很多办法,只找到了从view截图的方法,并没有一次性按照指定宽高的方法输出,下面总结下自己的方法,当然肯定有更高效的方法,望指点一下。

首先先写一个图片裁剪以及scale的接口

- (UIImage *)imageScaleWithImage:(UIImage*) image
                       withWidth:(CGFloat ) width
                      withHeight:(CGFloat) height
{
    if (!image) {
        return nil;
    }
    EAGLContext *previousContext = [EAGLContext currentContext];
    [EAGLContext setCurrentContext:nil];
    CIImage *ciimage = [CIImage imageWithCGImage:image.CGImage];
    CGFloat imageWidth = ciimage.extent.size.width;//需要取UIimage里面的CIImage 的宽高
    CGFloat imageHeight = ciimage.extent.size.height;
    CGFloat srcRatio = imageWidth/(imageHeight*1.0);
    CGFloat desRatio = width/(height*1.0);

    CIContext *context = [CIContext contextWithOptions:nil];

    //scale
    CGFloat scale = srcRatio < desRatio ? (width/imageWidth) : (height/imageHeight);
    ciimage = [ciimage imageByApplyingTransform:CGAffineTransformMakeScale(scale, scale)];

    CGRect extent = ciimage.extent;
    CGRect resultRect = CGRectMake(extent.origin.x+(extent.size.width - width)/2, extent.origin.y+(extent.size.height - height)/2, width, height);
    CGImageRef ref = [context createCGImage:ciimage fromRect:resultRect];
    UIImage *resultImage = [UIImage imageWithCGImage:ref];
    [EAGLContext setCurrentContext:previousContext];
    return resultImage;
}

然后就是从指定的view上获取UIimage了

- (UIImage*) snapshotWithWidth:(CGFloat) width
                withHeight:(CGFloat) height
{
    UIView *view =self.view;
    if ([view isKindOfClass:NSClassFromString(@"UIView")]) {
        UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, 0);
        [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
        UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        UIImage *resutImage = [self imageScaleWithImage:viewImage withWidth:width withHeight:height];
        return resultImage;
    }
  return nil
}

注意上面这段代码可能会耗时比较多,所以具体实现的时候需要用异步的方式。