0

您好,感谢您的阅读!我正在尝试将 NSImage 对象写入磁盘上的文件,但是当我从原始 NSImage 中提取 NSData 对象时,由于某些“图像属性”丢失了,因此遇到了麻烦。

为了说明问题,我有以下代码。原始 NSImage 对象称为“图像”,我将其传递给 imageDump(最后输出),然后我从中提取一个 NSData 对象以便将其写入文件,但这样做似乎会删除一些图像属性。我再次调用 imageDump(最后再次输出),但这次注意一些属性是如何被删除的。例如 CGImageGetBitsPerPixel:从 32 开始,但在第二次调用 imageDump 时,它现在是 24?

当我在将 NSData 对象写入磁盘之前提取它时,如何防止这些图像属性被删除?

NSLog(@"/n PRINTING THE IMAGE PASSED TO THIS METHOD\n");
[self imageDump:[image CGImageForProposedRect:NULL context:NULL hints:NULL]];

NSData *imageData =  [image TIFFRepresentation];
NSImage *montysImage = [[NSImage alloc ] initWithData:imageData];

NSLog(@"/n PRINTING THE IMAGE THAT WAS FIRST CONVERTED TO NSDATA AND THEN BACK\n");
[self imageDump:[montysImage CGImageForProposedRect:NULL context:NULL hints:NULL]];

-(void)imageDump:(CGImageRef)cgimage  {


    size_t width  = CGImageGetWidth(cgimage);
    size_t height = CGImageGetHeight(cgimage);

    size_t bpr = CGImageGetBytesPerRow(cgimage);
    size_t bpp = CGImageGetBitsPerPixel(cgimage);
    size_t bpc = CGImageGetBitsPerComponent(cgimage);
    size_t bytes_per_pixel = bpp / bpc;

    CGBitmapInfo info = CGImageGetBitmapInfo(cgimage);

    NSString *file = @"file";

    NSLog(
          @"\n"
          "===== %@ =====\n"
          "CGImageGetHeight: %d\n"
          "CGImageGetWidth:  %d\n"
          "CGImageGetColorSpace: %@\n"
          "CGImageGetBitsPerPixel:     %d\n"
          "CGImageGetBitsPerComponent: %d\n"
          "CGImageGetBytesPerRow:      %d\n"
          "CGImageGetBitmapInfo: 0x%.8X\n"
          "  kCGBitmapAlphaInfoMask     = %s\n"
          "  kCGBitmapFloatComponents   = %s\n"
          "  kCGBitmapByteOrderMask     = %s\n"
          "  kCGBitmapByteOrderDefault  = %s\n"
          "  kCGBitmapByteOrder16Little = %s\n"
          "  kCGBitmapByteOrder32Little = %s\n"
          "  kCGBitmapByteOrder16Big    = %s\n"
          "  kCGBitmapByteOrder32Big    = %s\n",
          file,
          (int)width,
          (int)height,
          CGImageGetColorSpace(cgimage),
          (int)bpp,
          (int)bpc,
          (int)bpr,
          (unsigned)info,
          (info & kCGBitmapAlphaInfoMask)     ? "YES" : "NO",
          (info & kCGBitmapFloatComponents)   ? "YES" : "NO",
          (info & kCGBitmapByteOrderMask)     ? "YES" : "NO",
          (info & kCGBitmapByteOrderDefault)  ? "YES" : "NO",
          (info & kCGBitmapByteOrder16Little) ? "YES" : "NO",
          (info & kCGBitmapByteOrder32Little) ? "YES" : "NO",
          (info & kCGBitmapByteOrder16Big)    ? "YES" : "NO",
          (info & kCGBitmapByteOrder32Big)    ? "YES" : "NO"  );



    CGDataProviderRef provider = CGImageGetDataProvider(cgimage);
    NSData* data = (__bridge id)CGDataProviderCopyData(provider);
    //[data autorelease];
    const uint8_t* bytes = [data bytes];

    printf("Pixel Data:\n");
    for(size_t row = 0; row < height; row++)
    {
        for(size_t col = 0; col < width; col++)
        {
            const uint8_t* pixel = &bytes[row * bpr + col * bytes_per_pixel];

            printf("(");
            for(size_t x = 0; x < 3; x++) // 3 WAS -> bytes_per_pixel - changed to remove the alpha component.
            {
                printf("%.2X", pixel[x]);
                if( x < 3 - 1 ) // 3 WAS -> bytes_per_pixel - changed to remove the alpha component.
                    printf(",");
            }

            printf(")");
            if( col < width - 1 )
                printf(", ");
        }

        printf("\n");
    }
}

