使用 Objective C 将 RGB 彩色图像更改为灰度图像

发布于 2024-10-11 01:59:45 字数 1680 浏览 3 评论 0原文

我正在开发一个将彩色图像更改为灰度图像的应用程序。然而,有些图片显示出来是错误的。我不知道代码有什么问题。也许我输入的参数有误,请帮忙。

 UIImage *c = [UIImage imageNamed:@"downRed.png"];
 CGImageRef cRef = CGImageRetain(c.CGImage);

 NSData* pixelData = (NSData*) CGDataProviderCopyData(CGImageGetDataProvider(cRef));

 size_t w = CGImageGetWidth(cRef);
 size_t h = CGImageGetHeight(cRef);

 unsigned char* pixelBytes = (unsigned char *)[pixelData bytes];

 unsigned char* greyPixelData = (unsigned char*) malloc(w*h);

 for (int y = 0; y < h; y++) {
 for(int x = 0; x < w; x++){

 int iter = 4*(w*y+x);
 int red = pixe lBytes[iter];
 int green = pixelBytes[iter+1];
 int blue = pixelBytes[iter+2];
 greyPixelData[w*y+x] = (unsigned char)(red*0.3 + green*0.59+ blue*0.11);
     int value = greyPixelData[w*y+x];

 }
 }

 CFDataRef imgData = CFDataCreate(NULL, greyPixelData, w*h);


 CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData(imgData);


 size_t width = CGImageGetWidth(cRef);
 size_t height = CGImageGetHeight(cRef);
 size_t bitsPerComponent = 8;
 size_t bitsPerPixel = 8;
 size_t bytesPerRow = CGImageGetWidth(cRef);
 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
 CGBitmapInfo info = kCGImageAlphaNone;
 CGFloat *decode = NULL;
 BOOL shouldInteroplate = NO;
 CGColorRenderingIntent intent = kCGRenderingIntentDefault;
  CGDataProviderRelease(imgDataProvider);

 CGImageRef throughCGImage = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpace, info, imgDataProvider, decode, shouldInteroplate, intent);


 UIImage* newImage = [UIImage imageWithCGImage:throughCGImage];

CGImageRelease(throughCGImage);
 newImageView.image = newImage;

I was developing a application that changes color image to gray image. However, some how the picture comes out wrong. I dont know what is wrong with the code. maybe the parameter that i put in is wrong please help.

 UIImage *c = [UIImage imageNamed:@"downRed.png"];
 CGImageRef cRef = CGImageRetain(c.CGImage);

 NSData* pixelData = (NSData*) CGDataProviderCopyData(CGImageGetDataProvider(cRef));

 size_t w = CGImageGetWidth(cRef);
 size_t h = CGImageGetHeight(cRef);

 unsigned char* pixelBytes = (unsigned char *)[pixelData bytes];

 unsigned char* greyPixelData = (unsigned char*) malloc(w*h);

 for (int y = 0; y < h; y++) {
 for(int x = 0; x < w; x++){

 int iter = 4*(w*y+x);
 int red = pixe lBytes[iter];
 int green = pixelBytes[iter+1];
 int blue = pixelBytes[iter+2];
 greyPixelData[w*y+x] = (unsigned char)(red*0.3 + green*0.59+ blue*0.11);
     int value = greyPixelData[w*y+x];

 }
 }

 CFDataRef imgData = CFDataCreate(NULL, greyPixelData, w*h);


 CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData(imgData);


 size_t width = CGImageGetWidth(cRef);
 size_t height = CGImageGetHeight(cRef);
 size_t bitsPerComponent = 8;
 size_t bitsPerPixel = 8;
 size_t bytesPerRow = CGImageGetWidth(cRef);
 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
 CGBitmapInfo info = kCGImageAlphaNone;
 CGFloat *decode = NULL;
 BOOL shouldInteroplate = NO;
 CGColorRenderingIntent intent = kCGRenderingIntentDefault;
  CGDataProviderRelease(imgDataProvider);

 CGImageRef throughCGImage = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpace, info, imgDataProvider, decode, shouldInteroplate, intent);


 UIImage* newImage = [UIImage imageWithCGImage:throughCGImage];

CGImageRelease(throughCGImage);
 newImageView.image = newImage;

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

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

发布评论

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

评论(3

扶醉桌前 2024-10-18 01:59:45

如果有人想要包含透明部分的灰度图像,则由 digipeople 提供的解决方案将在其周围有一个黑色掩模。使用它来保持透明原样。

- (UIImage *)imageToGreyImage:(UIImage *)image {
    // Create image rectangle with current image width/height
    CGFloat actualWidth = image.size.width;
    CGFloat actualHeight = image.size.height;

    CGRect imageRect = CGRectMake(0, 0, actualWidth, actualHeight);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();

    CGContextRef context = CGBitmapContextCreate(nil, actualWidth, actualHeight, 8, 0, colorSpace, kCGImageAlphaNone);
    CGContextDrawImage(context, imageRect, [image CGImage]);

    CGImageRef grayImage = CGBitmapContextCreateImage(context);
    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);

    context = CGBitmapContextCreate(nil, actualWidth, actualHeight, 8, 0, nil, kCGImageAlphaOnly);
    CGContextDrawImage(context, imageRect, [image CGImage]);
    CGImageRef mask = CGBitmapContextCreateImage(context);
    CGContextRelease(context);

    UIImage *grayScaleImage = [UIImage imageWithCGImage:CGImageCreateWithMask(grayImage, mask) scale:image.scale orientation:image.imageOrientation];
    CGImageRelease(grayImage);
    CGImageRelease(mask);

    // Return the new grayscale image
    return grayScaleImage;
}

