4

標準の NSImage を黒ではなく白で描画しようとしています。以下は、現在の NSGraphicsContext で画像を黒で描画する場合にうまく機能します。

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

私は NSCompositeXOR がそのトリックを行うことを期待していましたが、そうではありません。複雑な [CIFilter filterWithName:@"CIColorInvert"] パスを下る必要がありますか? シンプルなものが欠けているように感じます。

4

3 に答える 3

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]];
于 2010-01-27T06:54:18.807 に答える
0

1 つだけ注意してください: CIColorInvert フィルターが常に信頼できるとは限らないことがわかりました。たとえば、Photoshop で反転された画像を元に戻す場合、CIFilter ははるかに明るい画像を生成します。私が理解している限りでは、CIFilter のガンマ値 (ガンマは 1) と他のソースからの画像の違いが原因で発生します。

CIFilter のガンマ値を変更する方法を探していたときに、CIContext にバグがあるというメモを見つけました。ガンマ値をデフォルトの 1 から変更すると、予期しない結果が生じるということです。

とにかく、NSBitmapImageRep のピクセルを反転することにより、常に正しい結果を生成する NSImage を反転する別の解決策があります。

私は etutorials.org ( http://bit.ly/Y6GpLn ) からコードを再投稿しています:

// 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];
于 2013-04-07T18:18:35.840 に答える