iOS oc对网络图片进行黑白化处理
来源:互联网 发布:网络通讯软件 编辑:程序博客网 时间:2024/04/27 17:56
最近项目需要,图片显示两种状态, 一种是原版彩色的, 另外一种就是黑白的, 可是对于这两种状态我们的服务器端只给我们提供了一套彩色的图片, 我们前端需要根据状态自己处理图片, 于是我就请教了百度, 找到了下面这个方法:
- (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 = (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;}
然后我就写了个demo, 用本地图片做了下, 的确好使, 不愧是大神写的, 虽然看不懂, 但是会用就行了, 于是就照搬到我们的项目中去了, 一般事情发展到这里就应该完美结束了, 可是这却是麻烦来临前的平静, 然后在工程中运行时就出现了下面的错误:
访问了坏内存, 如果对于OC来说如果出现这样的问题还能找到些思路, 可是对于C语言对待这样的问题就一头雾水了, 不知道什么地方导致的问题, 所以在当时这个bug使我不知所措呀, 不知道从什么地方下手. 后来经过我重复测试, 得到下面规律:
- 对本地图片处理不会出现这个问题
- 对于网络图片都是应用安装(安装模拟器或者真机)后, 第一次运行到该地方时才会出现这个问题, 之后再怎么处理这个图片都不会有问题了.
问题定位:
最后我把问题点定位在了 图片缓存 上面, 我是通过 SDWebImage 来做图片下载和缓存的, 通过查看代码发现, SDWebImage 在下载完成后作的图片缓存是异步的, 也就是在第一次下载图片的时候, 本地是没有缓存的, 而且处理的图片是在内存里面的, 然后处理图片的时候出现了坏内存访问. 而在第二次处理的时候之前一次已经将图片缓存到本地了, 所以就没有问题了. 虽然我也不知道为什么这个处理方法对没有缓存到本地的图片处理会出现坏内存访问, 不过最终把问题定位到这个地方了.
解决方案:
在SDWebImage下载完图片后, 先检查本地有没有存在该图片, 如果没有, 则先把下载下来的图片同步缓存到本地, 然后再从本地取得图片进行处理.问题解决!
代码附上: [[SDWebImageManager sharedManager] downloadImageWithURL:imageUrl options:SDWebImageRetryFailed progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { NSString* key = [[SDWebImageManager sharedManager] cacheKeyForURL:imageURL]; BOOL result = [[SDImageCache sharedImageCache] diskImageExistsWithKey:key]; NSString* imagePath = [[SDImageCache sharedImageCache] defaultCachePathForKey:key]; NSData* newData = [NSData dataWithContentsOfFile:imagePath]; if (!result || !newData) { BOOL imageIsPng = ImageDataHasPNGPreffixWithData(nil); NSData* imageData = nil; if (imageIsPng) { imageData = UIImagePNGRepresentation(image); } else { imageData = UIImageJPEGRepresentation(image, (CGFloat)1.0); } NSFileManager* _fileManager = [NSFileManager defaultManager]; if (imageData) { [_fileManager removeItemAtPath:imagePath error:nil]; [_fileManager createFileAtPath:imagePath contents:imageData attributes:nil]; } } newData = [NSData dataWithContentsOfFile:imagePath]; UIImage* grayImage = nil; if (type == 0) { grayImage = [UIImage imageWithData:newData]; }else{ UIImage* newImage = [UIImage imageWithData:newData]; grayImage = [newImage grayscaleWithType:type]; } self.imageView.image = grayImage; }];
0 0
- iOS oc对网络图片进行黑白化处理
- 图像处理---黑白化
- 如何将图片黑白化
- iOS 对图片进行压缩处理
- iOS CGImageRef 对图片进行处理
- iOS对图片进行马赛克处理
- 如何将图片黑白化二
- IOS中使用像素位图(CGImageRef)对图片进行处理
- IOS中使用像素位图(CGImageRef)对图片进行处理
- IOS中使用像素位图(CGImageRef)对图片进行处理
- IOS中使用像素位图(CGImageRef)对图片进行处理
- iOS中使用像素位图(CGImageRef)对图片进行处理
- ios 对于网络图片进行的一些处理
- iOS 对图片进行压缩
- iOS 对图片进行压缩
- ios 对图片进行压缩
- IOS对异常进行处理
- iOS-Opencv 基础学习四(对图片进行图像模糊处理blur、边缘处理Canny)
- 打印杨辉三角
- “大牛”不可缺少的三种文献精读思维模式
- 高并发性能调试经验分享
- C#中Invoke的用法
- 349. Intersection of Two Arrays
- iOS oc对网络图片进行黑白化处理
- BP神经网络的学习
- 学习和借鉴别人的经验,书写了一个简单的图片轮播样式
- react native 错误:Make sure you have an Android emulator running or a device connected and have set up
- VS2012C++学习笔记1(第1-2章)
- 最全面的常用正则表达式大全
- Java线程同步
- <Android 基础(十二)> TextInputLayout,让输入框更有灵性
- 阿里云 windows2008自动更新windows日志文件使C盘变大