我编写了一个图像滤镜,它可以逐个像素地从旧的UII图像中生成新的UII图像。在包含我的图像的类中,声明如下:
@property UIImage *imageHandle; // contains the image of the class
我的CBImage类中的过滤器将位图从UIImage中提取为char数组(像素),分配具有相同大小的新char数组缓冲区(newPixels),然后运行RGBA像素以重建newPixels中的过滤后的图像。最后它生成一个新的UIImage并返回它。
这是代码(CBImage是我的类,其中包含上述声明):
-(CBImage *)doMyFancyStuff
{
// set up some convenience variables
UIImage *image = self.imageHandle;
CGImageRef imageRef = image.CGImage;
NSData *imageData = (NSData *)CFBridgingRelease(CGDataProviderCopyData(CGImageGetDataProvider(imageRef)));
NSLog(@"NumPixels %d", [imageData length]);
char *pixels = (char *)[imageData bytes];
char *newPixels = (char *)calloc([imageData length], sizeof(char));
// run through the image and manipulate the image
for (NSInteger i=0; i< [imageData length]; i+=4)
{
if ([whatEverIWantIsTrueForMyFilter])
{
// color pixel white and ALPHA = 1.0
newPixels[i] = 255;
newPixels[i+1] = 255;
newPixels[i+2] = 255;
newPixels[i+3] = 255;
}
else
newPixels[i+3] = 0; // make pixel translucent
}
// create new image
CBImage *result = [[CBImage alloc] init];
// construct new UImage
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 = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, newPixels, [imageData length], NULL);
CGImageRef newImageRef = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorspace, bitmapInfo, provider, NULL, FALSE, kCGRenderingIntentDefault);
result.imageHandle = [UIImage imageWithCGImage:newImageRef];
// clean up
free(pixels);
free(newPixels);
CGImageRelease(imageRef);
CGColorSpaceRelease(colorspace);
CGDataProviderRelease(provider);
CGImageRelease(newImageRef);
newImageRef = Nil;
return result;
}
这一切看起来效果很好,我可以在视图控制器中显示新创建的UImage:
CBImage *overlayImage = [testCBImage doMyFancyStuff];
self.overlayView.image = overlayImage.imageHandle;
但是......如果我想再次发布图像,则抛出BAD_ACCESS异常:
self.overlayView.image = Nil;
我不知道这里有什么问题。我唯一怀疑的是上面我的过滤器方法中#10行中的calloc调用,因为我有点“手动”分配内存(虽然我在方法结束时再次释放它),然后当它再次被引用时UIImage句柄设置为Nil ...但我不确定。
我正在使用iOS7和ARC。
有什么想法吗?
Beschi
答案 0 :(得分:3)
char *pixels = (char *)[imageData bytes];
然后,稍后......
free(pixels);
但是,像素不是使用create / malloc / ...等创建的,并且不需要发布。
另外,请考虑使用retain(或强大的,相同的东西)声明属性。
@property (nonatomic, retain)UIImage *imageHandle; // contains the image of the class