美文网首页
iOS 保存原图相关

iOS 保存原图相关

作者: 木木子席 | 来源:发表于2019-03-15 17:00 被阅读0次
    在app开发中,经常会遇到保存图片的需求。
    

    在对图片数据要求不高的情况下,可以直接拿到UIImage对象,然后保存这个UIImage。
    比如我们常用SDWebImage框架来下载和获取图片。

    示例图片.JPG
    SDWebImageDownloader *manager = [SDWebImageDownloader sharedDownloader];
        [manager downloadImageWithURL:imageUrl options:SDWebImageDownloaderUseNSURLCache progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) {
            saveToAsset(image); 
        }];
    

    可以看到SDWebImage的下载方法给我们回调四个数据,其中一个是UIImage,一个是原始数据NSData。当我们直接存的UIImage,其实我们保存的并不是原图,这个图片保存后比原图小很多,很多信息都会丢失,比如我们打印示例图片中的EXIF信息,会发现有很大的区别。

      原图的exif:
    {
    ColorModel = RGB;
    DPIHeight = 72;
    DPIWidth = 72;
    Depth = 8;
    PixelHeight = 3968;
    PixelWidth = 2976;
    ProfileName = "sRGB IEC61966-2.1";
    "{Exif}" =     {
        ApertureValue = "1.69";
        BrightnessValue = 0;
        ColorSpace = 1;
        ComponentsConfiguration =         (
            1,
            2,
            3,
            0
        );
        CompressedBitsPerPixel = "0.95";
        Contrast = 0;
        CustomRendered = 1;
        DateTimeDigitized = "2019:03:13 20:30:06";
        DateTimeOriginal = "2019:03:13 20:30:06";
        DigitalZoomRatio = 1;
        ExifVersion =         (
            2,
            1
        );
        ExposureBiasValue = 0;
        ExposureMode = 0;
        ExposureProgram = 2;
        ExposureTime = "0.01";
        FNumber = "1.8";
        FileSource = 3;
        Flash = 0;
        FlashPixVersion =         (
            1,
            0
        );
        FocalLenIn35mmFilm = 27;
        FocalLength = "4.75";
        GainControl = 0;
        ISOSpeedRatings =         (
            80
        );
        LightSource = 1;
        MaxApertureValue = "1.69";
        MeteringMode = 5;
        PixelXDimension = 2976;
        PixelYDimension = 3968;
        Saturation = 0;
        SceneCaptureType = 0;
        SceneType = 1;
        SensingMethod = 2;
        Sharpness = 0;
        ShutterSpeedValue = "29.89730002523341";
        SubjectDistRange = 0;
        SubsecTime = 298723;
        SubsecTimeDigitized = 298723;
        SubsecTimeOriginal = 298723;
        WhiteBalance = 0;
    };
    "{GPS}" =     {
        Altitude = 0;
        AltitudeRef = 1;
        DateStamp = "2019:03:13";
        GPSVersion =         (
            2,
            2,
            0,
            0
        );
        Latitude = "31.98787166666667";
        LatitudeRef = N;
        Longitude = "118.7609866666667";
        LongitudeRef = E;
        TimeStamp = "12:30:04";
    };
    "{JFIF}" =     {
        DensityUnit = 1;
        JFIFVersion =         (
            1,
            0,
            1
        );
        XDensity = 96;
        YDensity = 96;
    };
    "{TIFF}" =     {
        DateTime = "2019:03:13 20:30:06";
        ImageDescription = hdrpl;
        Make = HUAWEI;
        Model = "HMA-AL00";
        Orientation = 0;
        ResolutionUnit = 2;
        Software = "HMA-AL00 9.0.0.195(C00E195R1P21)";
        XResolution = 72;
        YResolution = 72;
    };
    
      用UIImage保存后图片的exif:
          {
        ColorModel = RGB;
        DPIHeight = 72;
        DPIWidth = 72;
        Depth = 8;
        Orientation = 1;
        PixelHeight = 3968;
        PixelWidth = 2976;
        ProfileName = "sRGB IEC61966-2.1";
        "{Exif}" =     {
            ColorSpace = 1;
            ComponentsConfiguration =         (
                1,
                2,
                3,
                0
            );
            ExifVersion =         (
                2,
                2,
                1
            );
            FlashPixVersion =         (
                1,
                0
            );
            PixelXDimension = 2976;
            PixelYDimension = 3968;
            SceneCaptureType = 0;
        };
        "{JFIF}" =     {
            DensityUnit = 0;
            JFIFVersion =         (
                1,
                0,
                1
            );
            XDensity = 72;
            YDensity = 72;
        };
        "{TIFF}" =     {
            Orientation = 1;
            ResolutionUnit = 2;
            XResolution = 72;
            YResolution = 72;
        };
    }
    

    两者对比,会发现照片中GPS等信息都丢失了。当项目要求保证exif信息不丢失时,一种方法是直接保存原始数据,也就是直接保存返回NSData二进制数据。另一种方法是将原图的EXIF信息取出,再设置给处理好的图片。

    这里记录下直接保存图片到相册的相关方法:

    - (void)saveImageWithData:(NSData *)data imageUrl:(NSString *)imageUrl completion:(void(^)(void))completion{
    //    [self getExifInfoWithImageData:data];
        BOOL dataValid = data && ([data isKindOfClass:NSData.class]||[data isKindOfClass:UIImage.class]);
        if (!dataValid) {
           //保存失败;
            return;
        }
        __block NSString* localIdentifier;
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
            PHAssetCreationRequest *createRequest = nil;
            PHAssetResourceCreationOptions *options = [[PHAssetResourceCreationOptions alloc] init];
            createRequest = [PHAssetCreationRequest creationRequestForAsset];
            [createRequest addResourceWithType:PHAssetResourceTypePhoto data:data options:options];
            localIdentifier = createRequest.placeholderForCreatedAsset.localIdentifier;
        } completionHandler:^(BOOL success, NSError * _Nullable error) {
            if (success && localIdentifier) {
                //以下代码是将图片放入新建的APP相册中,并给保存过的图片添加唯一标识,用做下载去重,如果不需要可以跳过
                //成功后取相册中的图片对象
                PHFetchResult *result = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil];
                PHAsset* asset = [result firstObject];
                //获取自己app的相册  这里不实现方法了
                PHAssetCollection *collection = [self getCollection];
                // 3. 将“相机胶卷”中的图片添加到新的相册
                [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
                    PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection];
                    [request addAssets:@[asset]];
                    //项目中的图片url有objId标识,具体看需求来
                    NSString *objID = [imageUrl componentsSeparatedByString:@"="][1];
                    if (objID) {
                         //给下载过的objID绑定一个相片标识   具体代码不实现了
                        [USER_TOOL addImageWithObjectID:objID localIdentifier:localIdentifier];
                    }
                } completionHandler:^(BOOL success, NSError * _Nullable error) {
                    NSLog(@"成功保存到相簿:%@", collection.localizedTitle);
                    if (completion) {
                        completion();
                    }
                }];
            }else{
                NSLog(@"保存失败 error: %@",error);
            }
        }];
    }
    

    获取exif的相关方法

    - (NSMutableDictionary *)getExifInfoWithImageData:(NSData *)imageData{
        CGImageSourceRef cImageSource = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
        NSDictionary *dict =  (NSDictionary *)CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(cImageSource, 0, NULL));
        NSMutableDictionary *dictInfo = [NSMutableDictionary dictionaryWithDictionary:dict];
        NSLog(@"%@",dictInfo);
        return dictInfo;
    }
    

    相关文章

      网友评论

          本文标题:iOS 保存原图相关

          本文链接:https://www.haomeiwen.com/subject/pchrmqtx.html