开始
在 UIKit 中有两种图片质量压缩与转换的写法:
1 | UIImageJPEGRepresentation(image, 0.75); |
目标
用 Core Foundation
实现相同功能
流程
创建
Translate
类的相关文件- 包含
Translate.h
和Translate.m
文件 - 删除所有
@interface
和@implementation
相关的内容- 这一步可不做, 之后的内容并没有操作
Translate
的类或实例对象
- 这一步可不做, 之后的内容并没有操作
- 包含
在
Translate.h
中创建结果相关的 Blok
1
typedef void(^complet)(BOOL isSuccess);
创建格式转换相关的枚举
1
2
3
4typedef NS_ENUM(NSUInteger, kUTType) {
kUTTypeJPEG,
kUTTypePNG
};声明定义压缩转换方法
1
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
中引入相关头文件
1
2#import <ImageIO/ImageIO.h>
#import <UIKit/UIKit.h>开始实现压缩转换方法
1
2
3
4
5
6
7void TImageRepresentation(NSString *sourceImagePath,
NSString *targetImagePatch,
double compressionQuality,
kUTType type,
complet complet) {
// do something...
}开启子线程
1
2
3dispatch_async(dispatch_get_global_queue(0, 0), ^{
// do something...
}获取图片源数据
1
CGImageRef image = [UIImage imageWithContentsOfFile:sourceImagePath].CGImage;
创建接收最终数据的目标容器
1
CFMutableDataRef imageData = CFDataCreateMutable(NULL, 0);
判断转换格式
1
2
3
4
5
6
7
8
9
10
11
12
13CFStringRef typeStr;
switch (type) {
case kUTTypeJPEG:
typeStr = CFSTR("public.jpeg");
break;
case kUTTypePNG:
typeStr = CFSTR("public.png");
break;
default:
break;
}创建转换者对象, 进行质量压缩和转换
1
CGImageDestinationRef destination = CGImageDestinationCreateWithData(imageData, typeStr, 1, NULL);
CGImageDestinationCreateWithData(_,_,_,_)
函数的相关详情创建所需参数
1
NSDictionary *properties = @{ (__bridge id)kCGImagePropertyMakerNikonQuality : @(compressionQuality) };
向转换者对象添加图片数据和参数数据
1
CGImageDestinationAddImage(destination, image, (__bridge CFDictionaryRef)properties);
CGImageDestinationAddImage(_,_,_)
函数的相关详情检测转换是否成功, 如失败直接释放数据源与转换者对象, 并结束所有流程
1
2
3
4
5
6
7
8
9
10
11
12if (!CGImageDestinationFinalize(destination)) {
CFRelease(imageData);
imageData = NULL;
if (complet) {
dispatch_async(dispatch_get_main_queue(), ^{
complet(NO);
});
}
// 释放转换者对象
CFRelease(destination);
return;
}成功后释放转换者对象
1
CFRelease(destination);
根据输出地址, 创建输出流
1
2
3CFAllocatorRef allocator = CFAllocatorGetDefault();
NSURL *fileUrl = [NSURL fileURLWithPath:targetImagePatch];
CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(allocator, (__bridge CFURLRef)fileUrl);开启输出流
1
CFWriteStreamOpen(writeStream);
向目标容器写入最终数据
1
CFIndex result = CFWriteStreamWrite(writeStream, CFDataGetBytePtr(imageData), CFDataGetLength(imageData));
CFWriteStreamWrite(_,_,_)
函数的相关详情判断最终数据写入是否成功
不成功的返回值为 -1, 成功则为输出的字节流长度
1
2
3
4
5
6
7
8
9
10
11
12
13if (result != -1) {
if (complet) {
dispatch_async(dispatch_get_main_queue(), ^{
complet(YES);
});
}
} else {
if (complet) {
dispatch_async(dispatch_get_main_queue(), ^{
complet(NO);
});
}
}关闭输出流
1
CFWriteStreamClose(writeStream);
释放目标容器
1
CFRelease(imageData);
使用
简单使用:
1 | NSString *sourceImagePath = @"要进行处理的图片的路径"; |