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

情景

项目当中需要截取当前屏幕图片,然后处理分享到微信朋友或朋友圈。微信分享图片需要设置一张不超过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

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

微信截屏分享、图片压缩处理!_第1张图片
这里写图片描述
时间上相差不大,但当任务量大之后,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];

问题来了-主界面卡死。原因如图
微信截屏分享、图片压缩处理!_第2张图片

很明显上面那段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 return [UIImage imageWithData:dataJPEG];//符合要求
    }

    if (imageDataLength >finalSize) {
    [self compressScreenShotToSize:finalSize withContextScale:contextScale-0.1];//递归
    }

    return nil;
}

总结

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

你可能感兴趣的:(iOS(一),经验分享)