Flip NSImage on both axes

∥☆過路亽.° 提交于 2019-12-01 04:24:35

You should init your NSImage with a size.

Show your attempt with translation, because that's the right way. Typically, it's easiest to translate first and then scale. Your code snippets seem to have vestigial traces of attempts to translate, but they're not right. You translate by 0,0 in one case and width,0 in another. Also, in your second code snippet, you're scaling by 1,1 (positive), so not flipping.

Also, it may be simpler to simply lock focus on a new image of the appropriate size, set up the transform, and draw the image rep. Avoids all of that stuff with 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];

Anyway, I think a good idea should be posting a complete function. Here is my solution based on Ken post

- (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;
}
sanket nagar

for vertical flip

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

}

for horizontal flip

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

}

Extension for Swift, based on the solution of Alejandro Lugeno:

extension NSImage {
    func flipped(flipHorizontally: Bool = false, flipVertically: Bool = false) -> NSImage {
        let flippedImage = NSImage(size: size)

        flippedImage.lockFocus()

        NSGraphicsContext.current?.imageInterpolation = .high

        let transform = NSAffineTransform()
        transform.translateX(by: flipHorizontally ? size.width : 0, yBy: flipVertically ? size.height : 0)
        transform.scaleX(by: flipHorizontally ? -1 : 1, yBy: flipVertically ? -1 : 1)
        transform.concat()

        draw(at: .zero, from: NSRect(origin: .zero, size: size), operation: .sourceOver, fraction: 1)

        flippedImage.unlockFocus()

        return flippedImage
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!