我对在我的 iPhone 应用程序中加载索引颜色 PNG 图像很感兴趣。加载后,我想按像素访问图像。特别是,我想获取单个像素的颜色索引(而不是颜色本身)。
不幸的是,似乎没有办法通过 UIImage 类访问像素,更不用说像素的颜色索引了。我也在查看与 Quartz2D 相关的 API,但到目前为止情况看起来很糟糕。
如果有任何建议,我将不胜感激。 我希望我不必从 libpng 移植必要的代码。
提前致谢!
更新:我可以使用 Quartz2D 加载 PNG,但出于某种原因,它会自动将我的索引颜色 8 位 PNG 转换为 32 位 ARGB PNG。有什么想法可以防止这种情况发生吗?
更新 2:这很重要的原因是内存限制。我试图防止光栅从每像素 8 位爆炸到 32 位,以避免开销。如果有人为我提供了神奇的答案,100 分就是你的!
最佳答案
通过使用 CGImageCreateWithPNGDataProvider() 将图像加载为 CGImage 而不是 UIImage,您可能能够获得索引色彩空间。见:
其中列出了 CGColorSpaceCreateIndexed()、CGColorSpaceGetColorTable() 等。使用 CGColorSpaceGetModel(CGImageGetColorSpace(img)) 查看您最终得到的颜色空间是否是索引颜色空间,然后使用 CGImageGetDataProvider() 获取 CGDataProviderRef,您可以将其与 CGDataProviderCopyData() 一起使用以获取实际的位图数据。 .
编辑赏金总能让事情顺利进行。我测试过,它很管用。 (抱歉处理不当,这当然是概念证明)
NSString *path = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:@"test.png"];
printf("path: %s\n",[path UTF8String]);
NSData *file = [[NSFileManager defaultManager] contentsAtPath:path];
if ( !file ) printf("file failed\n");
CGDataProviderRef src = CGDataProviderCreateWithCFData(file);
if ( !src ) printf("image failed\n");
CGImageRef img = CGImageCreateWithPNGDataProvider(src, NULL, NO, kCGRenderingIntentDefault);
if ( !img ) printf("image failed\n");
printf("Color space model: %d, indexed=%d\n",
CGColorSpaceGetModel(CGImageGetColorSpace(img)),
kCGColorSpaceModelIndexed);
输出:
path: /Users/..../638...8C12/test.app/test.png
Color space model: 5, indexed=5
有问题吗?
附言。我的测试图像来自 libgd,通过 php,使用
$img = imagecreatefrompng("whateverimage.png");
imagetruecolortopalette($img,false,256);
header("Content-Type: image/png");
imagepng($img);
这导致我的情况(黑白图像)
$ file test.png
test.png: PNG image, 2000 x 300, 1-bit colormap, non-interlaced
edit^2 这就是您访问位图数据的方式。 ASCII 艺术!
CGDataProviderRef data = CGImageGetDataProvider(img);
NSData *nsdata = (NSData *)(CGDataProviderCopyData(data));
char *rawbuf = malloc([nsdata length]);
if ( !rawbuf ) printf("rawbuf failed\n");
[nsdata getBytes:rawbuf];
int w = CGImageGetWidth(img);
int h = CGImageGetHeight(img);
int bpl = CGImageGetBytesPerRow(img);
printf("width: %d (%d bpl), height: %d, pixels: %d, bytes: %d\n",w,bpl,h,bpl*h,[nsdata length]);
if ( [nsdata length] != bpl*h )
{
printf("%d pixels is not %d bytes, i may be crashing now...\n",bpl*h,[nsdata length]);
}
for ( int y=0;y<h; y++ )
{
for ( int x=0;x<w; x++ )
{
char c = rawbuf[y*bpl+x];
while ( !isalnum(c) ) c += 31; //whoa!
printf("%c",c);
}
printf("\n");
}
关于iPhone SDK : accessing indexed color PNG images,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3251595/