Конвертировать изображение в черно-белую задачу CGContext - iPhone Dev - PullRequest
6 голосов
/ 27 июля 2010

Я использую метод для преобразования изображений, снятых камерой, в черно-белое изображение. Проблема, с которой я сталкиваюсь, заключается в том, что если снимок сделан в портретном режиме, он поворачивается и растягивается в следующем виде. Но если взять в ландшафте, это просто найти.

Я могу продублировать эту ошибку только при преобразовании изображения в черно-белое. Вот метод, который я использую.

Я не на 100% уверен, что эта ошибка связана с конверсией, но это происходит только тогда, когда она конвертирована. О да. Это iOS 4.

///

- (UIImage *)convertImageToGrayScale:(UIImage *)image
{

 // Create image rectangle with current image width/height
 CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);

 // Grayscale color space
 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();

 // Create bitmap content with current image size and grayscale colorspace
 CGContextRef context = CGBitmapContextCreate(nil, image.size.width, image.size.height, 8, 0, colorSpace, kCGImageAlphaNone);

 // Draw image into current context, with specified rectangle
 // using previously defined context (with grayscale colorspace)
 CGContextDrawImage(context, imageRect, [image CGImage]);

 // Create bitmap image info from pixel data in current context
 CGImageRef imageRef = CGBitmapContextCreateImage(context);

 // Create a new UIImage object  
 UIImage *newImage = [UIImage imageWithCGImage:imageRef];

 // Release colorspace, context and bitmap information
 CGColorSpaceRelease(colorSpace);
 CGContextRelease(context);
 CFRelease(imageRef);

 // Return the new grayscale image
 return newImage;
}

@ lessfame

Ответы [ 3 ]

13 голосов
/ 28 июля 2010

К я понял.

В итоге я нашел эту функцию, которая вращает изображения на основе преобразования в зависимости от ориентации. Он исправляет эту странную ошибку поворота.

Вот фрагмент кода:

- (UIImage *)rotateImage:(UIImage *)image {

int kMaxResolution = 320; // Or whatever

CGImageRef imgRef = image.CGImage;

CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);


CGAffineTransform transform = CGAffineTransformIdentity;
CGRect bounds = CGRectMake(0, 0, width, height);
if (width > kMaxResolution || height > kMaxResolution) {
    CGFloat ratio = width/height;
    if (ratio > 1) {
        bounds.size.width = kMaxResolution;
        bounds.size.height = bounds.size.width / ratio;
    }
    else {
        bounds.size.height = kMaxResolution;
        bounds.size.width = bounds.size.height * ratio;
    }
}

CGFloat scaleRatio = bounds.size.width / width;
CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
CGFloat boundHeight;
UIImageOrientation orient = image.imageOrientation;
switch(orient) {

    case UIImageOrientationUp: //EXIF = 1
        transform = CGAffineTransformIdentity;
        break;

    case UIImageOrientationUpMirrored: //EXIF = 2
        transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
        transform = CGAffineTransformScale(transform, -1.0, 1.0);
        break;

    case UIImageOrientationDown: //EXIF = 3
        transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
        transform = CGAffineTransformRotate(transform, M_PI);
        break;

    case UIImageOrientationDownMirrored: //EXIF = 4
        transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
        transform = CGAffineTransformScale(transform, 1.0, -1.0);
        break;

    case UIImageOrientationLeftMirrored: //EXIF = 5
        boundHeight = bounds.size.height;
        bounds.size.height = bounds.size.width;
        bounds.size.width = boundHeight;
        transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
        transform = CGAffineTransformScale(transform, -1.0, 1.0);
        transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
        break;

    case UIImageOrientationLeft: //EXIF = 6
        boundHeight = bounds.size.height;
        bounds.size.height = bounds.size.width;
        bounds.size.width = boundHeight;
        transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
        transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
        break;

    case UIImageOrientationRightMirrored: //EXIF = 7
        boundHeight = bounds.size.height;
        bounds.size.height = bounds.size.width;
        bounds.size.width = boundHeight;
        transform = CGAffineTransformMakeScale(-1.0, 1.0);
        transform = CGAffineTransformRotate(transform, M_PI / 2.0);
        break;

    case UIImageOrientationRight: //EXIF = 8
        boundHeight = bounds.size.height;
        bounds.size.height = bounds.size.width;
        bounds.size.width = boundHeight;
        transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
        transform = CGAffineTransformRotate(transform, M_PI / 2.0);
        break;

    default:
        [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];

}

UIGraphicsBeginImageContext(bounds.size);

CGContextRef context = UIGraphicsGetCurrentContext();

if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
    CGContextScaleCTM(context, -scaleRatio, scaleRatio);
    CGContextTranslateCTM(context, -height, 0);
}
else {
    CGContextScaleCTM(context, scaleRatio, -scaleRatio);
    CGContextTranslateCTM(context, 0, -height);
}

CGContextConcatCTM(context, transform);

CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return imageCopy; }

Метод возвращает ИЗОБРАЖЕНИЕ, которое я затем могу использовать в своей ЧЕРНОЙ И БЕЛОЙ функции

- (UIImage *)convertImageToGrayScale:(UIImage *)image {

image = [self rotateImage:image];//THIS IS WHERE REPAIR THE ROTATION PROBLEM

// Create image rectangle with current image width/height
CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);

// Grayscale color space
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();

// Create bitmap content with current image size and grayscale colorspace
CGContextRef context = CGBitmapContextCreate(nil, image.size.width, image.size.height, 8, 0, colorSpace, kCGImageAlphaNone);

// Draw image into current context, with specified rectangle
// using previously defined context (with grayscale colorspace)
CGContextDrawImage(context, imageRect, [image CGImage]);

// Create bitmap image info from pixel data in current context
CGImageRef imageRef = CGBitmapContextCreateImage(context);

// Create a new UIImage object  
UIImage *newImage = [UIImage imageWithCGImage:imageRef];

// Release colorspace, context and bitmap information
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
CFRelease(imageRef);

// Return the new grayscale image
return newImage; }

НАСЛАЖДАЙТЕСЬ!

1 голос
/ 06 января 2016

Я изменил, чтобы иметь возможность обрабатывать 2,0 масштабированных изображений без потери разрешения:

- (UIImage *)convertImageToGrayScale:(UIImage *)image {
    // Create image rectangle with current image width/height
    CGRect imageRect = CGRectMake(0, 0, image.scale*image.size.width, image.scale*image.size.height);

    // Grayscale color space
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();

    // Create bitmap content with current image size and grayscale colorspace
    CGContextRef context = CGBitmapContextCreate(nil, image.scale*image.size.width, image.scale*image.size.height, 8, 0, colorSpace, kCGImageAlphaNone);

    // Draw image into current context, with specified rectangle
    // using previously defined context (with grayscale colorspace)
    CGContextDrawImage(context, imageRect, [image CGImage]);

    // Create bitmap image info from pixel data in current context
    CGImageRef imageRef = CGBitmapContextCreateImage(context);

    // Create a new UIImage object
    UIImage *newImage = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation];

    // Release colorspace, context and bitmap information
    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);
    CFRelease(imageRef);

    // Return the new grayscale image
    return newImage;
}
0 голосов
/ 28 июля 2010

Я думаю, я понял это. Собираюсь сейчас проверить.

Оказывается, есть флаги ориентации UIImage. Я нашел тему поддержки по адресу: http://discussions.apple.com/message.jspa?messageID=7276709

Мое предположение заключается в том, чтобы использовать переключатель для проверки ориентации, а на основании этого повернуть его в правильное положение.

Я отправлю код после того, как выясню.

Stanks!

  • @ lessfame
...