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

Posted

技术标签:

【中文标题】检查 UIImage 是不是具有 alpha(透明)颜色的问题【英文标题】:Issue in checking UIImage have alpha (Transparent) color or not检查 UIImage 是否具有 alpha(透明)颜色的问题 【发布时间】:2016-08-17 14:21:23 【问题描述】:

我正在检查图像是否具有透明区域 (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;

此方法运行良好,但对于某些图像,它会产生问题。 见下图:

对于上面的图像 alpha 返回 0;

对于以上 2 张图像,alpha 具有一定的价值。

所有 3 张图片都有相同的白色背景。 对于第一个图像也应该有一些 alpha。它不应该是 0。 请指导我吗?我的方法中是否有任何代码错误或什么?

【问题讨论】:

【参考方案1】:

在 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
  

【讨论】:

常规图像被检测为透明【参考方案2】:

最后找出问题上显示的当前图像的解决方案。我想知道 UIImage 是否有 alpha 通道。

- (BOOL)hasAlpha : (UIImage*) img

    CGImageAlphaInfo alpha = CGImageGetAlphaInfo(img.CGImage);
    return (
            alpha == kCGImageAlphaFirst ||
            alpha == kCGImageAlphaLast ||
            alpha == kCGImageAlphaPremultipliedFirst ||
            alpha == kCGImageAlphaPremultipliedLast
            );


这个hasAlpha 方法在这种情况下工作正常。

欲了解更多信息:Check out this link

【讨论】:

【参考方案3】:

为了它的价值,我尝试下载您的图片,右键单击并选择“获取信息”。信息说图像没有 alpha 通道,所以我会先获取这些具有 alpha 的图像的新版本。

【讨论】:

【参考方案4】:

在图像\图层上的所有点上运行并检查 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 事件传递给它的超级视图。你可能会发现它useful。

【讨论】:

【参考方案5】:

首先,您对 CGDataProviderCopyData() 的调用是在循环内,所以它会非常缓慢。其次,您的代码不适用于不同的输入 PNG 图像类型。使其正常工作的唯一方法是将输入图像渲染到像素缓冲区中,然后检查平展为普通像素的输出。

【讨论】:

CGDataProviderCopyData() 不会在循环中创建任何永久问题。主要关注的是所有图像都有没有任何透明区域的背景,那么为什么它只为第一张图像返回 alpha 0。你能详细说明一下解决这个问题吗?

以上是关于检查 UIImage 是不是具有 alpha(透明)颜色的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何设置 UIImage 的不透明度/alpha?

如何使用GD检查图像是不是具有透明度?

Perl GD 检查像素是不是透明

将文本写入透明 UIImage

检测具有透明背景的 UIImage 的裁剪矩形

使用 CALayer 显示 alpha 映射图像