How to check if a uiimage is blank? (empty, transparent)

后端 未结 6 2026
说谎
说谎 2020-12-31 23:07

which is the best way to check whether a UIImage is blank?
I have this painting editor which returns a UIImage; I don\'t want to save this imag

相关标签:
6条回答
  • 2020-12-31 23:11

    I'm not at my Mac, so I can't test this (and there are probably compile errors). But one method might be:

    //The pixel format depends on what sort of image you're expecting. If it's RGBA, this should work
    typedef struct
    {
       uint8_t red;
       uint8_t green;
       uint8_t blue;
       uint8_t alpha;
    } MyPixel_T;
    
    UIImage *myImage = [self doTheThingToGetTheImage];
    CGImageRef myCGImage = [myImage CGImage];
    
    //Get a bitmap context for the image
    CGBitmapContextRef *bitmapContext = 
    CGBitmapContextFreate(NULL, CGImageGetWidth(myCGImage), CGImageGetHeight(myCGImage), 
                          CGImageGetBitsPerComponent(myCGImage), CGImageGetBytesPerRow(myCGImage),
                          CGImageGetColorSpace(myCGImage), CGImageGetBitmapInfo(myCGImage));
    
    //Draw the image into the context
    CGContextDrawImage(bitmapContext, CGRectMake(0, 0, CGImageGetWidth(myCGImage), CGImageGetHeight(myCGImage)), myCGImage);
    
    //Get pixel data for the image
    MyPixel_T *pixels = CGBitmapContextGetData(bitmapContext);
    size_t pixelCount = CGImageGetWidth(myCGImage) * CGImageGetHeight(myCGImage);
    
    for(size_t i = 0; i < pixelCount; i++)
    {
       MyPixel_T p = pixels[i];
       //Your definition of what's blank may differ from mine
       if(p.red > 0 && p.green > 0 && p.blue > 0 && p.alpha > 0)
          return NO;
    }
    
    return YES;
    
    0 讨论(0)
  • 2020-12-31 23:20

    Here's a solution in Swift that does not require any additional frameworks.

    Thanks to answers in a related question here: Get Pixel Data of ImageView from coordinates of touch screen on xcode?

    func imageIsEmpty(_ image: UIImage) -> Bool {
        guard let cgImage = image.cgImage,
              let dataProvider = cgImage.dataProvider else
        {
            return true
        }
    
        let pixelData = dataProvider.data
        let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)
        let imageWidth = Int(image.size.width)
        let imageHeight = Int(image.size.height)
        for x in 0..<imageWidth {
            for y in 0..<imageHeight {
                let pixelIndex = ((imageWidth * y) + x) * 4
                let r = data[pixelIndex]
                let g = data[pixelIndex + 1]
                let b = data[pixelIndex + 2]
                let a = data[pixelIndex + 3]
                if a != 0 {
                    if r != 0 || g != 0 || b != 0 {
                        return false
                    }
                }
            }
        }
    
        return true
    }
    
    0 讨论(0)
  • 2020-12-31 23:22

    Something along these lines:

    1. Create a 1 px square CGContext
    2. Draw the image so it fills the context
    3. Test the one pixel of the context to see if it contains any data. If it's completely transparent, consider the picture blank

    Others may be able to add more details to this answer.

    0 讨论(0)
  • 2020-12-31 23:22

    I just encountered the same problem. Solved it by checking the dimensions:

    Swift example:

    let image = UIImage()
    
    let height = image.size.height
    let width = image.size.height
    
    if (height > 0 && width > 0) {
        // We have an image
    } else {
        // ...and we don't
    }
    
    0 讨论(0)
  • 2020-12-31 23:30

    Try this code:

    BOOL isImageFlag=[self checkIfImage:image];
    

    And checkIfImage method:

    - (BOOL) checkIfImage:(UIImage *)someImage {
        CGImageRef image = someImage.CGImage;
        size_t width = CGImageGetWidth(image);
        size_t height = CGImageGetHeight(image);
        GLubyte * imageData = malloc(width * height * 4);
        int bytesPerPixel = 4;
        int bytesPerRow = bytesPerPixel * width;
        int bitsPerComponent = 8;
        CGContextRef imageContext =
        CGBitmapContextCreate(
                              imageData, width, height, bitsPerComponent, bytesPerRow, CGImageGetColorSpace(image),
                              kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big
                              );
    
        CGContextSetBlendMode(imageContext, kCGBlendModeCopy);
        CGContextDrawImage(imageContext, CGRectMake(0, 0, width, height), image);
        CGContextRelease(imageContext);
    
        int byteIndex = 0;
    
        BOOL imageExist = NO;
        for ( ; byteIndex < width*height*4; byteIndex += 4) {
            CGFloat red = ((GLubyte *)imageData)[byteIndex]/255.0f;
            CGFloat green = ((GLubyte *)imageData)[byteIndex + 1]/255.0f;
            CGFloat blue = ((GLubyte *)imageData)[byteIndex + 2]/255.0f;
            CGFloat alpha = ((GLubyte *)imageData)[byteIndex + 3]/255.0f;
            if( red != 1 || green != 1 || blue != 1 || alpha != 1 ){
                imageExist = YES;
                break;
            }
        }
    
        free(imageData);        
        return imageExist;
    }
    

    You will have to add OpenGLES framework and import this in the .m file:

    #import <OpenGLES/ES1/gl.h>
    
    0 讨论(0)
  • 2020-12-31 23:33

    One idea would be to call UIImagePNGRepresentation to get an NSData object then compare it with a pre-defined 'empty' version - ie: call:

    - (BOOL)isEqualToData:(NSData *)otherData
    

    to test?

    Not tried this on large data; might want to check performance, if your image data is quite large, otherwise if it's small it is probably just like calling memcmp() in C.

    0 讨论(0)
提交回复
热议问题