Pregunta

Estoy tratando de dibujar una NSImage estándar en blanco en lugar de negro. El siguiente funciona bien para dibujar la imagen en negro en la corriente NSGraphicsContext:

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

Me esperaba NSCompositeXOR para hacer el truco, pero no. ¿Es necesario ir por el complicado [CIFilter filterWithName: @ "CIColorInvert"] camino? Siento que debo estar perdiendo algo simple.

Anders

¿Fue útil?

Solución

La ruta Core Image sería el más fiable. En realidad no es muy complicado, he publicado una muestra a continuación. Si conoces a ninguno de sus imágenes se volcó entonces se puede eliminar el código de transformación. Lo principal a tener cuidado es que la conversión de NSImage a CIImage puede ser costoso en cuanto al rendimiento, por lo que debe asegurarse de guardar en caché el CIImage si es posible y no es necesario volver a crearlo durante cada operación de trazado.

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

Nota:. Liberación / retener la gestión de memoria se deja como un ejercicio, el código anterior supone la recogida de basura

Si desea procesar la imagen en un tamaño arbitrario, se puede hacer lo siguiente:

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

Otros consejos

Sólo una nota: me encontré con que el filtro CIColorInvert no siempre es fiable. Por ejemplo, si desea invertir vuelta una imagen invertida en Photoshop, el CIFilter producirá una imagen mucho más ligero. Por lo que he entendido, sucede debido a las diferencias en el valor de gamma CIFilter (gamma es 1) y las imágenes que vienen de otras fuentes.

Mientras que estaba buscando maneras de cambiar el valor gamma de CIFilter, encontré una nota que hay un error en CIContext:. Cambiar su valor de gama del valor predeterminado 1 producirá resultados impredecibles

Independientemente, no hay otra solución para invertir NSImage, que siempre produce los resultados correctos -. Invirtiendo pixeles de NSBitmapImageRep

Estoy volver a colocar el código de 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];
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top