Issue in checking UIImage have alpha (Transparent) color or not
Asked Answered
F

5

7

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?

Fall answered 17/8, 2016 at 14:21 Comment(0)
F
6

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

Fall answered 1/9, 2016 at 13:42 Comment(0)
H
13

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
  }
}
Horsecar answered 30/4, 2018 at 13:53 Comment(1)
Regular images are detected as transparentPrytaneum
F
6

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

Fall answered 1/9, 2016 at 13:42 Comment(0)
D
1

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.

Dextroamphetamine answered 23/8, 2016 at 17:24 Comment(0)
P
1

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.

Polygynous answered 24/8, 2016 at 10:50 Comment(0)
R
0

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.

Russi answered 17/8, 2016 at 16:45 Comment(1)
CGDataProviderCopyData() not creating any issue in loop for permanence. main concern is all images have background without any transparent area then why it return alpha 0 for only first image. can u please elaborate to resolved this issue.Fall

© 2022 - 2024 — McMap. All rights reserved.