9

我需要确定 png 图像是否包含任何透明度 - 实现这一目标的最有效代码是什么?

4

1 回答 1

19

将 png 转换为像素缓冲区并使用 vimage 计算颜色分布的直方图。然后检查 alpha 通道直方图。vimage 比逐个遍历像素要快得多。

CVPixelBufferRef pxbuffer = NULL;

vImagePixelCount histogramA[256];
vImagePixelCount histogramR[256];
vImagePixelCount histogramG[256];
vImagePixelCount histogramB[256];
vImagePixelCount *histogram[4];
histogram[0] = histogramA;
histogram[1] = histogramR;
histogram[2] = histogramG;
histogram[3] = histogramB;
vImage_Buffer vbuff;
vbuff.height = CVPixelBufferGetHeight(pxbuffer);
vbuff.width = CVPixelBufferGetWidth(pxbuffer);
vbuff.rowBytes = CVPixelBufferGetBytesPerRow(pxbuffer);

vbuff.data = pxbuffer; 
vImage_Error err = vImageHistogramCalculation_ARGB8888 (&vbuff,histogram, 0);
if (err != kvImageNoError) NSLog(@"%ld", err);

int trans = 255 //How little transparency you want to include
BOOL transparent = NO;      
for(int i=0; i<trans; i++){
   if(histogram[0][i]>0) transparent = YES;
}

vimage 假设颜色在缓冲区中是有序的 ARGB。如果您有其他东西,例如 BGRA,您只需检查 histogram[3][i]。

更快的可能是首先使用 vImageConvert_ARGB8888toPlanar8 将缓冲区分成四个平面缓冲区,然后使用 vImageHistogramCalculation_Planar8 对 alfa 缓冲区进行直方图计算。

您可以将 png 作为 CGImage 打开并使用 vImageBuffer_initWithCGImage 将其直接转换为 vimage 缓冲区(请参阅 WWDC 2014 的 session 703)。

最后,另一种方法是使用 Core Image 来计算直方图。

于 2013-04-13T09:52:13.113 回答