微信截屏分享、图片压缩处理!

来源:互联网 发布:鹊桥佣金数据哪里查看 编辑:程序博客网 时间:2024/06/02 05:46

情景

项目当中需要截取当前屏幕图片,然后处理分享到微信朋友或朋友圈。微信分享图片需要设置一张不超过32K大小的缩略图,超过32K将导致分享失败。功能是已经上线,过程中有些细节和注意的地方,在这里分享下(不妥之处,望指正!)。

上代码前先拓展下:

1、关于UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)参数;

1)size :
参数size为新创建的位图上下文的大小。它同时是由UIGraphicsGetImageFromCurrentImageContext函数返回的图形大小

2)opaque:
如果图形完全不用透明,设置为YES以优化位图的存储

3)scale:
缩放因子 iPhone 4是2.0,其他是1.0。虽然这里可以用[UIScreen mainScreen].scale来获取,但实际上设为0后,系统就会自动设置正确的比例了.

拓展

以前的iphone 设备屏幕分辨率都是320*480,后来apple 在iPhone 4中采用了名为Retina的显示技术,iPhone 4采用了960x640像素分辨率的显示屏幕。由于屏幕大小没有变,还是3.5英寸,分辨率的提升将iPhone 4的显示分辨率提升至iPhone 3GS的四倍,每英寸的面积里有326个像素。
scale属性的值有两个:
scale = 1; 的时候是代表当前设备是320*480的分辨率(就是iphone4之前的设备)
scale = 2; 的时候是代表分辨率为640*960的分辨率

2、关于UIImageJPEGRepresentation和UIImagePNGRepresentation

关于二者区别,可以看他们处理同一张图的效果,如图:

UIImagePNGRepresentation处理图片
这里写图片描述
时间上相差不大,但当任务量大之后,UIImageJPEGRepresentation处理图片高效率就会更加体现出来;另外UIImageJPEGRepresentation处理图片后的大小上优势也是相当明显。
我们将选用UIImageJPEGRepresentation方法来处理截屏图片。

正文

1、上代码。这段代码也是在网上查阅其他同胞后整理的!

      UIGraphicsBeginImageContextWithOptions([UIScreen mainScreen].bounds.size, NO, 1.0);        [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];        UIImage * img = UIGraphicsGetImageFromCurrentImageContext();        UIGraphicsEndImageContext();        float scaleNum =1.0;        NSData * dataJPEG =UIImageJPEGRepresentation(img, 1.0);        NSLog(@"UIImageJPEGRepresentation处理图片--%.2fK", dataJPEG.length/1024.0);            float imageDataLength = dataJPEG.length/1024.0;            while (imageDataLength>32.0) {                scaleNum = scaleNum - 0.01;                dataJPEG =UIImageJPEGRepresentation(img, scaleNum);                imageDataLength = dataJPEG.length/1024.0;                NSLog(@"压缩后图片大小%.2fk",imageDataLength);            }            UIImage * finalImg = [UIImage imageWithData:dataJPEG];

问题来了-主界面卡死。原因如图
这里写图片描述

很明显上面那段while,导致了死循环。另外我们发现上面那段代码将图片压缩到55.58K后就不能再小了!(这导致iPhone能正常分享,iPad就卡住)

2、解决办法改变UIImageJPEGRepresentation第二个缩放参数不奏效情况下,改变UIGraphicsBeginImageContextWithOptions第三个参数的值!(过程涉及耗时运算,这里将计算任务放进异步线程)

#define asy(task) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{task})#define getMainQueue(task)  dispatch_async(dispatch_get_main_queue(), ^{task})- (IBAction)screenShot:(UIButton *)sender {    asy(     UIImage * finalImage = [self compressScreenShotToSize:32.0 withContextScale:[UIScreen mainScreen].scale];        getMainQueue(//回主线程        self.finalImage.image = finalImage;        );    );    }-(void)compressScreenShotToSize:(CGFloat)finalSize withContextScale:(CGFloat)contextScale{    float JPEGScale = 1.0;    //位图    UIGraphicsBeginImageContextWithOptions([UIScreen mainScreen].bounds.size, NO, contextScale);    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();    UIGraphicsEndImageContext();    //data    NSData * dataJPEG =UIImageJPEGRepresentation(img, JPEGScale);    float imageDataLength = dataJPEG.length/1024.0;    while (imageDataLength>finalSize) {        JPEGScale = JPEGScale - 0.2;        if (JPEGScale<0.0) {            break;//跳出        }        dataJPEG =UIImageJPEGRepresentation(img, JPEGScale);        imageDataLength = dataJPEG.length/1024.0;    }       if (imageDataLength <finalSize) {        return [UIImage imageWithData:dataJPEG];//符合要求    }    if (imageDataLength >finalSize) {    [self compressScreenShotToSize:finalSize withContextScale:contextScale-0.1];//递归    }    return nil;}

总结

整个过程并没有涉及复杂的内容,皆为基础,如果大家有更好更高效方式,希望分享下。不足之处请指正!

原创粉丝点击