2010-01-26 5 views
3

표준 NSImage를 검은 색 대신 흰색으로 그립니다. 현재 NSGraphicsContext에 검은 색으로 이미지를 그리기위한 미세 다음 작품 : 표준 NSImage를 뒤집어 그립니다 (검은 색 대신 흰색).

NSImage* image = [NSImage imageNamed:NSImageNameEnterFullScreenTemplate]; 
[image drawInRect:r fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; 

나는 NSCompositeXOR 더 트릭을 할 만 할 것으로 예상. 복잡한 [CIFilter filterWithName : @ "CIColorInvert"] 경로를 내려야합니까? 나는 무언가를 놓치고있는 것처럼 느껴진다.

앤더스

답변

6

핵심 이미지 경로는 가장 신뢰할 수있는 것입니다. 실제로는 그렇게 복잡하지는 않지만 아래 샘플을 게시했습니다. 이미지를 뒤집을 수 없다는 것을 알고 있으면 변환 코드를 제거 할 수 있습니다. 주의해야 할 주요 사항은 NSImage에서 CIImage으로의 변환이 성능면에서 비쌉니다. 가능한 경우 CIImage을 캐시에 저장하고 각 그리기 작업 중에 다시 생성하지 않도록해야합니다.

CIImage* ciImage = [[CIImage alloc] initWithData:[yourImage TIFFRepresentation]]; 
if ([yourImage isFlipped]) 
{ 
    CGRect cgRect = [ciImage extent]; 
    CGAffineTransform transform; 
    transform = CGAffineTransformMakeTranslation(0.0,cgRect.size.height); 
    transform = CGAffineTransformScale(transform, 1.0, -1.0); 
    ciImage = [ciImage imageByApplyingTransform:transform]; 
} 
CIFilter* filter = [CIFilter filterWithName:@"CIColorInvert"]; 
[filter setDefaults]; 
[filter setValue:ciImage forKey:@"inputImage"]; 
CIImage* output = [filter valueForKey:@"outputImage"]; 
[output drawAtPoint:NSZeroPoint fromRect:NSRectFromCGRect([output extent]) operation:NSCompositeSourceOver fraction:1.0]; 

참고 : 메모리 관리 해제/유지는 연습으로 남겨 둡니다. 위의 코드는 가비지 수집을 가정합니다. 당신은 임의의 크기로 이미지를 렌더링 할 경우

, 당신은 다음 작업을 수행 할 수 있습니다 :

NSSize imageSize = NSMakeSize(1024,768); //or whatever size you want 
[yourImage setSize:imageSize]; 
[yourImage lockFocus]; 
NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect(0, 0, imageSize.width, imageSize.height)]; 
[yourImage unlockFocus]; 
CIImage* image = [CIImage imageWithData:[bitmap TIFFRepresentation]]; 
+0

감사합니다, 색상 반전 문제를 해결 않습니다

나는 etutorials.org의 코드 (http://bit.ly/Y6GpLn를) 다시 게시하고 있습니다. 불행히도, 그것은 나에게 완전한 해상도를주지 못합니다. 초기 TIFFRepresentation은 그리기 원하는 크기보다 훨씬 작습니다. 어떻게하면 고해상도로 데이터를 얻을 수 있습니까? – smartgo

+0

원하는 크기를 사용하여'NSImage'에서'NSBitmapImageRep'을 생성 한 다음 비트 맵에서'CIImage'를 생성 할 수 있습니다. http://pastie.org/798088 –

+0

완벽하게 고마워요! – smartgo

0

딱 한 주 : 나는 CIColorInvert 필터는 항상 신뢰할 수 없습니다 것을 발견했다. 예를 들어, Photoshop에서 반전 된 이미지를 반전 시키려면 CIFilter가 훨씬 더 밝은 이미지를 생성합니다. 내가 알기 론, CIFilter (감마는 1)의 감마값과 다른 출처의 이미지의 차이로 인해 발생합니다.

CIFilter의 감마 값을 변경하는 방법을 찾고있는 동안 CIContext에 버그가 있다는 것을 발견했습니다. 감마 값을 기본값 1에서 변경하면 예기치 않은 결과가 발생합니다.

NSBitmapImageRep의 픽셀을 반전시킴으로써 항상 올바른 결과를 생성하는 NSImage를 반전시킬 수있는 또 다른 해결책이 있습니다.

// srcImageRep is the NSBitmapImageRep of the source image 
int n = [srcImageRep bitsPerPixel]/8;   // Bytes per pixel 
int w = [srcImageRep pixelsWide]; 
int h = [srcImageRep pixelsHigh]; 
int rowBytes = [srcImageRep bytesPerRow]; 
int i; 

NSImage *destImage = [[NSImage alloc] initWithSize:NSMakeSize(w, h)]; 
NSBitmapImageRep *destImageRep = [[[NSBitmapImageRep alloc] 
     initWithBitmapDataPlanes:NULL 
      pixelsWide:w 
      pixelsHigh:h 
      bitsPerSample:8 
      samplesPerPixel:n 
      hasAlpha:[srcImageRep hasAlpha] 
      isPlanar:NO 
      colorSpaceName:[srcImageRep colorSpaceName] 
      bytesPerRow:rowBytes 
      bitsPerPixel:NULL] autorelease]; 

unsigned char *srcData = [srcImageRep bitmapData]; 
unsigned char *destData = [destImageRep bitmapData]; 

for (i = 0; i < rowBytes * h; i++) 
    *(destData + i) = 255 - *(srcData + i); 

[destImage addRepresentation:destImageRep]; 
관련 문제