English 中文(简体)
生产从CGImage CCITT压缩TIFF
原标题:
  • 时间:2009-04-16 22:14:04
  •  标签:

我有一个CGImage(核心图形,C / c++)。它年代灰度。哦,原来这是B / W,但CGImage可能RGB。应该t。我想创建一个CCITT-Group 4 TIFF。

我可以创建一个LZW TIFF(灰度或颜色)通过创建目的地与正确的词典和添加图像。没有问题。

然而,似乎并t同等代表CCITT-4 kCGImagePropertyTIFFCompression价值。应该是4,但产生的未压缩的。

我有一个手动CCITT压缩程序,所以如果我可以得到二进制(1位/像素)的数据,我设置。但我可以t似乎1 BPP CGImage的数据。我的代码应该把CGImage放进CGBitmapContext然后给我的数据,但它似乎给了我所有的黑人。

我今天已经问了几个问题想达到这一点,但我只是想,让问我真正想要的回答,看看是否有人能回答它。

年代必须有一种方法来做到这一点。我要失踪愚蠢的东西。它是什么?

问题回答

这似乎工作和产生not-all-black输出。可能存在一种方法涉及到这不手动转换为灰度第一,但至少它工作!

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

< a href = " http://www.imagemagick.org/script/index.php " rel = " nofollow noreferrer " > ImageMagick < / >可以从和几乎任何图像格式转换。因为它是开源的你可以去读< a href = " http://www.imagemagick.org/script/subversion.php " rel = " nofollow noreferrer " > < / >源代码找到你问题的答案。

您甚至可以使用< a href = " http://www.imagemagick.org/Magick + + /”rel = " nofollow noreferrer " > < / > ImageMagick API在你应用程序使用c++。

Edit:
If you can get the data from CGImage in any format (and it sounded like you can) you can use ImageMagick to convert it from whatever the format is that you get from CGImage to any other format supported by ImageMagick (your desired TIFF format).

Edit: Technical Q&A QA1509 Getting the pixel data from a CGImage object states:

在Mac OS X 10.5或更高版本,添加了一个新电话,允许您从CGImage对象获取实际的像素数据。CGDataProviderCopyData,这个调用返回一个CFData对象包含图像的像素数据。

一旦你有了像素数据可以使用ImageMagick转换它。

NSBitmapImageRep声称能够生成一个CCITT传真组4压缩TIFF。所以这样可能奏效(未测试):

CFDataRef tiffFaxG4DataForCGImage(CGImageRef cgImage) {
  NSBitmapImageRep *imageRep =
      [[[NSBitmapImageRep alloc] initWithCGImage:cgImage] autorelease];
  NSData *tiffData =
      [imageRep TIFFRepresentationUsingCompression:NSTIFFCompressionCCITTFAX4
                                            factor:0.0f];
  return (CFDataRef) tiffData;
}

这个函数应该返回的数据。





相关问题
热门标签