检查UIImage是否具有alpha(透明)颜色的问题

7

我正在检查图像是否具有透明区域(alpha)。基于此,我必须更改 UIImage 的颜色。

我已经实现了以下方法来检查图像是否具有 alpha

- (BOOL) checkAlpha  : (UIImage*) image
{
    for(int x = 0; x <  image.size.width ; x++)
    {
        for(int y = 0; y < image.size. height; y++)
        {
            CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));
            const UInt8* data = CFDataGetBytePtr(pixelData);

            int pixelInfo = ((image.size.width  * y) + x ) * 4; // The image is png

            UInt8 red = data[pixelInfo];         // If you need this info, enable it
            UInt8 green = data[(pixelInfo + 1)]; // If you need this info, enable it
            UInt8 blue = data[pixelInfo + 2];    // If you need this info, enable it
            UInt8 alpha = data[pixelInfo + 3];     // I need only this info for my maze game
            CFRelease(pixelData);

            UIColor* color = [UIColor colorWithRed:red/255.0f green:green/255.0f blue:blue/255.0f alpha:alpha/255.0f];

            DLog(@"color : %@",color);
            DLog(@"alpha : %hhu",alpha)

            if (alpha)
                return YES;     // display original image from url.
            else
                return NO;      // apply brand color here.
        }
    }
    return YES;
}

此方法运行良好,但对于某些图像会出现问题。 请参见下面的图片:enter image description here 对于上面的图片alpha返回值为0;
另外两张图片enter image description hereenter image description here的alpha值都不为0。
这3张图片都有相同的白色背景。第一张图片也应该有一些alpha值,而不应该是0。请指导我?我的方法是否有代码错误?
5个回答

13

用Swift4重写@Hitarth的答案:

extension UIImage {
  public func isTransparent() -> Bool {
    guard let alpha: CGImageAlphaInfo = self.cgImage?.alphaInfo else { return false }
    return alpha == .first || alpha == .last || alpha == .premultipliedFirst || alpha == .premultipliedLast
  }
}

常规图像被检测为透明。 - Yaroslav Dukal

6

终于找到了解决当前问题的方法,我想要找出UIImage是否有alpha通道。

- (BOOL)hasAlpha : (UIImage*) img
{
    CGImageAlphaInfo alpha = CGImageGetAlphaInfo(img.CGImage);
    return (
            alpha == kCGImageAlphaFirst ||
            alpha == kCGImageAlphaLast ||
            alpha == kCGImageAlphaPremultipliedFirst ||
            alpha == kCGImageAlphaPremultipliedLast
            );

}

在这种情况下,hasAlpha方法运行良好。

了解更多信息: 点击此链接


1

说句实话,我尝试下载你的图片,右键点击并选择“获取信息”。信息显示图片没有alpha通道,因此建议获取具有alpha通道的新版本图片。


1

在图像/层上运行所有点,并检查alpha通道是否存在,如下所示:

 UIColor *pixelColor = [SSAlphaPass colorOfPoint:point withLayer:self.layer];
    if(CGColorGetAlpha(pixelColor.CGColor))
    {
        return YES;
    }

    return NO;

+ (UIColor *) colorOfPoint:(CGPoint)point withLayer:(CALayer*)layer
{
    unsigned char pixel[4] = {0};

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGContextRef context = CGBitmapContextCreate(pixel, 1, 1, 8, 4, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast);

    CGContextTranslateCTM(context, -point.x, -point.y);

    [layer renderInContext:context];

    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);

    //NSLog(@"pixel: %d %d %d %d", pixel[0], pixel[1], pixel[2], pixel[3]);

    UIColor *color = [UIColor colorWithRed:pixel[0]/255.0 green:pixel[1]/255.0 blue:pixel[2]/255.0 alpha:pixel[3]/255.0];

    return color;
}

我写了一个类,用于检测特定像素是否透明。如果是这种情况,例如UIButton,则将Touch事件传递给其父视图。你可能会发现它有用


0
首先,你调用CGDataProviderCopyData()的位置在循环内部,所以它会非常慢。其次,你的代码无法处理不同类型的输入PNG图像。要使其正常工作的唯一方法是将输入图像渲染到像素缓冲区中,然后在展开为普通像素后检查输出结果。

1
CGDataProviderCopyData() 在循环中没有出现任何问题。主要问题是所有图像都没有透明区域的背景,为什么它只返回第一张图像的 alpha 值为 0。您能否详细说明以解决此问题? - Hitarth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接