2012-06-07 17 views
5

Próbuję odwrócić NSImage utworzone za pomocą reprezentacji NSImageBitmapRep. Po kilku kopaniu (Flipping Quicktime preview & capture i Mirroring CIImage/NSImage) próbowałem na dwa sposoby przez CIImage i stosując transformację skalowania z -1 dla obu czynników.Odwróć NSImage na obu osiach

Najpierw za pomocą 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]; 

następnie przy użyciu filtra 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]; 

Oba sposoby produkować pusty obraz. Próbowałem również przetłumaczyć obraz, na wypadek, gdyby był poza ekranem z powodu -1 skalowań, ale bez skutku. Jeśli użyję dodatnich wartości do skalowania, widzę, że transformacja jest poprawnie zastosowana.

self.ivImage to NSImageView. Chcę rzeczywistego NSImage, który jest odwrócony, więc zastosowanie transformacji do NSImageView nie jest opcją.

To jest 32-bitowy, Xcode 4.3.2 na Lion.

Odpowiedz

7

Powinieneś zainicjować swój NSImage o rozmiarze.

Pokaż swoją próbę z tłumaczeniem, ponieważ jest to właściwy sposób. Zazwyczaj najłatwiej jest najpierw przetłumaczyć, a następnie skalować. Wydaje się, że fragmenty kodu mają ślady prób translacji, ale nie mają racji. Tłumaczymy przez 0,0 w jednym przypadku i szerokości, 0 w innym. Ponadto w drugim fragmencie kodu skalujesz o 1,1 (pozytywny), więc nie odwracaj.

Łatwiejsze może być po prostu zablokowanie fokusa na nowym obrazie o odpowiednim rozmiarze, ustawienie transformacji i narysowanie obrazu. Unika tych wszystkich rzeczy za pomocą 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

Dzięki, które działały od razu po wyjęciu z pudełka! :) I jest znacznie czystszy bez objazdu przez CIImage! Moje próby z tłumaczeniem i dodatnim skalowaniem zostały pozostawione, aby sprawdzić, czy transformacja została w ogóle zastosowana. – msohn

+0

Idealne rozwiązanie. Dziękuję za to! –

5

W każdym razie myślę, że dobrym pomysłem powinna być publikacja pełnej funkcji. Oto moje rozwiązanie oparte na Ken zakładać

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

do pionowej klapki

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

} 

do poziomego klapce

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

}