将图像转换为黑白问题 CGContext - iPhone Dev

发布于 2024-09-11 08:39:56 字数 1321 浏览 10 评论 0原文

我正在使用一种方法将相机拍摄的图像转换为黑白图像。 我遇到的问题是,如果照片是在纵向模式下拍摄的,它会在下一个视图中旋转和拉伸。但是,如果是在风景中拍摄,那就只是发现。

当我将图像转换为黑白时,我只能重复此错误。 这是我正在使用的方法。

我不是 100% 这个 bug 是由转换引起的,但它只在转换时发生。 噢耶。这是 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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风月客 2024-09-18 08:39:56

基明白了。

我最终做的是找到这个函数,该函数根据方向根据变换旋转图像。它的作用是修复这个奇怪的旋转错误。

这是代码片段:

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

它享受!

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!

爱的那么颓废 2024-09-18 08:39:56

我进行了修改,以便能够在不损失分辨率的情况下处理 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;
}

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;
}
得不到的就毁灭 2024-09-18 08:39:56

我想我已经明白了这一点。
现在要去测试了。

事实证明,有 UIImage 方向标志。
我在以下位置找到了支持线程:
http://discussions.apple.com/message.jspa?messageID=7276709

我对此的看法是使用开关来检查方向,并据此将其旋转到正确的方向。

等我弄清楚后我会发布代码。

臭了!

  • @少名

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文