【问题标题】:Convert indexed color .png to RGB or greyscale将索引颜色 .png 转换为 RGB 或灰度
【发布时间】:2017-02-07 14:42:53
【问题描述】:

我正在编写这个 Today Widget,它需要显示一张图片。 我注意到,每次加载小部件时,都会重新绘制图像。这大约需要半秒钟。 经过一番调查,我发现罪魁祸首是图像文件位于索引颜色空间中。 所以:我的问题是: 如何将此文件转换为 iPhone 可以更有效地显示的内容?例如,RGB 文件。然后我会将它保存到一个新文件中,并将该新文件加载到我的 UIImageView 中。

我玩了一下 CGImage,因为我相信这是解决方案的方向,但我最终得到了一个白色的 UIImageView。

这是我的代码:

UIImage * theCartoon = [UIImage imageWithData:imageData];
    CGImageRef si = [theCartoon CGImage];
    CGDataProviderRef src = CGImageGetDataProvider(si);
    CGImageRef imageRef = CGImageCreateWithPNGDataProvider(src, NULL, NO, kCGRenderingIntentDefault);
    cartoon.image = [[UIImage alloc] initWithCGImage:imageRef];

对这种方法有什么建议吗?一些明显的错误编程?

【问题讨论】:

    标签: ios objective-c cgimage color-space


    【解决方案1】:

    试试这个

    // The source image
    CGImageRef image = theCartoon.CGImage;
    CGSize size = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image));
    
    // The result image in RGB color space   
    CGImageRef result = nil;
    
    // Check color space
    CGColorSpaceRef srcColorSpace = CGImageGetColorSpace(image);
    if (CGColorSpaceGetModel(srcColorSpace) != kCGColorSpaceModelRGB) {
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef context = CGBitmapContextCreate(nil, size.width, size.height, 8, 0, colorSpace, kCGImageAlphaNoneSkipLast);
    
        CGRect rect = {CGPointZero, size};
        CGContextDrawImage(context, rect, image);
        result = CGBitmapContextCreateImage(context);
    
        CGContextRelease(context);
        CGColorSpaceRelease(colorSpace);
    }
    

    【讨论】:

      【解决方案2】:

      问这个问题已经有一段时间了,但是对于可能需要这个问题的其他人,这是我的解决方案:

      -(UIImage *) convertIndexedColorSpaceToRGB:(UIImage *) sourceImage {
      
      CGImageRef originalImageRef = sourceImage.CGImage;
      const CGBitmapInfo originalBitmapInfo = CGImageGetBitmapInfo(originalImageRef);
      
      // See: http://stackoverflow.com/questions/23723564/which-cgimagealphainfo-should-we-use
      const uint32_t alphaInfo = (originalBitmapInfo & kCGBitmapAlphaInfoMask);
      CGBitmapInfo bitmapInfo = originalBitmapInfo;
      switch (alphaInfo)
      {
          case kCGImageAlphaNone:
              bitmapInfo |= kCGBitmapByteOrder32Big | kCGImageAlphaNoneSkipLast;
              break;
          case kCGImageAlphaPremultipliedFirst:
          case kCGImageAlphaPremultipliedLast:
          case kCGImageAlphaNoneSkipFirst:
          case kCGImageAlphaNoneSkipLast:
              break;
          case kCGImageAlphaOnly:
          case kCGImageAlphaLast:
          case kCGImageAlphaFirst:
          { 
              return sourceImage;
          }
              break;
      }
      
      const CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
      const CGSize pixelSize = CGSizeMake(sourceImage.size.width * sourceImage.scale, sourceImage.size.height * sourceImage.scale);
      
      const CGContextRef context = CGBitmapContextCreate(NULL,
                                                         pixelSize.width,
                                                         pixelSize.height,
                                                         CGImageGetBitsPerComponent(originalImageRef),
                                                         pixelSize.width*4,
                                                         colorSpace,
                                                         bitmapInfo
                                                         );
      
      CGColorSpaceRelease(colorSpace);
      
      if (!context) return sourceImage;
      
      const CGRect imageRect = CGRectMake(0, 0, pixelSize.width, pixelSize.height);
      UIGraphicsPushContext(context);
      
      // Flip coordinate system. See: http://stackoverflow.com/questions/506622/cgcontextdrawimage-draws-image-upside-down-when-passed-uiimage-cgimage
      CGContextTranslateCTM(context, 0, pixelSize.height);
      CGContextScaleCTM(context, 1.0, -1.0);
      [sourceImage drawInRect:imageRect];
      UIGraphicsPopContext();
      const CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);
      CGContextRelease(context);
      UIImage *image = [UIImage imageWithCGImage:decompressedImageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
      CGImageRelease(decompressedImageRef);
      
      return image; }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-27
        • 2013-01-12
        • 1970-01-01
        • 1970-01-01
        • 2020-04-29
        • 1970-01-01
        • 1970-01-01
        • 2011-07-10
        相关资源
        最近更新 更多