iPhone SDK:访问索引颜色的PNG图像 [英] iPhone SDK: accessing indexed color PNG images

查看:172
本文介绍了iPhone SDK:访问索引颜色的PNG图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有兴趣在我的iPhone应用程序中加载索引颜色的PNG图像。一旦加载,我想以每个像素为基础访问图像。特别是,我想获得单个像素的颜色索引(而不是颜色本身)。

I'm interested in loading indexed-color PNG images in my iPhone application. Once they're loaded, I want to access the images on a per-pixel basis. In particular, I want to get the index of the color (rather than the color itself) of individual pixels.

不幸的是,似乎没有办法访问通过UIImage类的像素,更不用说像素的颜色索引了。我也看看与Quartz2D相关的API,但到目前为止看起来很惨淡。

Unfortunately, there does not seem to be a way to access pixels via the UIImage class, let alone color index of a pixel. I'm also taking a look at Quartz2D-related APIs, but so far things look bleak.

我非常感谢任何建议。
我希望我不必从libpng移植必要的代码。

I'd greatly appreciate any suggestions. I'm hoping I won't have to port the necessary code from libpng.

提前致谢!

更新:我可以使用Quartz2D加载PNG,但由于某种原因,它会自动将我的索引颜色8位PNG转换为32位ARGB PNG。我有什么想法可以阻止这种情况吗?

UPDATE: I'm able to load the PNG using Quartz2D, but for some reason it automatically converts my indexed-color 8bit PNG to a 32-bit ARGB PNG. Any thoughts how I might prevent this?

更新2:这一点很重要的原因是内存限制。我试图阻止光栅从每像素8位上升到32位,以避免开销。如果有人对我有神奇的答案,那么100分就是你的!

UPDATE 2: The reason this is important is due to memory limitations. I'm trying to keep the raster from blowing up form eight bits per pixel to thirty two to avoid the overhead. If anyone has the magic answer for me, 100 points are yours!

推荐答案

将图像加载为CGImage而不是UIImage ,使用CGImageCreateWithPNGDataProvider(),您可能能够获得索引颜色空间。请参阅:

By loading the image as a CGImage rather than an UIImage, using CGImageCreateWithPNGDataProvider(), you might be able to get an indexed color space. See:

http://developer.apple.com/iphone/library/documentation/GraphicsImaging/Reference/CGColorSpace/Reference/reference.html

其中列出了CGColorSpaceCreateIndexed(),CGColorSpaceGetColorTable()等。使用CGColorSpaceGetModel(CGImageGetColorSpace(img))查看最终得到的颜色空间是否为索引颜色空间,然后使用CGImageGetDataProvider()获取CGDataProviderRef,您可以使用CGDataProviderCopyData()来获取实际的位图数据。 。

which lists CGColorSpaceCreateIndexed(), CGColorSpaceGetColorTable() and more. Use CGColorSpaceGetModel(CGImageGetColorSpace(img)) to see if the color space you end up with is an indexed one, then use CGImageGetDataProvider() to get a CGDataProviderRef, which you can use with CGDataProviderCopyData() to get to the actual bitmap data...

编辑赏金总能让事情顺利进行。我测试过,它只是有效。 (对不起蹩脚的处理,这当然是概念的证明)

edit a bounty always gets things going. I tested and it just works. (sorry for the crappy handling, this is proof of concept of course)

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

qed?

ps。我的测试图像来自libgd,通过php,使用

ps. my test image is from libgd, through php, using

    $img = imagecreatefrompng("whateverimage.png");
    imagetruecolortopalette($img,false,256);
    header("Content-Type: image/png");
    imagepng($img);

这导致我的情况(黑白图像)

which results in my case (b/w image) in

$ file test.png 
test.png: PNG image, 2000 x 300, 1-bit colormap, non-interlaced

编辑^ 2 这是您访问位图数据的方式。 ASCII art ftw!

edit^2 This is how you access the bitmap data. ASCII art ftw!

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:访问索引颜色的PNG图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