Convert Image to B&W problem CGContext – iPhone Dev

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.

  • Detecting iPhone camera orientation
  • How to get rid of this “points” between my lines when I am drawing?
  • Erasing on UIImageView
  • How to launch camera on viewDidLoad with UIImagePickerControllerDelegate?
  • How can I do fast image processing from the iPhone camera?
  • iOS take photo from camera without modalViewController
  • 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

    3 Solutions Collect From Internet About “Convert Image to B&W problem CGContext – iPhone Dev”

    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!

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

    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