2012-06-07 15 views
5

Estoy intentando voltear un NSImage creado con una representación NSImageBitmapRep. Después de algunas excavaciones (Flipping Quicktime preview & capture y Mirroring CIImage/NSImage) probé de dos maneras a través de un CIImage y aplicando una transformación de escala con -1 para ambos factores.Flip NSImage en ambos ejes

En primer lugar usando CIImage imageByApplyingTransform:

NSBitmapImageRep *imgRep = ... 
    CGImageRef cgi = [imgRep CGImage]; 
    CIImage *cii = [CIImage imageWithCGImage:cgi]; 
    CGAffineTransform at = CGAffineTransformTranslate(CGAffineTransformMakeScale(-1, -1), 0, 0); 
    NSCIImageRep *ciiRep = [NSCIImageRep imageRepWithCIImage:[cii imageByApplyingTransform:at]]; 

    NSImage *img = [[[NSImage alloc] init] autorelease]; 
    [img addRepresentation:ciiRep]; 
    [self.ivImage setImage:img]; 

a continuación, utilizando un filtro CIAffineTransform:

NSBitmapImageRep *imgRep = ... 
    CGImageRef cgi = [imgRep CGImage]; 
    CIImage *cii = [CIImage imageWithCGImage:cgi]; 
    CIFilter *f = [CIFilter filterWithName:@"CIAffineTransform"]; 
    NSAffineTransform *t = [NSAffineTransform transform]; 
    [t scaleXBy:1.0 yBy:1.0]; 
    //[t translateXBy:width yBy:0]; 
    [f setValue:t forKey:@"inputTransform"]; 
    [f setValue:cii forKey:@"inputImage"]; 
    CIImage *cii2 = [f valueForKey:@"outputImage"]; 
    NSCIImageRep *ciiRep = [NSCIImageRep imageRepWithCIImage:cii2]; 

    NSImage *img = [[[NSImage alloc] init] autorelease]; 
    [img addRepresentation:ciiRep]; 
    [self.ivImage setImage:img]; 

Ambas formas producen una imagen en blanco. También traté de traducir la imagen, en caso de que esté fuera de la pantalla debido a las escalas de -1, pero fue en vano. Si uso valores positivos para la escala, puedo ver que la transformación se aplica correctamente.

self.ivImage es un NSImageView. Quiero un NSImage real que se voltee, por lo que aplicar una transformación al NSImageView no es una opción.

Esto es 32bits, Xcode 4.3.2 en Lion.

Respuesta

7

Debe iniciar su NSImage con un tamaño.

Muestra tu intento con la traducción, porque esa es la manera correcta. Normalmente, es más fácil traducir primero y luego escalar. Parece que los fragmentos de código tienen vestigios de intentos de traducción, pero no están correctos. Se traduce por 0,0 en un caso y ancho, 0 en otro. Además, en su segundo fragmento de código, está escalando 1,1 (positivo), por lo que no se invierte.

Además, puede ser más simple simplemente bloquear el enfoque en una nueva imagen del tamaño apropiado, configurar la transformación y dibujar la imagen representada. Evita todas esas cosas con CIImage.

NSBitmapImageRep *imgRep = ... 
NSImage* img = [[[NSImage alloc] initWithSize:NSMakeSize(imgRep.pixelsWide, imgRep.pixelsHigh)] autorelease]; 
[img lockFocus]; 
NSAffineTransform* t = [NSAffineTransform transform]; 
[t translateXBy:imgRep.pixelsWide yBy:imgRep.pixelsHigh]; 
[t scaleXBy:-1 yBy:-1]; 
[t concat]; 
[imgRep drawInRect:NSMakeRect(0, 0, imgRep.pixelsWide, imgRep.pixelsHigh)]; 
[img unlockFocus]; 
+0

Gracias, que trabajaron nada más sacarlo de la caja! :) ¡Y es mucho más limpio sin el desvío a través de CIImage! Mis pruebas con traducción y escalado positivo se dejaron para probar si la transformación se aplicó en absoluto. – msohn

+0

Solución perfecta. ¡Gracias por eso! –

5

De todos modos, creo que una buena idea debería ser publicar una función completa. Aquí está mi solución basada en Ken enviar

- (NSImage *)flipImage:(NSImage *)image 
{ 
    NSImage *existingImage = image; 
    NSSize existingSize = [existingImage size]; 
    NSSize newSize = NSMakeSize(existingSize.width, existingSize.height); 
    NSImage *flipedImage = [[[NSImage alloc] initWithSize:newSize] autorelease]; 

    [flipedImage lockFocus]; 
    [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh]; 

    NSAffineTransform *t = [NSAffineTransform transform]; 
    [t translateXBy:existingSize.width yBy:existingSize.height]; 
    [t scaleXBy:-1 yBy:-1]; 
    [t concat]; 

    [existingImage drawAtPoint:NSZeroPoint fromRect:NSMakeRect(0, 0, newSize.width, newSize.height) operation:NSCompositeSourceOver fraction:1.0]; 

    [flipedImage unlockFocus]; 

    return flipedImage; 
} 
0

vertical del tirón para

- (NSImage *)flipImageVertically:(NSImage *)inputImage { 

    NSImage *tmpImage; 
    NSAffineTransform *transform = [NSAffineTransform transform]; 

    NSSize dimensions = [inputImage size]; 
    NSAffineTransformStruct flip = {1.0, 0.0, 0.0, -1.0, 0.0, 
     dimensions.height}; 
    tmpImage = [[NSImage alloc] initWithSize:dimensions]; 
    [tmpImage lockFocus]; 
    [transform setTransformStruct:flip]; 
    [transform concat]; 
    [inputImage drawAtPoint:NSMakePoint(0,0) 
         fromRect:NSMakeRect(0,0, dimensions.width, dimensions.height) 
         operation:NSCompositeCopy fraction:1.0]; 
    [tmpImage unlockFocus]; 


    return [tmpImage autorelease]; 

} 

para flip horizontal

+ (NSImage *)flipImageHorizontally:(NSImage *)inputImage { 

    NSImage *tmpImage; 
    NSAffineTransform *transform = [NSAffineTransform transform]; 

    NSSize dimensions = [inputImage size]; 
    NSAffineTransformStruct flip = {-1.0, 0.0, 0.0, 1.0, 
     dimensions.width, 0.0 }; 
    tmpImage = [[NSImage alloc] initWithSize:dimensions]; 
    [tmpImage lockFocus]; 
    [transform setTransformStruct:flip]; 
    [transform concat]; 
    [inputImage drawAtPoint:NSMakePoint(0,0) 
         fromRect:NSMakeRect(0,0, dimensions.width, dimensions.height) 
         operation:NSCompositeCopy fraction:1.0]; 
    [tmpImage unlockFocus]; 

    return [tmpImage autorelease]; 

}