Как проверить, пусто ли изображение(пустой, прозрачный) - PullRequest
7 голосов
/ 19 января 2011

Какой лучший способ проверить, является ли UIImage пустым?
У меня есть этот редактор рисования, который возвращает UIImage; Я не хочу сохранять это изображение, если на нем ничего нет.

Ответы [ 6 ]

5 голосов
/ 27 марта 2014
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>
2 голосов
/ 19 января 2011

Что-то вроде этого:

  1. Создание квадрата размером 1 пиксель CGContext
  2. Нарисуйте изображение так, чтобы оно заполняло контекст
  3. Проверьте один пиксель контекста, чтобы увидеть, содержит ли он какие-либо данные. Если он полностью прозрачный, считайте изображение пустым

Другие могут добавить больше деталей к этому ответу.

2 голосов
/ 19 января 2011

Одной из идей было бы вызвать UIImagePNGRepresentation , чтобы получить объект NSData, а затем сравнить его с заранее определенной «пустой» версией - то есть: call:

- (BOOL)isEqualToData:(NSData *)otherData

дляtest?

Не пробовал это на больших данных;Возможно, вы захотите проверить производительность, если ваши данные изображения достаточно велики, в противном случае, если они маленькие, это, вероятно, похоже на вызов memcmp() в C.

0 голосов
/ 08 января 2019

Вот решение в Swift, которое не требует никаких дополнительных фреймворков.

Благодаря ответам на связанный с этим вопрос здесь: Получить пиксельные данные ImageView из координат сенсорного экрана на 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 голосов
/ 30 декабря 2015

Я только что столкнулся с той же проблемой.Решил это, проверив размеры:

Пример Swift:

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 голосов
/ 19 января 2011

Я не на своем Mac, поэтому я не могу проверить это (и, возможно, есть ошибки компиляции). Но один метод может быть:

//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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...