問題背景:
某個H5頁面中需要打開手機(jī)本地相冊及照相機(jī)超棺,用戶選擇某幾張圖片之后上傳至服務(wù)器上向族。純H5完成的話,當(dāng)打開相機(jī)或者相冊時棠绘,第一次會正常詢問權(quán)限件相,但是如果用戶點(diǎn)擊了不允許之后,詢問彈窗不再能彈出氧苍,H5處理不了夜矗。
當(dāng)然簡單粗暴地方式就是改為純原生來寫,不過我們的頁面已用了很久让虐,只是新增了一個上傳的功能紊撕,所以還是延續(xù)當(dāng)前頁面,只不過改為原生和H5交互的方式赡突,即e頁面仍是H5頁面对扶,打開相冊相機(jī)的彈窗改為由原生代碼處理,最后將用戶選擇到的圖片傳給H5惭缰,由H5將數(shù)據(jù)傳給服務(wù)端浪南。
中間的交互不再贅述,網(wǎng)上到處都是漱受,只是最后將拿到的數(shù)據(jù)傳給H5這一步有一個小小的坑需注意;
第一步络凿,將圖片轉(zhuǎn)化成字符串:
//當(dāng)我們拿到圖片之后,會將圖片image轉(zhuǎn)化成字符串
NSString *imageStr = [self encodeImageToBase64:image];
//將上述合法的字符串傳給H5
[self p_toJSPramaWithImageBase64Str:imageStr];
此處昂羡,壓縮轉(zhuǎn)化中絮记,base64EncodedStringWithOptions的options必須傳NSDataBase64EncodingEndLineWithCarriageReturn,否則會失斀艉丁5角А!赴穗!
// 將image轉(zhuǎn)成5兆以內(nèi)的二進(jìn)制流憔四,然后轉(zhuǎn)化成base64的字符串
// #define ImageMaxLength 1024.0*1024.0*5 //5M
- (NSString *)encodeImageToBase64:(UIImage *)image {
NSData *imageData = [image compressWithMaxLength:ImageMaxLength];
return [imageData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn];
}
壓縮圖片
//壓縮到多少以內(nèi) 1024.0*1024.0*5 5兆以內(nèi)
-(NSData *)compressWithMaxLength:(NSUInteger)maxLength
{
// Compress by quality
CGFloat compression = 1;
NSData *data = UIImageJPEGRepresentation(self, compression);
//NSLog(@"Before compressing quality, image size = %ld KB",data.length/1024);
if (data.length < maxLength) return data;
CGFloat max = 1;
CGFloat min = 0;
for (int i = 0; i < 6; ++i) {
compression = (max + min) / 2;
data = UIImageJPEGRepresentation(self, compression);
//NSLog(@"Compression = %.1f", compression);
//NSLog(@"In compressing quality loop, image size = %ld KB", data.length / 1024);
if (data.length < maxLength * 0.9) {
min = compression;
} else if (data.length > maxLength) {
max = compression;
} else {
break;
}
}
//NSLog(@"After compressing quality, image size = %ld KB", data.length / 1024);
if (data.length < maxLength) return data;
UIImage *resultImage = [UIImage imageWithData:data];
// Compress by size
NSUInteger lastDataLength = 0;
while (data.length > maxLength && data.length != lastDataLength) {
lastDataLength = data.length;
CGFloat ratio = (CGFloat)maxLength / data.length;
//NSLog(@"Ratio = %.1f", ratio);
CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)),
(NSUInteger)(resultImage.size.height * sqrtf(ratio))); // Use NSUInteger to prevent white blank
UIGraphicsBeginImageContext(size);
[resultImage drawInRect:CGRectMake(0, 0, size.width, size.height)];
resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
data = UIImageJPEGRepresentation(resultImage, compression);
//NSLog(@"In compressing size loop, image size = %ld KB", data.length / 1024);
}
//NSLog(@"After compressing size loop, image size = %ld KB", data.length / 1024);
return data;
}
第二步將數(shù)據(jù)傳給H5:
iosSelectImageSuc為和h5約定好的方法
此處要點(diǎn):字符串必須要拼接 data:image/jpg;base64,否則依然會失敯蛳ⅰ!A苏浴G敝А!
- (void)p_toJSPramaWithImageBase64Str:(NSString *)imageBase64Str {
//oc調(diào)js柿汛,將圖片傳給H5
NSString *str = [@"data:image/jpg;base64," stringByAppendingString:imageBase64Str];
NSString *jsStr = [NSString stringWithFormat:@"%@('%@')",@"iosSelectImageSuc",str];
[self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) {
NSLog(@"%@--%@",result,error);
}];
}