c++ - 从 CGImage 生成 CCITT 压缩的 TIFF

标签 c++ macos core-graphics cgimage

我有一个 CGImage(核心图形,C/C++)。是灰度的。嗯,本来是B/W,但是CGImage可能是RGB。那应该没关系。我想创建 CCITT-Group 4 TIFF。

我可以通过使用正确的字典创建目标并添加图像来创建 LZW TIFF(灰度或彩色)。没问题。

但是,似乎没有等效的 kCGImagePropertyTIFFCompression 值来表示 CCITT-4。它应该是 4,但这会产生未压缩的结果。

我有一个手动 CCITT 压缩例程,因此如果我可以获得二进制(每像素 1 位)数据,我就准备好了。但我似乎无法从 CGImage 中获取 1 BPP 数据。我有代码应该将 CGImage 放入 CGBitmapContext 然后给我数据,但它似乎给了我全黑。

我今天问了几个问题试图解决这个问题,但我只是想,让我们问我真正想要回答的问题,看看是否有人可以回答。

一定有办法做到这一点。我一定错过了一些愚蠢的东西。它是什么?

最佳答案

这似乎有效并产生非全黑输出。可能有一种方法可以做到这一点,首先不需要手动转换为灰度,但至少它有效!

static void WriteCCITTTiffWithCGImage_URL_(CGImageRef im, CFURLRef url) {
    // produce grayscale image
    CGImageRef grayscaleImage;
    {
        CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
        CGContextRef bitmapCtx = CGBitmapContextCreate(NULL, CGImageGetWidth(im), CGImageGetHeight(im), 8, 0, colorSpace, kCGImageAlphaNone);
        CGContextDrawImage(bitmapCtx, CGRectMake(0,0,CGImageGetWidth(im), CGImageGetHeight(im)), im);
        grayscaleImage = CGBitmapContextCreateImage(bitmapCtx);
        CFRelease(bitmapCtx);
        CFRelease(colorSpace);
    }

    // generate options for ImageIO. Man this sucks in C.
    CFMutableDictionaryRef options = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    {
        {
            CFMutableDictionaryRef tiffOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
            int fourInt = 4;
            CFNumberRef fourNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &fourInt);
            CFDictionarySetValue(tiffOptions, kCGImagePropertyTIFFCompression, fourNumber);
            CFRelease(fourNumber);

            CFDictionarySetValue(options, kCGImagePropertyTIFFDictionary, tiffOptions);

            CFRelease(tiffOptions);                
        }

        {
            int oneInt = 1;
            CFNumberRef oneNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &oneInt);

            CFDictionarySetValue(options, kCGImagePropertyDepth, oneNumber);

            CFRelease(oneNumber);
        }
    }

    // write file
    CGImageDestinationRef idst = CGImageDestinationCreateWithURL(url, kUTTypeTIFF, 1, NULL);
    CGImageDestinationAddImage(idst, grayscaleImage, options);
    CGImageDestinationFinalize(idst);

    // clean up
    CFRelease(idst);
    CFRelease(options);
    CFRelease(grayscaleImage);
}


Nepheli:tmp ken$ tiffutil -info /tmp/output.tiff 
Directory at 0x1200
  Image Width: 842 Image Length: 562
  Bits/Sample: 1
  Sample Format: unsigned integer
  Compression Scheme: CCITT Group 4 facsimile encoding
  Photometric Interpretation: "min-is-black"
  Orientation: row 0 top, col 0 lhs
  Samples/Pixel: 1
  Number of Strips: 1
  Planar Configuration: Not planar

关于c++ - 从 CGImage 生成 CCITT 压缩的 TIFF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/758249/

相关文章:

objective-c - ConnectionKit框架: Adding it to a project

ios - 获取Apple Clock应用程序中使用的城市/时区列表

ios - 通过应用过滤从 ALAsset 获取缩略图的快速方法

ios - 在 CGContext 中绘制透明 PNG 显示为黑色

c++ - 从访问者更改 boost::variant 基础类型

c++ - QtCreator : No valid kits found

c++ - C 和 C++ 中 void 指针的区别

java - 使用 java 执行和终止 OSX 的任何应用程序

ios - 如何在 iOS 运行时修改索引 PNG 的调色板?

c++ - 运行时在错误的库中搜索来自 libc++ 的符号