如何创建空/空白 UIImage 或 CGImage 并在其上操作像素(Xcode)?
Posted
技术标签:
【中文标题】如何创建空/空白 UIImage 或 CGImage 并在其上操作像素(Xcode)?【英文标题】:How to create empty/blank UIImage or CGImage and manipulate pixels on it (Xcode)? 【发布时间】:2011-04-24 15:46:14 【问题描述】:我有以下问题,只能部分解决。我正在使用 XCode 3.2.5,为 ios 4+ 开发。
我只是尝试创建一个预定义大小的图像,在其上操作像素,然后在 UIImageView 中显示该图像。我的视图由连接到的简单按钮和名为“buttonClicked”的 IBAction 和一个名为“qrImage”并设置为“IBOutlet”的 UIImageView 组成。我使用以下代码:
头文件:myClassViewController.h
#import <UIKit/UIKit.h>
@interface myClassViewController : UIViewController
IBOutlet UIImageView *qrImage;
@property (nonatomic, retain) UIImageView *qrImage;
- (IBAction) buttonClicked;
- (UIImage*) drawQRImage;
@end
主文件 myClassViewController.m
#import "myClassViewController.h"
#include <math.h>
@implementation myClassViewController
@synthesize qrImage;
-(UIImage*) drawQRImage
// load Image
//
UIImage *image = [UIImage imageNamed:@"blank.png"];
CGImageRef imageRef = image.CGImage;
NSData *data = (NSData *) CGDataProviderCopyData(CGImageGetDataProvider(imageRef));
char *pixels = (char *)[data bytes];
unsigned long int startPixel, pixelNr;
// manipulate the individual pixels
//
size_t width = CGImageGetWidth(imageRef);
size_t height = CGImageGetHeight(imageRef);
//
// [...] deleted some unimportant code here
//
pixelNr = 10;
int red = pixelNr*3;
int green = pixelNr*3+1;
int blue = pixelNr*3+2;
// Set Pixel-Color Black
//
pixels[red] = 0;
pixels[green] = 0;
pixels[blue] = 0;
//
// [...] deleted some unimportant code here
//
// create a new image from the modified pixel data
//
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, pixels, [data length], NULL);
CGImageRef newImageRef = CGImageCreate (
width,
height,
bitsPerComponent,
bitsPerPixel,
bytesPerRow,
colorspace,
bitmapInfo,
provider,
NULL,
false,
kCGRenderingIntentDefault
);
// the modified image
//
UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
// cleanup
//
free(pixels);
//CGImageRelease(imageRef); // DO NOT RELEASE OR ON NEXT RUN NSData GETS EXC_BAD_ACCESS
CGColorSpaceRelease(colorspace);
CGDataProviderRelease(provider);
CGImageRelease(newImageRef);
QRcode_free(qrCode);
QRinput_free(input);
[image release];
// return created Image
//
return newImage;
-(IBAction) buttonClicked
UIImage *createdUIImg = [self drawQRImage];
qrImage.image = createdUIImg;
我希望代码是非常自我解释的,如果没有,这里是一个简短的描述:
A.在 Button-Click 上,我调用方法 drawQRImage,它会返回一个 UIImage。 B. 在 drawQRImage 我打开一个 PNG 文件,直到现在它的大小为 210x210,只有一个白色背景。没有其他的。然后我操纵它上面的一些像素并“将它们涂成黑色”。当前代码应设置像素 nr。 11 黑色。完成后,我返回新创建的图像。 C. buttonClicked 方法会在 UIImageView 中显示这个 Image。
总而言之其实很简单。它也(几乎)完美地工作。但现在我想进行一些修改,但直到现在才能让它们工作:
我必须返回的图像并不总是 210x210 像素,因此我必须能够更改大小。加载“空白”PNG文件并操纵它的像素是迄今为止我设法开始工作的唯一解决方法。一种更优雅的方法是创建一个具有所需大小的白色 BG 的空白图像,我可以在我当前的方法中使用它。不幸的是,我还没有找到关于该主题的任何内容。仅在处理现有图像上的像素时。这就是我想出当前解决方法的方式。我已经尝试了从以下链接调整大小的片段:Resizing a UIImage the right way
按钮可以点击多次,绘制的像素也会发生变化。我现在的问题是,我似乎有内存泄漏,因为我注释掉了这一行
//CGImageRelease(imageRef);
但如果我确实释放了 UIImageRef“imageRef”,再次单击该按钮时会出现 EXC_BAD_ACCESS-Error。所以我知道这意味着我尝试访问一个已经被释放的对象。但是我该如何解决这个问题,我不确定我是否在这里得到了一切。我认为 imageRef 将在方法“drawQRImage”的开头新创建,因此当我再次调用该方法时释放它应该不是问题。但看起来我好像错了。
感谢每一点帮助!
【问题讨论】:
我发现了一个不完美但或多或少可以接受的问题 #1 的解决方法。我将在测试并完成代码后立即发布代码。不过,如果有人能给我一个关于如何创建空白图像而不是打开空白/白色 png(我现在这样做)的提示,我会很高兴。关于问题 #2:我想下面的链接回答了我对 EXC_BAD_ACCESS-Error 的问题,对吧? ***.com/questions/1428102/… 【参考方案1】:以下讨论解决了 CGImage 对象的内存管理: Releasing CGImage (CGImageRef)
至于空白图片问题: Drawing into CGImageRef
【讨论】:
前段时间我问了这个问题,但还是谢谢。我想那会做到的!这两个链接看起来很有希望。不幸的是,该项目不得不暂停,但可能会在 12 月左右继续进行。【参考方案2】:为什么不用这个简单的技巧呢?这个对我有用。
(假设self.imageViewSymbol
是UIImageView*
)
self.imageViewSymbol.image = nil;
self.imageView.frame = CGRect(...as you like...);
UIGraphicsBeginImageContext(self.imageViewSymbol.bounds.size);
[self.imageViewSymbol.image drawInRect:self.imageViewSymbol.bounds];
self.imageViewSymbol.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
【讨论】:
【参考方案3】:豪宅大小和比例以创建图像
UIGraphicsBeginImageContextWithOptions(*defineSize*, NO, *Scale*);
UIImage *imgClearBG = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
【讨论】:
以上是关于如何创建空/空白 UIImage 或 CGImage 并在其上操作像素(Xcode)?的主要内容,如果未能解决你的问题,请参考以下文章
使用 indexPath 访问数组内的 UIImage 并创建空的 UIImage 数组元素
如何在 UIImage 数组中设置第二张或中间的图像? (斯威夫特 3)