2012-06-07 13 views
5

Sto provando a capovolgere un NSImage creato con una rappresentazione NSImageBitmapRep. Dopo alcuni scavi (Flipping Quicktime preview & capture e Mirroring CIImage/NSImage) ho provato in due modi tramite una CIImage e applicando una trasformazione di ridimensionamento con -1 per entrambi i fattori.Flip NSImage su entrambi gli assi

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

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

Entrambi i modi produrre un'immagine vuota. Ho anche provato a tradurre l'immagine, nel caso in cui sia fuori dallo schermo a causa del -1 scaling, ma senza successo. Se utilizzo valori positivi per il ridimensionamento, posso vedere che la trasformazione viene applicata correttamente.

self.ivImage è un NSImageView. Voglio un NSImage effettivo che viene capovolto, quindi applicare una trasformazione a NSImageView non è un'opzione.

Questo è 32 bit, Xcode 4.3.2 su Lion.

risposta

7

Dovresti inserire il tuo NSImage con una dimensione.

Mostra il tuo tentativo con la traduzione, perché è la strada giusta. In genere, è più semplice tradurre prima e poi ridimensionare. I frammenti di codice sembrano avere tracce residue di tentativi di traduzione, ma non hanno ragione. Si traduce per 0,0 in un caso e larghezza, 0 in un altro. Inoltre, nel tuo secondo snippet di codice, stai ridimensionando di 1,1 (positivo), quindi non capovolgilo.

Inoltre, potrebbe essere più semplice bloccare semplicemente la messa a fuoco su una nuova immagine della dimensione appropriata, impostare la trasformazione e disegnare il rappresentante dell'immagine. Evita tutte queste cose 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

Grazie, che ha lavorato a destra, fuori dalla scatola! :) Ed è molto più pulito senza la deviazione tramite CIImage! Le mie prove con traduzione e ridimensionamento positivo sono state lasciate per testare se la trasformazione è stata applicata del tutto. – msohn

+0

Soluzione perfetta. Grazie per quello! –

5

In ogni caso, penso che una buona idea dovrebbe essere distacco una funzione completa. Qui è la mia soluzione basata su Ken inviare

- (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

per Flip verticale

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

} 

per Flip orizzontale

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

}