查看: 203|回复: 0

[IOS开发教程] iOS如何扫描HEIF格式的二维码图片

发表于 6 天前

一、说在前面

iPhone 7 之后系统相机支持HEIF格式的图片,在扫描二维码时,该格式的图片需要转换成JPG格式才能进行扫描成功。

二、思路

用户在打开系统相册选择完一张照片后,要判断该照片是否是HEIF格式,如果是,进行格式转换之后再扫描JPG图片的内容,得到扫描结果。

三、具体实现

因为过程中用到photoKit,因此需要加入该头文件,#import

  1. @protocol TVUImageManagerDelegate <NSObject>
  2. - (void)letQRCodeVCScanQRCodeImageInAlbum:(BOOL)isHEIFFormat;
  3. @end
  4. @interface TVUImageManager : NSObject
  5. @property (strong, nonatomic) UIImage *jpgImage;
  6. @property (strong, nonatomic) UIImage *selectedImage;
  7. @property (strong, nonatomic) PHAsset *selectedAsset;
  8. @property (nonatomic,strong) id <TVUImageManagerDelegate> delegate;
  9. + (TVUImageManager *)defaultManager;
  10. - (void)doSomethingAfterSelectedImage:(NSDictionary *)info;
  11. @end
复制代码

自定义类:(.mm)

  1. #define IOS9orLater ([UIDevice currentDevice].systemVersion.integerValue >= 9)
  2. @implementation TVUImageManager
  3. #pragma mark - init part
  4. + (TVUImageManager *)defaultManager
  5. {
  6. static TVUImageManager *m_manager = nil;
  7. if (m_manager == nil) {
  8. m_manager = [[TVUImageManager alloc] init];
  9. }
  10. return m_manager;
  11. }
  12. - (id)init
  13. {
  14. self = [super init];
  15. if (self) {
  16. }
  17. return self;
  18. }
  19. #pragma mark - image format part
  20. - (void)doSomethingAfterSelectedImage:(NSDictionary *)info
  21. {
  22. [self getSelectedImagePHAsset:info];
  23. if (self.selectedAsset == nil) {
  24. log4cplus_error("TVUImageManagerLog", "%s:selected image is null",__func__);
  25. return;
  26. }else {
  27. BOOL isHEIF = [self judgeIfAnImageIsHeifFormat];
  28. if (isHEIF) {
  29. log4cplus_error("TVUImageManagerLog", "%s:selected image is HEIF format",__func__);
  30. [self convertImageFormatFromHeifToJpegAndThenScanTheImage];
  31. }else {
  32. log4cplus_error("TVUImageManagerLog", "%s:selected image is not HEIF format",__func__);
  33. self.selectedImage = (UIImage *)[info objectForKey:UIImagePickerControllerOriginalImage];
  34. if (self.selectedImage == nil) {
  35. log4cplus_error("TVUImageManagerLog", "%s:selected image is null",__func__);
  36. return;
  37. }
  38. [self.delegate letQRCodeVCScanQRCodeImageInAlbum:NO];
  39. }
  40. }
  41. }
  42. // Choose a picture from the system album
  43. - (void)getSelectedImagePHAsset:(NSDictionary *)info
  44. {
  45. log4cplus_error("TVUImageManagerLog", "%s:get selected image PHAsset",__func__);
  46. NSURL *imageAssetUrl = [info objectForKey:UIImagePickerControllerReferenceURL];
  47. PHFetchResult *fetchResult = [PHAsset fetchAssetsWithALAssetURLs:[NSArray arrayWithObject:imageAssetUrl] options:nil];
  48. if (fetchResult.count == 0) {
  49. log4cplus_error("TVUImageManagerLog", "%s:fetchResult's count is 0",__func__);
  50. return;
  51. }
  52. self.selectedAsset = (PHAsset*)fetchResult.firstObject;
  53. }
  54. // Determine if the picture is in HEIF format
  55. - (BOOL)judgeIfAnImageIsHeifFormat
  56. {
  57. log4cplus_error("TVUImageManagerLog", "%s:begin to judge if an image is HEIF format",__func__);
  58. __block BOOL isHEIF = NO;
  59. if (IOS9orLater) {
  60. NSArray *resourceList = (NSArray *)[PHAssetResource assetResourcesForAsset:self.selectedAsset];
  61. [resourceList enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  62. PHAssetResource *resource = obj;
  63. NSString *UTI = resource.uniformTypeIdentifier;
  64. if ([UTI isEqualToString:@"public.heif"] || [UTI isEqualToString:@"public.heic"]) {
  65. isHEIF = YES;
  66. *stop = YES;
  67. }
  68. }];
  69. }else {
  70. NSString *UTI = [self.selectedAsset valueForKey:@"uniformTypeIdentifier"];
  71. isHEIF = [UTI isEqualToString:@"public.heif"] || [UTI isEqualToString:@"public.heic"];
  72. }
  73. return isHEIF;
  74. }
  75. // Convert image format from HEIF to JPEG and then scan the image
  76. - (void)convertImageFormatFromHeifToJpegAndThenScanTheImage
  77. {
  78. log4cplus_error("TVUImageManagerLog", "%s:begin to convert image format from HEIF to JPEG",__func__);
  79. [[PHImageManager defaultManager] requestImageDataForAsset:self.selectedAsset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
  80. CIImage *ciImage = [CIImage imageWithData:imageData];
  81. CIContext *context = [CIContext context];
  82. NSData *jpgData = [context JPEGRepresentationOfImage:ciImage colorSpace:ciImage.colorSpace options:@{}];
  83. self.jpgImage = [UIImage imageWithData:jpgData];
  84. [self.delegate letQRCodeVCScanQRCodeImageInAlbum:YES];
  85. }];
  86. }
  87. @end
复制代码

调用:

  1. #pragma mark UIImagePickerControllerDelegate
  2. - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
  3. {
  4. [self.imageMgr doSomethingAfterSelectedImage:info];
  5. }
复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员之家。



回复

使用道具 举报