2012-06-07 2 views
5

Я пытаюсь перевернуть NSImage, созданный с представлением NSImageBitmapRep. После некоторого рытья (Flipping Quicktime preview & capture и Mirroring CIImage/NSImage) Я пробовал два пути через CIImage и применял масштабирующее преобразование с -1 для обоих факторов.Flip NSImage на обе оси

Во-первых, используя 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]; 

затем с помощью фильтра 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]; 

Оба способа производят пустое изображение. Я также попытался перевести изображение, если он вышел из экрана из-за масштабирования -1, но безрезультатно. Если я использую положительные значения для масштабирования, я вижу, что преобразование применяется правильно.

self.ivImage - это NSImageView. Я хочу, чтобы фактическое NSImage было перевернуто, поэтому применение преобразования в NSImageView не является вариантом.

Это 32 бит, Xcode 4.3.2 на льве.

ответ

7

Вы должны установить свой NSImage с размером.

Покажите свою попытку перевода, потому что это правильный путь. Как правило, проще всего перенести сначала, а затем масштаб. У ваших фрагментов кода, похоже, есть рудиментарные следы попыток перевода, но они не правы. Вы переводите на 0,0 в одном случае и ширине, 0 в другом. Кроме того, во втором фрагменте кода вы масштабируетесь на 1,1 (положительный), поэтому не переворачиваете.

Также может быть проще просто сфокусироваться на новом изображении соответствующего размера, настроить преобразование и нарисовать изображение. Избегает всего этого с 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

Спасибо, что работало прямо из коробки! :) И это намного чище без обхода через CIImage! Мои испытания с переводом и положительным масштабированием были оставлены для проверки того, было ли преобразование применено вообще. – msohn

+0

Идеальное решение. Спасибо за это! –

5

В любом случае, я думаю, что хорошая идея должна публиковать полную функцию. Вот мое решение, основанное на Ken размещать

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

для вертикального флипа

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

} 

для горизонтальной флип

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

} 
Смежные вопросы