本篇文章主要寫的是轉(zhuǎn)換過程中遇到的幾個令人頭疼的問題并解決,轉(zhuǎn)換的和顯示的主要代碼參考了SDWebImage/Web和# iOS-WebP;
使用的庫:'libwebp','~> 1.0.0'
1.遇到的問題及解決
出問題的圖片主要是iphone6及以上手機截頻的圖片,這種圖片有一個共同特性:包含Alpha通道;以及少部分不包含Alpha通道且從網(wǎng)絡(luò)下載的圖片。
1> 圖片轉(zhuǎn)換后無法顯示
這個問題出現(xiàn)在iOS11及以上系統(tǒng)機型。
主要原因:
如下方法中代碼:
+ (UIImage *)imageWithWebPData:(NSData *)imgData error:(NSError **)error;
有誤代碼:
CGDataProviderRef provider = CGDataProviderCreateWithData(config, data, config->options.scaled_width * config->options.scaled_height * 4, free_image_data);
config->options.scaled_width和config->options.scaled_height的值都為0;
解決:
CGDataProviderRef provider = CGDataProviderCreateWithData(&config, data,width * height * 4 , free_image_data);
2> 轉(zhuǎn)換成webP直接在google瀏覽器顯示或者再轉(zhuǎn)換成png顯示后的樣式
解決:
方法:
+ (NSData *)convertToWebP:(UIImage *)image
compressionQuality:(CGFloat)quality
alpha:(CGFloat)alpha
preset:(WebPPreset)preset
configBlock:(void (^)(WebPConfig *))configBlock
error:(NSError **)error;
舊代碼:
if (alpha < 1) {
image = [self webPImage:image withAlpha:alpha];
}
新代碼:
image = [self webPImage:image withAlpha:alpha];
修改代碼轉(zhuǎn)換后的樣式:
依舊有問題。
3> 最后一步
經(jīng)過測試發(fā)現(xiàn)只有將從相冊或者拍照獲取的圖片按照寬 = 320的整倍數(shù),高 = 320 /(原始圖片寬/原始圖片高)的方式轉(zhuǎn)換后,才能完整的將圖片轉(zhuǎn)換為webP并展示。
方法:
+ (NSData *)convertToWebP:(UIImage *)image
compressionQuality:(CGFloat)quality
alpha:(CGFloat)alpha
preset:(WebPPreset)preset
configBlock:(void (^)(WebPConfig *))configBlock
error:(NSError **)error;
加入新的代碼:
CGFloat scale = image.size.width / image.size.height;
CGFloat imageWidth = 320 * 2;
if (image.size.width > 1000){
imageWidth = 320 * 3;
}
UIImage *resizeImage = [self imageResize:image size:CGSizeMake(imageWidth,imageWidth/scale)];
resizeImage = [self webPImage:resizeImage withAlpha:alpha];
CGImageRef webPImageRef = resizeImage.CGImage;
新代碼轉(zhuǎn)換后的效果:
如果不按這種比列去轉(zhuǎn)換則會出現(xiàn)如下樣式:
UIImage *resizeImage = [self imageResize:image size:CGSizeMake(414,736)];
- (UIImage)imageResize:(UIImage)image size:(CGSize)size ;方法實現(xiàn)的代碼
+ (UIImage*)imageResize:(UIImage*)image size:(CGSize)size {
UIGraphicsBeginImageContext(size);
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}
4> 最最最后一步
經(jīng)過以上散步發(fā)現(xiàn)直拖入到項目內(nèi)部的圖片可以正常轉(zhuǎn)換和展示了,但是經(jīng)過photos框架從相冊中獲取的圖片仍然無法正常轉(zhuǎn)換。
解決辦法如下:
UIImage *convertImage = [UIImage imageWithData:UIImageJPEGRepresentation(image, 1.0)];
將從相冊中的獲取的圖片通過UIImageJPEGRepresentation裝換成data再轉(zhuǎn)換為UIImage,將現(xiàn)在在的image執(zhí)行上訴的1,2,3步即可獲。
完整代碼如下:
+ (NSData *)convertToWebP:(UIImage *)image
compressionQuality:(CGFloat)quality
alpha:(CGFloat)alpha
preset:(WebPPreset)preset
configBlock:(void (^)(WebPConfig *))configBlock
error:(NSError **)error
{
UIImage *convertImage = [UIImage imageWithData:UIImageJPEGRepresentation(image, 1.0)];
CGFloat scale = convertImage.size.width / convertImage.size.height;
CGFloat imageWidth = 320 * 2;
if (convertImage.size.width > 1000){
imageWidth = 320 * 3;
}
UIImage *resizeImage = [self imageResize:convertImage size:CGSizeMake(imageWidth,imageWidth/scale)];
resizeImage = [self webPImage:resizeImage withAlpha:alpha];
CGImageRef webPImageRef = resizeImage.CGImage;
size_t webPBytesPerRow = CGImageGetBytesPerRow(webPImageRef);
size_t webPImageWidth = CGImageGetWidth(webPImageRef);
size_t webPImageHeight = CGImageGetHeight(webPImageRef);
... ...
2.其它
我們服務(wù)器為了減小服務(wù)器存儲圖片空間的大小,經(jīng)過調(diào)研選用webP格式圖片為最佳的方案。但是同事在調(diào)研時未能測試出以上問題。我接手這個問題開始以為是相冊框架的問題,經(jīng)過測試排除。前后總共花了兩天時間測試才解決了這個幾個坑,以下是demo地址:https://github.com/moreFine/WWWebPConvert。