iOS图片的渲染
2016-01-27 20:39
281 查看
最近写项目都要吐了,看见自己的代码就恶心,尽管是自己的心血,但是原本已经写完的代码,但是老板却又改了需求,唉,尽管界面没怎么变,但是你不知道现在是牵一发而动全身吗。牢骚一下,但是还得皱着眉头改啊。
最近收获好大的几个地方,分享一下。以供今后的学习。
1.第一个是改变图片的颜色,我封装了一个类。
这是.h文件
这是.m文件
理解:图片渲染的那个方法不是我自己写的,是在网上找到的,在这里要说声谢谢这位神了。首先这个方法渲染的图片必须是本地的图片,我这个方法将图片下载到本地后然后进行渲染的(其实这样说是不准确的,主要是方法中的图片的data不能为空)。之前用的是SDWebImage,但是我发现sd从网络获取图片中,将文件存放到本地是个异步方法的,也就是sd下载图片和存储图片是不同的进程中实现的,这样虽然图片已经显示到界面上,但是你在本地是获取不到图片数据的。这样程序就cash了。大家可以动手体验一下。
最近收获好大的几个地方,分享一下。以供今后的学习。
1.第一个是改变图片的颜色,我封装了一个类。
这是.h文件
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface AsynNetWorkHandleImage : NSObject // 定义一个block属性 @property (nonatomic, copy) void(^block)(UIImage *image); // 定义类方法 + (instancetype)requestDataForImageWithURLString:(NSString *)urlString block:(void(^)(UIImage *image))block; @end
这是.m文件
#import "AsynNetWorkHandleImage.h" @implementation AsynNetWorkHandleImage - (instancetype)init { self = [super init]; if (self) { } return self; } + (instancetype)requestDataForImageWithURLString:(NSString *)urlString block:(void(^)(UIImage *image))block { AsynNetWorkHandleImage *asyn = [[AsynNetWorkHandleImage alloc] init]; asyn.block = block; // 先将字符串进行转码 urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; NSArray *array = [urlString componentsSeparatedByString:@"/"]; NSArray *arr =NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); // 拼接最终得到图片的存储路径 NSString *imagePath = [NSString stringWithFormat:@"%@/%@", [arr firstObject], [array lastObject]]; NSFileManager *manager = [NSFileManager defaultManager]; // 如果图片已经存到本地 if ([manager fileExistsAtPath:imagePath]) { NSData *data = [NSData dataWithContentsOfFile:imagePath]; UIImage *image = [UIImage imageWithData:data]; ; asyn.block([asyn grayscale:image type:1]); } // 如果图片没有存到本地, 则进行数据请求 else { NSURL *url = [NSURL URLWithString:urlString]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; request.HTTPMethod = @"GET"; NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration]; NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error == nil) { UIImage *image = [UIImage imageWithData:data]; asyn.block([asyn grayscale:image type:1]); // 同时将数据存入本地 [data writeToFile:imagePath atomically:YES]; } else { NSLog(@"图片数据请求失败"); } }]; // 开始执行任务 [task resume]; } return asyn; } // 渲染图片的方法 - (UIImage *)grayscale:(UIImage *)anImage type:(int)type { CGImageRef imageRef = anImage.CGImage; size_t width = CGImageGetWidth(imageRef); size_t height = CGImageGetHeight(imageRef); size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef); size_t bitsPerPixel = CGImageGetBitsPerPixel(imageRef); size_t bytesPerRow = CGImageGetBytesPerRow(imageRef); CGColorSpaceRef colorSpace = CGImageGetColorSpace(imageRef); CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); bool shouldInterpolate = CGImageGetShouldInterpolate(imageRef); CGColorRenderingIntent intent = CGImageGetRenderingIntent(imageRef); CGDataProviderRef dataProvider = CGImageGetDataProvider(imageRef); CFDataRef data = CGDataProviderCopyData(dataProvider); UInt8 *buffer = nil; // 代码保护, 数据存在时执行 if (data) { buffer = (UInt8*)CFDataGetBytePtr(data); NSUInteger x, y; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { UInt8 *tmp; tmp = buffer + y * bytesPerRow + x * 4; UInt8 red,green,blue; red = *(tmp + 0); green = *(tmp + 1); blue = *(tmp + 2); UInt8 brightness; switch (type) { case 1: brightness = (77 * red + 28 * green + 151 * blue) / 256; *(tmp + 0) = brightness; *(tmp + 1) = brightness; *(tmp + 2) = brightness; break; case 2: *(tmp + 0) = red; *(tmp + 1) = green * 0.7; *(tmp + 2) = blue * 0.4; break; case 3: *(tmp + 0) = 255 - red; *(tmp + 1) = 255 - green; *(tmp + 2) = 255 - blue; break; default: *(tmp + 0) = red; *(tmp + 1) = green; *(tmp + 2) = blue; break; } } } CFDataRef effectedData = CFDataCreate(NULL, buffer, CFDataGetLength(data)); CGDataProviderRef effectedDataProvider = CGDataProviderCreateWithCFData(effectedData); CGImageRef effectedCgImage = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpace, bitmapInfo, effectedDataProvider, NULL, shouldInterpolate, intent); UIImage *effectedImage = [[UIImage alloc] initWithCGImage:effectedCgImage]; CGImageRelease(effectedCgImage); CFRelease(effectedDataProvider); CFRelease(effectedData); CFRelease(data); return effectedImage; } return nil; } @end
理解:图片渲染的那个方法不是我自己写的,是在网上找到的,在这里要说声谢谢这位神了。首先这个方法渲染的图片必须是本地的图片,我这个方法将图片下载到本地后然后进行渲染的(其实这样说是不准确的,主要是方法中的图片的data不能为空)。之前用的是SDWebImage,但是我发现sd从网络获取图片中,将文件存放到本地是个异步方法的,也就是sd下载图片和存储图片是不同的进程中实现的,这样虽然图片已经显示到界面上,但是你在本地是获取不到图片数据的。这样程序就cash了。大家可以动手体验一下。
相关文章推荐
- 怎么设置启动界面ios 8设置状态栏字体颜色
- [iOS]iPhone利用<极光推送>实现远程推送
- iOS中常见的报错及解决方案
- 2015年最新苹果开发者账号注册流程详解
- 转: ios学习入门进阶
- 转:ios学习指南
- iOS开发:自定义tableViewCell处理的问题
- iOS-NSNumber对象介绍
- iOS:自定义代码块{ }
- iOS如何定位 IDFA?
- iOS 隐藏状态栏
- iPhone/iOS开启个人热点的纵向适配小结
- iOS图片验证码使用SDWeb实现的加载如何实现清理缓存点击刷新
- 与现有的应用程序集成
- iOS自定义视频LLMediaPlayerView支持横竖屏改良版(附DEMO)
- ios9 解决计算字体/字数自定义控件高度的方法:
- iOS 开发者能用上的 10 个 Xcode 插件
- iOS生成二维码
- 初学IOS之启动页面
- iOS性能优化之内存管理:Analyze、Leaks、Allocations的使用和案例代码