【发布时间】:2013-04-22 03:50:05
【问题描述】:
我发现自己有几个 NSImage 对象需要旋转 90 度,将一种颜色的像素的颜色更改为另一种颜色,然后将 RGB565 数据表示为 NSData 对象.
我在 Accelerate 框架中找到了 vImageConvert_ARGB8888toRGB565 函数,所以它应该能够进行 RGB565 输出。
我在 StackOverflow 上找到了一些 UIImage 旋转,但我无法将它们转换为 NSImage,因为我似乎必须使用 NSGraphicsContext 而不是 CGContextRef?
理想情况下,我希望这些在 NSImage 类别中,这样我就可以调用了。
NSImage *rotated = [inputImage rotateByDegrees:90];
NSImage *colored = [rotated changeColorFrom:[NSColor redColor] toColor:[NSColor blackColor]];
NSData *rgb565 = [colored rgb565Data];
我只是不知道从哪里开始,因为图像处理对我来说是新的。
感谢我能得到的任何帮助。
编辑 (22/04/2013)
我已经设法将这段代码拼凑在一起以生成 RGB565 数据,它会颠倒生成它并带有一些小伪像,我认为第一个是由于使用了不同的坐标系,第二个可能是因为我来自 PNG到 BMP。我将使用 BMP 和非透明 PNG 进行更多测试。
- (NSData *)RGB565Data
{
CGContextRef cgctx = CreateARGBBitmapContext(self.CGImage);
if (cgctx == NULL)
return nil;
size_t w = CGImageGetWidth(self.CGImage);
size_t h = CGImageGetHeight(self.CGImage);
CGRect rect = {{0,0},{w,h}};
CGContextDrawImage(cgctx, rect, self.CGImage);
void *data = CGBitmapContextGetData (cgctx);
CGContextRelease(cgctx);
if (!data)
return nil;
vImage_Buffer src;
src.data = data;
src.width = w;
src.height = h;
src.rowBytes = (w * 4);
void* destData = malloc((w * 2) * h);
vImage_Buffer dst;
dst.data = destData;
dst.width = w;
dst.height = h;
dst.rowBytes = (w * 2);
vImageConvert_ARGB8888toRGB565(&src, &dst, 0);
size_t dataSize = 2 * w * h; // RGB565 = 2 5-bit components and 1 6-bit (16 bits/2 bytes)
NSData *RGB565Data = [NSData dataWithBytes:dst.data length:dataSize];
free(destData);
return RGB565Data;
}
- (CGImageRef)CGImage
{
return [self CGImageForProposedRect:NULL context:[NSGraphicsContext currentContext] hints:nil];
}
CGContextRef CreateARGBBitmapContext (CGImageRef inImage)
{
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void * bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
size_t pixelsWide = CGImageGetWidth(inImage);
size_t pixelsHigh = CGImageGetHeight(inImage);
bitmapBytesPerRow = (int)(pixelsWide * 4);
bitmapByteCount = (int)(bitmapBytesPerRow * pixelsHigh);
colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL)
return nil;
bitmapData = malloc( bitmapByteCount );
if (bitmapData == NULL)
{
CGColorSpaceRelease( colorSpace );
return nil;
}
context = CGBitmapContextCreate (bitmapData,
pixelsWide,
pixelsHigh,
8,
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedFirst);
if (context == NULL)
{
free (bitmapData);
fprintf (stderr, "Context not created!");
}
CGColorSpaceRelease( colorSpace );
return context;
}
【问题讨论】:
-
您通常根本不需要直接使用 NSGraphicsContext。您需要做一些事情,例如 gstate 或获取 CGContext,但 AppKit 的绘图方法只是自己获取当前上下文,您甚至可以从整块布料创建图像,而无需自己创建上下文。
-
“将一种颜色的像素颜色更改为另一种颜色”到底是什么意思?
-
@PeterHosey 我的意思是,我想将图像中具有某个 RGB 值的所有像素更改为另一个 RGB 值。例如。所有红色像素都变成绿色。
-
棘手。颜色循环通常假设一个索引颜色空间(使用转换表将一些颜色转换为其他颜色)。您可能需要编写自定义过滤器。
标签: objective-c macos cocoa nsimage