【问题标题】:Manipulating individual pixels of a UIImage操作 UIImage 的单个像素
【发布时间】:2011-12-01 19:14:00
【问题描述】:
我目前正在尝试将一个 Java 程序移植到 iO,它利用 BufferedImage 的 .setRGB 方法来单独操作图像的像素,像这样
image.setRGB(x, y, color);
在 Objective-C 中,我使用 UIImage 代替 BufferedImage,我想知道是否有等效的方法来执行 Java 的 setRGB ,或者我必须将图像转换为字节数组,操作像素然后使用 ImageWithData?
【问题讨论】:
标签:
iphone
objective-c
cocoa-touch
uiimage
【解决方案1】:
您必须将图像转换为位图,在位图上使用 setRGB,然后使用位图创建图像并绘制它或将新图像分配给您的图像视图内容。
为什么?这些像素可能在 GPU 的另一侧以不透明格式存在,应用程序的 ARM 代码无法访问它们。
【解决方案2】:
您可以使用以下方法访问像素并对其进行操作
-(UIImage*) applyFilterContext:(void*)context
{
CGImageRef inImage = self.CGImage;
CFDataRef m_DataRef = CGDataProviderCopyData(CGImageGetDataProvider(inImage));
UInt8 * m_PixelBuf = (UInt8 *) CFDataGetBytePtr(m_DataRef);
int length = CFDataGetLength(m_DataRef);
for (int i=0; i<length; i+=4)
{
filterGreyScale(m_PixelBuf, i, context);
}
//Create Context
CGContextRef ctx = CGBitmapContextCreate(m_PixelBuf,
CGImageGetWidth(inImage),
CGImageGetHeight(inImage),
CGImageGetBitsPerComponent(inImage),
CGImageGetBytesPerRow(inImage),
CGImageGetColorSpace(inImage),
CGImageGetBitmapInfo(inImage)
);
CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
CGContextRelease(ctx);
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CFRelease(m_DataRef);
return finalImage;
}
//将像素操作为灰度值
void filterGreyScale (UInt8 *pixelBuf, UInt32 offset, void *context)
{
int r = offset;
int g = offset+1;
int b = offset+2;
int red = pixelBuf[r];
int green = pixelBuf[g];
int blue = pixelBuf[b];
uint32_t gray = 0.3 * red + 0.59 * green + 0.11 * blue;
pixelBuf[r] = gray;
pixelBuf[g] = gray;
pixelBuf[b] = gray;
}
【解决方案4】:
这是我最终用来设置像素的代码
-(void)setPixel:(UInt8*)buffer width:(int)width x:(int)x y:(int)y r:(int)r g:(int)g b:(int)b
{
buffer[x*4 + y*(width*4)] = r;
buffer[x*4 + y*(width*4)+1] = g;
buffer[x*4 + y*(width*4)+2] = b;
}