美文网首页iOS小功能点iOS Developer
Core Foundation 学习 -- 图片质量的压缩与转换

Core Foundation 学习 -- 图片质量的压缩与转换

作者: Norld | 来源:发表于2017-03-22 14:06 被阅读208次

原地址: Norld's Blog -- Core Foundation 学习 -- 图片质量的压缩与转换

开始

  在 UIKit 中有两种图片质量压缩与转换的写法:

UIImageJPEGRepresentation(image, 0.75);
UIImagePNGRepresentation(image);

目标

  用 Core Foundation 实现相同功能

流程

  • 创建 Translate 类的相关文件

    • 包含 Translate.hTranslate.m 文件
    • 删除所有 @interface@implementation 相关的内容
      • 这一步可不做, 之后的内容并没有操作 Translate 的类或实例对象
  • Translate.h

    • 创建结果相关的 Blok
    typedef void(^complet)(BOOL isSuccess);
    
    • 创建格式转换相关的枚举
    typedef NS_ENUM(NSUInteger, kUTType) {
        kUTTypeJPEG,
        kUTTypePNG
    };
    
    • 声明定义压缩转换方法
    extern void TImageRepresentation(NSString *sourceImagePath,NSString *targetImagePatch,double compressionQuality,kUTType type,complet complet);
    
参数 格式 定义
sourceImagePath NSString * 原图片文件路径
targetImagePatch NSString * 输出路径, 必须包含文件名与后缀
compressionQuality double 图片压缩质量, 范围 0~1, 1为最高质量
type kUTType 输出格式, 务必与输出路径的后缀相同
complet Block 输出结果的回调
  • Translate.m

    • 引入相关头文件
    #import <ImageIO/ImageIO.h>
    #import <UIKit/UIKit.h>
    
    • 开始实现压缩转换方法
    void TImageRepresentation(NSString *sourceImagePath,
                                NSString *targetImagePatch,
                                double compressionQuality,
                                kUTType type,
                                complet complet) {
        // do something...
    }
    
    • 开启子线程
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        // do something...
    }
    
    • 获取图片源数据
    CGImageRef image = [UIImage imageWithContentsOfFile:sourceImagePath].CGImage;
    
    • 创建接收最终数据的目标容器
    CFMutableDataRef imageData = CFDataCreateMutable(NULL, 0);
    
    • 判断转换格式
    CFStringRef typeStr;
    switch (type) {
        case kUTTypeJPEG:
            typeStr = CFSTR("public.jpeg");
            break;
                
        case kUTTypePNG:
            typeStr = CFSTR("public.png");
            break;
                
        default:
            break;
    }
    
    • 创建转换者对象, 进行质量压缩和转换
    CGImageDestinationRef destination = CGImageDestinationCreateWithData(imageData, typeStr, 1, NULL);
    

    CGImageDestinationCreateWithData(_,_,_,_) 函数的相关详情

    • 创建所需参数
    NSDictionary *properties = @{ (__bridge id)kCGImageDestinationLossyCompressionQuality : @(compressionQuality) };
    
    • 向转换者对象添加图片数据和参数数据
    CGImageDestinationAddImage(destination, image, (__bridge CFDictionaryRef)properties);
    

    CGImageDestinationAddImage(_,_,_) 函数的相关详情

    • 检测转换是否成功, 如失败直接释放数据源与转换者对象, 并结束所有流程
    if (!CGImageDestinationFinalize(destination)) {
        CFRelease(imageData);
        imageData = NULL;
        if (complet) {
            dispatch_async(dispatch_get_main_queue(), ^{
                complet(NO);
            });
        }
        // 释放转换者对象
        CFRelease(destination);
        return;
    }
    
    • 成功后释放转换者对象
    CFRelease(destination);
    
    • 根据输出地址, 创建输出流
    CFAllocatorRef allocator = CFAllocatorGetDefault();
    NSURL *fileUrl = [NSURL fileURLWithPath:targetImagePatch];
    CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(allocator, (__bridge CFURLRef)fileUrl);
    
    • 开启输出流
    CFWriteStreamOpen(writeStream);
    
    • 向目标容器写入最终数据
    CFIndex result = CFWriteStreamWrite(writeStream, CFDataGetBytePtr(imageData), CFDataGetLength(imageData));
    

    CFWriteStreamWrite(_,_,_) 函数的相关详情

    • 判断最终数据写入是否成功

      不成功的返回值为 -1, 成功则为输出的字节流长度

    if (result != -1) {
        if (complet) {
            dispatch_async(dispatch_get_main_queue(), ^{
                complet(YES);
            });
        }
    } else {
        if (complet) {
            dispatch_async(dispatch_get_main_queue(), ^{
                complet(NO);
            });
        }
    }
    
    • 关闭输出流
    CFWriteStreamClose(writeStream);
    
    • 释放目标容器
    CFRelease(imageData);
    

使用

  简单使用:

NSString *sourceImagePath = @"要进行处理的图片的路径";
NSString *targetImagePath = @"处理完成的输出路径";
double compressionQuality = 0.75f;
kUTType targetImageType = kUTTypeJPEG;
    
TImageRepresentation(sourceImagePath, targetImagePath, compressionQuality, targetImageType, ^(BOOL isSuccess) {
    if (isSuccess) {
        NSLog(@"Winer");
    } else {
        NSLog(@"Loser");
    }
});

相关

相关文章

网友评论

  • 0e69335b0e64:压缩的属性写错了,不是kCGImagePropertyMakerNikonQuality,应该是kCGImageDestinationLossyCompressionQuality
    Norld:感谢指出文中的错误:+1:
    文章已修改
  • small路飞:谢谢楼主分享
    Vincent20481:@small路飞 路飞是你吗?

本文标题:Core Foundation 学习 -- 图片质量的压缩与转换

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