Flip UIImage Along Either Axis

后端 未结 5 1509
余生分开走
余生分开走 2021-01-13 17:05

I\'m trying to create a method which flips a UIImage along the X axis, Y axis, or both. I keep getting close but my transform knowledge isn\'t good enough to get all the way

相关标签:
5条回答
  • 2021-01-13 17:45

    Try the following:

    UIImage* myimage = [UIImage imageNamed: @"myimage.png"];
    myimage = [UIImage imageWithCGImage: myimage.CGImage scale: 1.0f orientation: UIImageOrientationUpMirrored];
    
    0 讨论(0)
  • 2021-01-13 17:47

    This is merely a slightly fixed and 'updated to Swift' version of the old answer by @ultramiraculous. Just in case it helps someone.

    Vertical Flip (reflection over x-axis):

    func flipV(im:UIImage)->UIImage {
        var newOrient:UIImageOrientation
        switch im.imageOrientation {
        case .Up:
            newOrient = .DownMirrored
        case .UpMirrored:
            newOrient = .Down
        case .Down:
            newOrient = .UpMirrored
        case .DownMirrored:
            newOrient = .Up
        case .Left:
            newOrient = .LeftMirrored
        case .LeftMirrored:
            newOrient = .Left
        case .Right:
            newOrient = .RightMirrored
        case .RightMirrored:
            newOrient = .Right
        }
        return UIImage(CGImage: im.CGImage, scale: im.scale, orientation: newOrient)
    }
    

    Horizontal Flip (reflection over y-axis)

    func flipH(im:UIImage)->UIImage {
        var newOrient:UIImageOrientation
        switch im.imageOrientation {
        case .Up:
            newOrient = .UpMirrored
        case .UpMirrored:
            newOrient = .Up
        case .Down:
            newOrient = .DownMirrored
        case .DownMirrored:
            newOrient = .Down
        case .Left:
            newOrient = .RightMirrored
        case .LeftMirrored:
            newOrient = .Right
        case .Right:
            newOrient = .LeftMirrored
        case .RightMirrored:
            newOrient = .Left
        }
        return UIImage(CGImage: im.CGImage, scale: im.scale, orientation: newOrient)
    }
    
    0 讨论(0)
  • 2021-01-13 17:48

    If you're intending to just display the image and not save it, you probably don't want to create a second CGContext. It's far more efficient to just use the already-loaded CGImage in the UIImage, and change the orientation like so:

    - (UIImage *)flippedImageByFlippingAlongXAxis:(BOOL)flipOnX andAlongYAxis:(BOOL)flipOnY
    {
        UIImageOrientation currentOrientation = self.imageOrientation;
        UIImageOrientation newOrientation = currentOrientation;
    
        if (flipOnX == YES) {
            switch (newOrientation) {
                case UIImageOrientationUp:
                    newOrientation = UIImageOrientationUpMirrored;
                    break;
                case UIImageOrientationDown:
                    newOrientation = UIImageOrientationMirrored;
                    break;
                case UIImageOrientationUpMirrored:
                    newOrientation = UIImageOrientationUp;
                    break;
                case UIImageOrientationDownMirrored:
                    newOrientation = UIImageOrientationDown;
                    break;
                case UIImageOrientationLeft:
                    newOrientation = UIImageOrientationLeftMirrored;
                    break;
                case UIImageOrientationRight:
                    newOrientation = UIImageOrientationRightMirrored;
                    break;
                case UIImageOrientationLeftMirrored:
                    newOrientation = UIImageOrientationLeft;
                    break;
                case UIImageOrientationRightMirrored:
                    newOrientation = UIImageOrientationRight;
                    break;
            }
        }
    
        if (flipOnY == YES) {
            switch (newOrientation) {
                case UIImageOrientationUp:
                    newOrientation = UIImageOrientationDownMirrored;
                    break;
                case UIImageOrientationDown:
                    newOrientation = UIImageOrientationUpMirrored;
                    break;
                case UIImageOrientationUpMirrored:
                    newOrientation = UIImageOrientationDown;
                    break;
                case UIImageOrientationDownMirrored:
                    newOrientation = UIImageOrientationUp;
                    break;
                case UIImageOrientationLeft:
                    newOrientation = UIImageOrientationRightMirrored;
                    break;
                case UIImageOrientationRight:
                    newOrientation = UIImageOrientationLeftMirrored;
                    break;
                case UIImageOrientationLeftMirrored:
                    newOrientation = UIImageOrientationRight;
                    break;
                case UIImageOrientationRightMirrored:
                    newOrientation = UIImageOrientationLeft;
                    break;
            }
        }
    
        return [UIImage imageWithCGImage:self.CGImage scale:self.scale orientation:newOrientation];
    }
    

    When you start a new CGContext and doing flip using CGContextDrawImage, you're allocating another block of memory to hold the same bytes in a different order. By changing the UIImage orientation, you're able to avoid another allocation. The same image data is used, just drawn in a different orientation.

    0 讨论(0)
  • 2021-01-13 17:53

    I finally was able to figure this out. Here is the code that works for anyone else who might need it.

    - (UIImage *)flippedImageByAxis:(MVImageFlip)axis{
        UIGraphicsBeginImageContext(self.size);
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        if(axis == MVImageFlipXAxis){
            // Do nothing, X is flipped normally in a Core Graphics Context
        } else if(axis == MVImageFlipYAxis){
            // fix X axis
            CGContextTranslateCTM(context, 0, self.size.height);
            CGContextScaleCTM(context, 1.0f, -1.0f);
    
            // then flip Y axis
            CGContextTranslateCTM(context, self.size.width, 0);
            CGContextScaleCTM(context, -1.0f, 1.0f);
        } else if(axis == MVImageFlipXAxisAndYAxis){
            // just flip Y
            CGContextTranslateCTM(context, self.size.width, 0);
            CGContextScaleCTM(context, -1.0f, 1.0f);
        }
    
        CGContextDrawImage(context, CGRectMake(0.0, 0.0, self.size.width, self.size.height), [self CGImage]);
    
        UIImage *flipedImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return flipedImage;
    }
    
    0 讨论(0)
  • 2021-01-13 17:53

    Swift 3 version:

    func flipV(im:UIImage)->UIImage {
            var newOrient:UIImageOrientation
            switch im.imageOrientation {
            case .up:
                newOrient = .downMirrored
            case .upMirrored:
                newOrient = .down
            case .down:
                newOrient = .upMirrored
            case .downMirrored:
                newOrient = .up
            case .left:
                newOrient = .leftMirrored
            case .leftMirrored:
                newOrient = .left
            case .right:
                newOrient = .rightMirrored
            case .rightMirrored:
                newOrient = .right
            }
            return UIImage(cgImage: im.cgImage!, scale: im.scale, orientation: newOrient)
        }
    
        func flipH(im:UIImage)->UIImage {
            var newOrient:UIImageOrientation
            switch im.imageOrientation {
            case .up:
                newOrient = .upMirrored
            case .upMirrored:
                newOrient = .up
            case .down:
                newOrient = .downMirrored
            case .downMirrored:
                newOrient = .down
            case .left:
                newOrient = .rightMirrored
            case .leftMirrored:
                newOrient = .right
            case .right:
                newOrient = .leftMirrored
            case .rightMirrored:
                newOrient = .left
            }
            return UIImage(cgImage: im.cgImage!, scale: im.scale, orientation: newOrient)
        }
    
    0 讨论(0)
提交回复
热议问题