Convert Image to B&W problem CGContext - iPhone De

2019-01-17 13:59发布

问题:

I am using a method to convert images taken with the camera into black and white. The problem I'm running into is that if the picture is taken in Portrait mode, it rotates and stretches in the next view. But, if is taken in landscape it is just find.

I can only duplicate this bug when I convert the image to Black And White. Here is the method I am using.

Im not 100% that this bug is from the conversion, but it only happens when its converted. Oh ya. This is the 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

回答1:

K I got it.

What I ended up doing is finding this function that rotates images based off of transform depending on the orientation. What it does is fixes this weird rotate bug.

Heres the code snippet:

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

The method returns an IMAGE that i can then use in my BLACK AND WHITE Function

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

ENJOY!



回答2:

I modified to be able to deal with 2.0 scaled images without loosing resolution:

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


回答3:

I think i figured this out. Going to test now.

Turns out that there are UIImage orientation flags. I found a support thread at: http://discussions.apple.com/message.jspa?messageID=7276709

My take on this is to use a switch to check the orientation, and based off of that rotate it to its proper orientation.

Ill post the code after i figure it out.

Stanks!

  • @lessfame