控制台输出:

2013-11-06 22:52:01.082 LibraryBuilder[20792:303] /n PRINTING THE IMAGE PASSED TO THIS METHOD
2013-11-06 22:52:01.082 LibraryBuilder[20792:303] 
===== file =====
CGImageGetHeight: 6
CGImageGetWidth:  7
CGImageGetColorSpace: <CGColorSpace 0x60000003b840> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; Color LCD)
CGImageGetBitsPerPixel:     32
CGImageGetBitsPerComponent: 8
CGImageGetBytesPerRow:      64
CGImageGetBitmapInfo: 0x00002006
  kCGBitmapAlphaInfoMask     = YES
  kCGBitmapFloatComponents   = NO
  kCGBitmapByteOrderMask     = YES
  kCGBitmapByteOrderDefault  = NO
  kCGBitmapByteOrder16Little = NO
  kCGBitmapByteOrder32Little = YES
  kCGBitmapByteOrder16Big    = YES
  kCGBitmapByteOrder32Big    = NO
Pixel Data:
(F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (EA,D9,C2)
(F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7)
(F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7)
(F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7)
(B3,B3,B3), (B3,B3,B3), (B3,B3,B3), (B3,B3,B3), (B3,B3,B3), (B3,B3,B3)
(F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7)
(F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7)

2013-11-06 22:52:01.122 LibraryBuilder[20792:303] /n PRINTING THE IMAGE THAT WAS FIRST CONVERTED TO NSDATA AND THEN BACK
2013-11-06 22:52:01.122 LibraryBuilder[20792:303] 
===== file =====
CGImageGetHeight: 6
CGImageGetWidth:  7
CGImageGetColorSpace: <CGColorSpace 0x618000032f40> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; Color LCD)
CGImageGetBitsPerPixel:     24
CGImageGetBitsPerComponent: 8
CGImageGetBytesPerRow:      18
CGImageGetBitmapInfo: 0x00000000
  kCGBitmapAlphaInfoMask     = NO
  kCGBitmapFloatComponents   = NO
  kCGBitmapByteOrderMask     = NO
  kCGBitmapByteOrderDefault  = NO
  kCGBitmapByteOrder16Little = NO
  kCGBitmapByteOrder32Little = NO
  kCGBitmapByteOrder16Big    = NO
  kCGBitmapByteOrder32Big    = NO
Pixel Data:
(F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (C2,D9,EA)
(F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7)
(F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7)
(F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7)
(B3,B3,B3), (B3,B3,B3), (B3,B3,B3), (B3,B3,B3), (B3,B3,B3), (B3,B3,B3)
(F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7)
(F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7), (F7,F7,F7)
4

1 回答 1

0

目前尚不清楚是否有任何数据实际上丢失了。有很多方法可以表示完全相同的图像,并且您正在做一堆扭曲来转储可能会修改其格式的数据(而不改变它的绘制方式)。就像,图像是存储 BRG 还是 RGB 或 BGR 都没有关系,但是这些会改变你的转储的外观。

在你的例子中,如果你的原始图像有一个透明通道,但它总是 100% 不透明,那么 -TIFFRepresentation 调用可能(合理地)决定不写出透明通道,所以当你读回它时它就会消失。但这不会改变图像的绘制方式。

您没有在转储中显示 alpha 通道,因此不清楚您是否丢失了任何数据,但其他一切看起来都很正常。

于 2014-01-09T17:58:49.910 回答