2009-04-16 107 views
2

我有一个CGImage(核心图形,C/C++)。这是灰度。那么,最初是B/W,但CGImage可能是RGB。这应该不重要。我想创建一个CCITT-Group 4 TIFF。从CGImage生成CCITT压缩的TIFF

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

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

我有一个手动CCITT压缩程序,所以如果我可以得到二进制(每像素1位)数据,我设置。但我似乎无法从CGImage中获取1个BPP数据。我有代码应该把CGImage放到CGBitmapContext中,然后给我数据,但它似乎给我全黑。

我已经问了一些问题,今天试图得到这个,但我只是想,让我们问我真的想要回答的问题,看看有人能回答它。

有GOT可以做到这一点。我必须失去一些愚蠢的东西。它是什么?

回答

1

ImageMagick可以转换和几乎任何图像格式。因为它是开源的,你可以去阅读source code来找到你的问题的答案。

如果您使用C++,您甚至可以在您的应用程序中使用ImageMagick API

编辑:
如果你可以从CGImage数据以任何格式(和它听起来像您可以),你可以使用ImageMagick的它无论从任何转换格式是你从CGImage到任何其他格式由ImageMagick支持(您所需的TIFF格式)。

编辑: Technical Q&A QA1509 Getting the pixel data from a CGImage object状态:

在Mac OS X 10.5或更高版本,一个新的呼叫已被添加,允许你从CGImage对象获得实际的像素数据。这个调用CGDataProviderCopyData返回一个CFData对象,该对象包含有问题的图像的像素数据。

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

+0

这没有帮助,因为它根本没有显示图像。所以它不处理CGImage对象。假设我有1Bit数据,我已经有读取组4文件并编写它们的代码。我需要以这种方式从CGImage中获取数据,以便我可以编写TIFF ... – 2009-04-17 13:20:41

+0

如果您可以以任何格式从CGImage获取数据(并且听起来可以),则可以使用ImageMagick将其从CGImage获得的格式转换为ImageMagick支持的任何其他格式(您所需的TIFF格式) 。 – lothar 2009-04-17 15:34:01

+0

好吧,我真的不能从CGImage中获取二进制数据...我可以用其他格式保存文档,但我宁愿不保存,然后转换... – 2009-04-20 13:55:30

1

NSBitmapImageRep宣称能够生成CCITT FAX Group 4压缩的TIFF。所以像这样的东西可能会做伎俩(未经测试):

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

此函数应该返回您寻找的数据。

2

这似乎工作,并产生不全黑输出。可能有办法做到这一点,不需要手动将灰度转换为灰度,但至少可以工作!

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