2009-04-16 5 views
2

CGImage (코어 그래픽, C/C++)가 있습니다. 회색조입니다. 음, 원래 B/W 였지만 CGImage는 RGB 일 수 있습니다. 그건 중요하지 않아. CCITT-Group 4 TIFF를 만들고 싶습니다.CGImage에서 CCITT 압축 TIFF 생성

나는 올바른 사전에 목적지를 만들고에 이미지를 추가를 통해 LZW의 TIFF (흑백 또는 컬러)를 만들 수 없습니다. 아무 문제.

그러나 CCITT-4를 나타내는 등가 kCGImagePropertyTIFFCompression 값일 수없는 것. 그것은 4이어야하지만 압축되지 않은 상태로 생성됩니다.

나는 수동 CCITT 압축 루틴을 가지고, 그래서 데이터 바이너리 (픽셀 당 1 비트)을 얻을 수 있다면, 내가 설정하고있다. 하지만 CGI 이미지에서 1 BPP 데이터를 가져올 수 없습니다. CGImage를 CGBitmapContext에 넣은 다음 코드를 가지고 나에게 데이터를 주겠다. 그러나 그것은 나에게 모두 검은 색으로 보인다.

는 내가 이것려고 오늘 몇 가지 질문을 요청했습니다,하지만 난 그냥 생각, 내가 정말 대답하려는 질문을 누군가가 답변을 할 수 있는지 볼 수 있습니다.

이렇게하는 방법이 있습니다. 나는 바보 같은 것을 놓치고있어. 이게 뭐야?

답변

1

ImageMagick은 거의 모든 이미지 형식으로 변환 할 수 있습니다. 오픈 소스이므로 source code을 읽고 질문에 대한 답을 찾을 수 있습니다. 당신은 C를 사용하는 경우

당신은 ++ 응용 프로그램 당신의 ImageMagick API를 사용할 수 있습니다.

편집 :
당신은 형식이 다른 형식의 CGImage에서 얻을 것이 무엇이든에서 변환하는 ImageMagick를 사용할 수 있습니다 당신은 어떤 형식의 CGImage의 데이터를 얻을 수있다 (그리고 당신이 할 수처럼 소리가났다) 경우 ImageMagick (원하는 TIFF 형식)에서 지원됩니다.

편집 : Technical Q&A QA1509 Getting the pixel data from a CGImage object 상태 :

맥 OS X 10.5에

이상, 새 통화 당신이의 CGImage 객체에서 실제 픽셀 데이터를 얻을 수 있습니다 추가되었습니다. 이 CGDataProviderCopyData 호출은 해당 이미지의 픽셀 데이터가 포함 된 CFData 객체를 반환합니다.

일단 픽셀 데이터가 있으면 ImageMagick을 사용하여 변환 할 수 있습니다.

+0

실제로 이미지를 전혀 표시하지 않기 때문에 도움이되지 않습니다. 따라서 CGImage 객체를 다루지 않습니다. 이미 1Bit 데이터가 있다고 가정하고 그룹 4 파일을 읽고 쓰는 코드가 있습니다. CGImage에서 TIFF를 작성할 수있는 방식으로 데이터를 가져와야합니다. –

+0

CGImage에서 어떤 형식 으로든 데이터를 가져올 수 있고 가능하다면 ImageMagick을 사용하여 CGImage에서 얻은 형식이 ImageMagick에서 지원하는 다른 형식 (원하는 TIFF 형식)으로 변환 할 수 있습니다. . – lothar

+0

음, CGImage에서 실제로 이진 데이터를 가져 오는 것 같지 않습니다. 다른 형식으로 문서를 저장할 수는 있지만 저장하지 않고 변환하면됩니다. –

1

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; 
} 

: 그래서 이런 일이 (안된) 트릭을 할 수 있습니다.

+0

그건 목표 C, C++이 아닙니다. –

+0

예 -하지만 그게 왜 문제가됩니까? Objective-C는 C의 엄격한 수퍼 세트로, C 함수에서 Objective-C 코드를 쉽게 감쌀 수 있고 C 코드에서 사용할 수 있습니다. 사실, 애플은 C API 중 일부를 위해 Objective-C 구현을 중심으로 C 함수를 랩핑했습니다. –

+0

자동 복구 풀이 없을 때 객체를 자동 리 레스하면 콘솔 스팸과 메모리 누출이 발생합니다 (이 경우 상당히 중요한 것입니다). –

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 
+0

목표 C 또는 C++입니까? 그것은 wierd 조합처럼 보입니다. C++에서는 압축 4가 작동하지 않는다고 생각합니다. 그것은 압축되지 않은 데이터를 제공합니다 ... –

+0

당신이 쓰는 언어는 API의 동작에 영향을 미치지 않을 것입니다. 이것은 Objective-C입니다. 나는 그것을 당신을 위해 순수한 C로 다시 쓰겠습니다. – user96459

+0

좋아, C로 편집해야합니다. C++로 컴파일해야합니다. CGImageDestination은 libtiff를 다루고 unmolested를 통해 압축을 전달합니다. 나는 depth == 1과 회색 음영 이미지를 명시 적으로 전달해야만 작동한다는 것을 알았습니다. 당신이 libtiff와 ​​"CCITT Group 4"에 대해 구글이라면 그것에 대해 질문하는 사람들이 보일 것입니다. – user96459

관련 문제