Issue in checking UIImage have alpha (Transparent)

2019-06-22 07:03发布

I'm checking that image have transparent area (alpha) or not. Bashed on that I have to change the color of UIImage

I have implement the below method to check the image have alpha or not.

- (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;
}

This method is working fine but for some image it is creating issue. See the below image:

enter image description here
For above image alpha return 0;

enter image description here enter image description here
And for above 2 images alpha have some value.

All 3 images have same white background. For the first image also should have some alpha. it should not be 0. Please guide me out on this ? is there any code error in my method or what?

5条回答
Animai°情兽
2楼-- · 2019-06-22 07:45

Finally find out the solution for the current images which are displaying on the question. I want to find out that UIImage have alpha Channel or not.

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

}

This hasAlpha method is working fine in this case.

For More info : Check out this link

查看更多
太酷不给撩
3楼-- · 2019-06-22 07:47

For what it's worth, I tried downloading your images, right clicking and picking 'get info'. The info says the images have no alpha channel, so I would start by getting new versions of these images that do have alpha.

查看更多
甜甜的少女心
4楼-- · 2019-06-22 07:51

Rewrite @Hitarth's answer in Swift4:

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
  }
}
查看更多
放我归山
5楼-- · 2019-06-22 07:57

Run on all the points on an image \ layer and check for alpha channel existence like so:

 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;
}

I wrote a class that detects if a certain pixel is transparent, if that's the case the UIButton, for example, passes the Touch event to its super view. You might find it useful.

查看更多
倾城 Initia
6楼-- · 2019-06-22 07:58

First off, your call to CGDataProviderCopyData() is inside the loop, so it going to be shockingly slow. Second, your code is not going to work with different input PNG image types. The only way to make it work properly is to render the input image into a pixel buffer and then examine the output once flattened out into plain pixels.

查看更多
登录 后发表回答