iPhone SDK:访问索引颜色的PNG图像

Tom*_*Tom 4 iphone png objective-c

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

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

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

提前致谢!

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

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

mvd*_*vds 7

通过使用CGImageCreateWithPNGDataProvider()将图像加载为CGImage而不是UIImage,您可能能够获得索引颜色空间.看到:

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

其中列出了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);
Run Code Online (Sandbox Code Playgroud)

输出:

path: /Users/..../638...8C12/test.app/test.png
Color space model: 5, indexed=5
Run Code Online (Sandbox Code Playgroud)

QED?

PS.我的测试图像来自libgd,通过php,使用

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

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

$ file test.png 
test.png: PNG image, 2000 x 300, 1-bit colormap, non-interlaced
Run Code Online (Sandbox Code Playgroud)

编辑^ 2这是访问位图数据的方法.ASCII艺术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");
}
Run Code Online (Sandbox Code Playgroud)