iPhone SDK: accessing indexed color PNG images

后端 未结 1 871
小蘑菇
小蘑菇 2020-12-15 14:24

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 t

相关标签:
1条回答
  • 2020-12-15 14:38

    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

    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);
    

    output:

    path: /Users/..../638...8C12/test.app/test.png
    Color space model: 5, indexed=5
    

    qed?

    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
    

    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");
    }
    
    0 讨论(0)
提交回复
热议问题