iPhone SDK: доступ к индексированным цветным изображениям PNG - PullRequest
4 голосов
/ 15 июля 2010

Я заинтересован в загрузке изображений PNG индексированного цвета в моем приложении для iPhone.После того, как они будут загружены, я хочу получить доступ к изображениям для каждого пикселя.В частности, я хочу получить индекс цвета (а не самого цвета) отдельных пикселей.

К сожалению, нет способа доступа к пикселям через класс UIImage, не говоря уже о цветеиндекс пикселя.Я также смотрю на API, связанные с Quartz2D, но пока все выглядит мрачно.

Буду очень признателен за любые предложения.Я надеюсь, что мне не придется переносить необходимый код из libpng.

Заранее спасибо!

ОБНОВЛЕНИЕ: я могу загрузить PNG с помощью Quartz2D, но по какой-то причинеон автоматически преобразует мой 8-битный PNG индексированного цвета в 32-битный PNG ARGB.Любые мысли, как я мог бы предотвратить это?

ОБНОВЛЕНИЕ 2: Причина этого важна из-за ограничений памяти.Я пытаюсь удержать растр от взрыва от восьми бит на пиксель до тридцати двух, чтобы избежать накладных расходов.Если у кого-нибудь есть волшебный ответ для меня, 100 баллов - ваши!

1 Ответ

7 голосов
/ 15 июля 2010

Загружая изображение как CGImage, а не как UIImage, используя CGImageCreateWithPNGDataProvider (), вы можете получить индексированное цветовое пространство. См:

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

, в котором перечислены CGColorSpaceCreateIndexed (), CGColorSpaceGetColorTable () и другие. Используйте CGColorSpaceGetModel (CGImageGetColorSpace (img)), чтобы увидеть, является ли цветовое пространство, с которым вы в конечном итоге, индексированным, затем используйте CGImageGetDataProvider (), чтобы получить CGDataProviderRef, который можно использовать с данными CGDataProviderCopyData () для получения фактического .

edit щедрость всегда помогает. Я проверил, и это просто работает. (извините за дерьмовое обращение, это, конечно, подтверждение концепции)

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 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");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...