2010-03-29 38 views
3

對於我的iPhone 3D應用程序,我正在使用CoreGraphics加載具有預乘alpha的png文件。這裏是要領:iPhone上的CoreGraphics。加載預乘alpha的PNG文件的正確方法是什麼?

// load a 4-channel rgba png file with pre-multiplied alpha. 
CGContextRef context = 
CGBitmapContextCreate(data, width, height, 8, num_channels * width, colorSpace, 
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 

// Draw the image into the context 
CGRect rect = CGRectMake(0, 0, width, height); 
CGContextDrawImage(context, rect, image); 
CGContextRelease(context); 

然後,我繼續並使用數據作爲OpenGL中的紋理。

我的問題:通過指定預倍乘α - kCGImageAlphaPremultipliedLast - 我是 - 無意中 - 告訴CoreGraphics乘以α或rgb通道 - 我所假設的 - 我只是表明傳入圖像的格式已預先乘以alpha?

感謝, 道格

回答

4

通過指定乘預阿爾法 - kCGImageAlphaPremultipliedLast - 我是 - 不經意的 - 讓CoreGraphics中的α乘以RGB通道或者 - 我假設是什麼 - 我我只是表明傳入圖像的格式是否已預先乘以alpha?

都不是。您指定了目的地(上下文)的格式,而不是源。源代碼 - 圖像對象 - 知道它的像素的顏色是否是預乘,Quartz會在將源圖像繪製到上下文中時使用該知識來做正確的事情。

這意味着,在您的緩衝區中的像素將被預乘,不兩次,但他們會在上下文緩衝器來相乘,源顏色是否預乘與否(如果他們成功了,沒有必要再乘以;如果他們不是,那麼它會第一次增加)。

我不知道OpenGL是否足夠了解這是否是問題,如果是這樣,那麼這個代碼可能沒有解決方案:至少在Mac上,Quartz does not support unpremultiplied colors in bitmap contexts

您可以改爲使用this storage format

+0

感謝彼得。我更喜歡pre-mult,因爲我是Porter/Duff(pre-mult approach的發明者)奉獻者。不幸的是OpenGL是* not * premult,所以我需要自己處理。乾杯。 – dugla 2010-03-29 14:50:45

2

備查絆人在這個問題,這裏有一個關於如何去預乘一個例子:

/////// .... 
    /////// load the image into imageRef up here 
    /////// e.g. with CGImageSourceCreateWithURL(); and CGImageSourceCreateImageAtIndex(); on OS X 
    /////// or, by accessing CGImage property of UIImage 
    /////// 
    /////// then extract bitsPerComponent, bytesPerRow and color space 
    /////// .... 


    // draw CG image to a byte array 
    CGContextRef bitmapContext = CGBitmapContextCreate(img->data, 
                 img->w, img->h, 
                 bitsPerComponent, 
                 bytesPerRow, 
                 space, 
                 kCGImageAlphaPremultipliedLast); 

    CGContextDrawImage(bitmapContext,CGRectMake(0.0, 0.0, (float)img->w, (float)img->h),imageRef); 
    CGContextRelease(bitmapContext); 

    // let's undo premultiplication 
    for(int i=0; i < bytesPerRow * img->h; i+=4) 
    { 
     for(int j=0; j<3; j++) 
     { 
      img->data[i+j] = img->data[i+j]/(img->data[i+3]/255.); 
     } 
    } 
+0

如果alpha值爲0,這將不起作用。實際上,對於alpha接近0的任何像素,它將變得越來越難以獲得原始的rgb。你根本無法準確地預乘alpha。但是,您可以將RGB替換爲沒有Alpha通道的第二版圖像。這可能會起作用。如:img-> data [i + j] = img2-> data [i + j]' – badweasel 2014-03-08 07:00:40

相關問題