If someone wants to gray scale images that contain transparent parts the solution offered by digipeople will have a black mask around it. Use this instead to leave the transparent as it is.

- (UIImage *)imageToGreyImage:(UIImage *)image {
    // Create image rectangle with current image width/height
    CGFloat actualWidth = image.size.width;
    CGFloat actualHeight = image.size.height;

    CGRect imageRect = CGRectMake(0, 0, actualWidth, actualHeight);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();

    CGContextRef context = CGBitmapContextCreate(nil, actualWidth, actualHeight, 8, 0, colorSpace, kCGImageAlphaNone);
    CGContextDrawImage(context, imageRect, [image CGImage]);

    CGImageRef grayImage = CGBitmapContextCreateImage(context);
    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);

    context = CGBitmapContextCreate(nil, actualWidth, actualHeight, 8, 0, nil, kCGImageAlphaOnly);
    CGContextDrawImage(context, imageRect, [image CGImage]);
    CGImageRef mask = CGBitmapContextCreateImage(context);
    CGContextRelease(context);

    UIImage *grayScaleImage = [UIImage imageWithCGImage:CGImageCreateWithMask(grayImage, mask) scale:image.scale orientation:image.imageOrientation];
    CGImageRelease(grayImage);
    CGImageRelease(mask);

    // Return the new grayscale image
    return grayScaleImage;
}
甜味拾荒者 2024-10-18 01:59:45

只需使用这个:

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

Just use this:

- (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;
}
江心雾 2024-10-18 01:59:45

Swift 版本,已测试且 100% 正常工作:

    func imageToGreyImage(image: UIImage) -> UIImage {

    // Create image rectangle with current image width/height
    var actualWidth = image.size.width;
    var actualHeight = image.size.height;

    var imageRect = CGRectMake(0, 0, actualWidth, actualHeight);
    var colorSpace = CGColorSpaceCreateDeviceGray();

    var bitmapInfo = CGBitmapInfo(CGImageAlphaInfo.None.rawValue)

    var context = CGBitmapContextCreate(nil, Int(actualWidth), Int(actualHeight), 8, 0, colorSpace, bitmapInfo);
    CGContextDrawImage(context, imageRect, image.CGImage);

    var grayImage = CGBitmapContextCreateImage(context);
    bitmapInfo = CGBitmapInfo(CGImageAlphaInfo.Only.rawValue)
    context = CGBitmapContextCreate(nil, Int(actualWidth), Int(actualHeight), 8, 0, nil, bitmapInfo);
    CGContextDrawImage(context, imageRect, image.CGImage);
    var mask = CGBitmapContextCreateImage(context);

    var grayScaleImage = UIImage(CGImage: CGImageCreateWithMask(grayImage, mask), scale: image.scale, orientation: image.imageOrientation)

    // Return the new grayscale image
    return grayScaleImage!;
}

如果你不需要 alpha,只需删除以下行:

bitmapInfo = CGBitmapInfo(CGImageAlphaInfo.Only.rawValue)

Swift version, tested and working 100%:

    func imageToGreyImage(image: UIImage) -> UIImage {

    // Create image rectangle with current image width/height
    var actualWidth = image.size.width;
    var actualHeight = image.size.height;

    var imageRect = CGRectMake(0, 0, actualWidth, actualHeight);
    var colorSpace = CGColorSpaceCreateDeviceGray();

    var bitmapInfo = CGBitmapInfo(CGImageAlphaInfo.None.rawValue)

    var context = CGBitmapContextCreate(nil, Int(actualWidth), Int(actualHeight), 8, 0, colorSpace, bitmapInfo);
    CGContextDrawImage(context, imageRect, image.CGImage);

    var grayImage = CGBitmapContextCreateImage(context);
    bitmapInfo = CGBitmapInfo(CGImageAlphaInfo.Only.rawValue)
    context = CGBitmapContextCreate(nil, Int(actualWidth), Int(actualHeight), 8, 0, nil, bitmapInfo);
    CGContextDrawImage(context, imageRect, image.CGImage);
    var mask = CGBitmapContextCreateImage(context);

    var grayScaleImage = UIImage(CGImage: CGImageCreateWithMask(grayImage, mask), scale: image.scale, orientation: image.imageOrientation)

    // Return the new grayscale image
    return grayScaleImage!;
}

And if u want no alpha just delete the following line:

bitmapInfo = CGBitmapInfo(CGImageAlphaInfo.Only.rawValue)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文