如何水平翻转 UIImage?

如何水平翻转 UIImage,我在 UIImage类引用中找到了 UIImageOrientationUpMirrored枚举值,如何利用这个属性翻转 UIImage

77442 次浏览

目标 C

UIImage* sourceImage = [UIImage imageNamed:@"whatever.png"];


UIImage* flippedImage = [UIImage imageWithCGImage:sourceImage.CGImage
scale:sourceImage.scale
orientation:UIImageOrientationUpMirrored];

Swift

let flippedImage = myImage.withHorizontallyFlippedOrientation()

形象定位定义:

typedef NS_ENUM(NSInteger, UIImageOrientation) {
UIImageOrientationUp,            // default orientation
UIImageOrientationDown,          // 180 deg rotation
UIImageOrientationLeft,          // 90 deg CCW
UIImageOrientationRight,         // 90 deg CW
UIImageOrientationUpMirrored,    // as above but image mirrored along other axis. horizontal flip
UIImageOrientationDownMirrored,  // horizontal flip
UIImageOrientationLeftMirrored,  // vertical flip
UIImageOrientationRightMirrored, // vertical flip
};

我对更多的情况做了一些改进,比如从 AVCaptureSession 处理 UIImage。

UIImage* sourceImage = [UIImage imageNamed:@"whatever.png"];
UIImageOrientation flipingOrientation;
if(sourceImage.imageOrientation>=4){
flippedOrientation = sourceImage.imageOrientation - 4;
}else{
flippedOrientation = sourceImage.imageOrientation + 4;
}
UIImage* flippedImage = [UIImage imageWithCGImage:sourceImage.CGImage
scale: sourceImage.scale orientation: flipingOrientation];

这可能对某些人有用:

    UIImageOrientation imageOrientation;


switch (sourceImage.imageOrientation) {
case UIImageOrientationDown:
imageOrientation = UIImageOrientationDownMirrored;
break;


case UIImageOrientationDownMirrored:
imageOrientation = UIImageOrientationDown;
break;


case UIImageOrientationLeft:
imageOrientation = UIImageOrientationLeftMirrored;
break;


case UIImageOrientationLeftMirrored:
imageOrientation = UIImageOrientationLeft;


break;


case UIImageOrientationRight:
imageOrientation = UIImageOrientationRightMirrored;


break;


case UIImageOrientationRightMirrored:
imageOrientation = UIImageOrientationRight;


break;


case UIImageOrientationUp:
imageOrientation = UIImageOrientationUpMirrored;
break;


case UIImageOrientationUpMirrored:
imageOrientation = UIImageOrientationUp;
break;
default:
break;
}


resultImage = [UIImage imageWithCGImage:sourceImage.CGImage scale:sourceImage.scale orientation:imageOrientation];

Vertical flip is often required to initialise OpenGL texture using glTexImage2d(...). The above proposed tricks do not actually modify image data and will not work in this case. Here is a code to do the actual data flip inspired by https://stackoverflow.com/a/17909372

- (UIImage *)flipImage:(UIImage *)image
{
UIGraphicsBeginImageContext(image.size);
CGContextDrawImage(UIGraphicsGetCurrentContext(),CGRectMake(0.,0., image.size.width, image.size.height),image.CGImage);
UIImage *i = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return i;
}

这里有一个快速的版本: (我在评论中看到了这个问题)

let srcImage = UIImage(named: "imageName")
let flippedImage = UIImage(CGImage: srcImage.CGImage, scale: srcImage.scale, orientation: UIImageOrientation.UpMirrored)

实现这一点的一个非常简单的方法是创建 UIImageView 而不是 UIImage,并在 UIImageView 上进行转换。

yourImageView.image =[UIImage imageNamed:@"whatever.png"];
yourImageView.transform = CGAffineTransform(scaleX: -1, y: 1); //Flipped

希望这个能帮上忙。

我已经尝试使用 image FlippedForRightToLeftLayoutDirection,并创建了一个具有不同方向的新 UIImage,但至少这是我找到的唯一一个翻转图像的解决方案

let ciimage: CIImage = CIImage(CGImage: imagenInicial.CGImage!)
let rotada3 = ciimage.imageByApplyingTransform(CGAffineTransformMakeScale(-1, 1))

就像你在我的操场上看到的那样,它起作用了! ! :) enter image description here

当然,让 finalImage = UIImage (CIImage: rotada3)

这是一个兼容 iOS8/9操作系统的版本:

UIImage *image = [UIImage imageNamed:name];


if ([[UIApplication sharedApplication] userInterfaceLayoutDirection] == UIUserInterfaceLayoutDirectionRightToLeft) {


if ([image respondsToSelector:@selector(imageFlippedForRightToLeftLayoutDirection)]) {
//iOS9
image = image.imageFlippedForRightToLeftLayoutDirection;
}
else {
//iOS8
CIImage *coreImage = [CIImage imageWithCGImage:image.CGImage];
coreImage = [coreImage imageByApplyingTransform:CGAffineTransformMakeScale(-1, 1)];
image = [UIImage imageWithCIImage:coreImage scale:image.scale orientation:UIImageOrientationUp];
}
}


return image;

对于斯威夫特3/4:

imageView.transform = CGAffineTransform(scaleX: -1, y: 1)

这是水平镜像/翻转 UIImage 的可靠实现,可以来回应用于图像。因为它改变了底层的图像数据,所以绘图(如屏幕快照)也会改变。经过测试,没有质量损失。

func flipImage() -> UIImage? {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
let bitmap = UIGraphicsGetCurrentContext()!


bitmap.translateBy(x: size.width / 2, y: size.height / 2)
bitmap.scaleBy(x: -1.0, y: -1.0)


bitmap.translateBy(x: -size.width / 2, y: -size.height / 2)
bitmap.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))


let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()


return image?
}

这里的一个答案上述修改和在 Swift 3,我发现特别有用的时候,你有一个按钮,需要不断翻转图像来回。

func flipImage(sourceImage: UIImage,orientation: UIImageOrientation) -> UIImage {




var imageOrientation = orientation


switch sourceImage.imageOrientation {


case UIImageOrientation.down:
imageOrientation = UIImageOrientation.downMirrored;
break;


case UIImageOrientation.downMirrored:
imageOrientation = UIImageOrientation.down;
break;


case UIImageOrientation.left:
imageOrientation = UIImageOrientation.leftMirrored;
break;


case UIImageOrientation.leftMirrored:
imageOrientation = UIImageOrientation.left;


break;


case UIImageOrientation.right:
imageOrientation = UIImageOrientation.rightMirrored;


break;


case UIImageOrientation.rightMirrored:
imageOrientation = UIImageOrientation.right;


break;


case UIImageOrientation.up:
imageOrientation = UIImageOrientation.upMirrored;
break;


case UIImageOrientation.upMirrored:
imageOrientation = UIImageOrientation.up;
break;




}




return UIImage(cgImage: sourceImage.cgImage!, scale: sourceImage.scale, orientation: imageOrientation)


}

用途:

imageToFlip: UIImage = flipImage(sourceImage: imageToFlip, orientation: imageToFlip.imageOrientation)

一个简单的扩展。

extension UIImage {


var flipped: UIImage {
guard let cgImage = cgImage else {
return self
}


return UIImage(cgImage: cgImage, scale: scale, orientation: .upMirrored)
}
}

用法:

let image = #imageLiteral(resourceName: "imageName")
let imageView = UIImageView(image: image.flipped)

阿罗斯在 SWIFT 3:中的回答

let sourceImage = UIImage(named: "whatever.png")!
let flippedImage = UIImage(cgImage: sourceImage.cgImage!, scale: sourceImage.scale, orientation: .upMirrored)

IOS10 +

[myImage imageWithHorizontallyFlippedOrientation];

迅捷4:

let flippedImage = myImage.withHorizontallyFlippedOrientation()

Swift 4

yourImage.transform = CGAffineTransform(scaleX: -1, y: 1)

在 Swift 3及以上版本中测试

Here is the simple solution to achieve this problem with extensions. 我测试过,成功了,你可以从任何方向反射。

extension UIImage {


func imageUpMirror() -> UIImage {
guard let cgImage = cgImage else { return self }
return UIImage(cgImage: cgImage, scale: scale, orientation: .upMirrored)
}


func imageDownMirror() -> UIImage {
guard let cgImage = cgImage else { return self }
return UIImage(cgImage: cgImage, scale: scale, orientation: .downMirrored)
}


func imageLeftMirror() -> UIImage {
guard let cgImage = cgImage else { return self }
return UIImage(cgImage: cgImage, scale: scale, orientation: .leftMirrored)
}


func imageRightMirror() -> UIImage {
guard let cgImage = cgImage else { return self }
return UIImage(cgImage: cgImage, scale: scale, orientation: .rightMirrored)
}
}

此代码的用法

let image = #imageLiteral(resourceName: "imageName")
flipHorizontally = image.imageUpMirror()

因此,您可以使用其他函数。

Due to unwrapping do the following:

let srcImage = UIImage(named: "myimage")!
let flippedImage = UIImage(cgImage: srcImage.cgImage!,
scale: srcImage.scale, orientation: UIImage.Orientation.upMirrored)

you can rotate the image as you want using this

SWIFT 4

extension UIImage {
public func imageRotatedByDegrees(degrees: CGFloat, flip: Bool) -> UIImage {
let radiansToDegrees: (CGFloat) -> CGFloat = {
return $0 * (180.0 / CGFloat(M_PI))
}
let degreesToRadians: (CGFloat) -> CGFloat = {
return $0 / 180.0 * CGFloat(M_PI)
}


// calculate the size of the rotated view's containing box for our drawing space
let rotatedViewBox = UIView(frame: CGRect(origin: CGPoint.zero, size: size))
let t = CGAffineTransform(rotationAngle: degreesToRadians(degrees));
rotatedViewBox.transform = t
let rotatedSize = rotatedViewBox.frame.size


// Create the bitmap context
UIGraphicsBeginImageContext(rotatedSize)
let bitmap = UIGraphicsGetCurrentContext()!


bitmap.translateBy(x: rotatedSize.width / 2.0, y: rotatedSize.height / 2.0)
// Move the origin to the middle of the image so we will rotate and scale around the center.
//CGContextTranslateCTM(bitmap, rotatedSize.width / 2.0, rotatedSize.height / 2.0);


//   // Rotate the image context
bitmap.rotate(by: degreesToRadians(degrees))
// CGContextRotateCTM(bitmap, degreesToRadians(degrees));


// Now, draw the rotated/scaled image into the context
var yFlip: CGFloat


if(flip){
yFlip = CGFloat(-1.0)
} else {
yFlip = CGFloat(1.0)
}
bitmap.scaleBy(x: yFlip, y: -1.0)
//CGContextScaleCTM(bitmap, yFlip, -1.0)
bitmap.draw(self.cgImage!, in: CGRect.init(x: -size.width / 2, y: -size.height / 2, width: size.width, height: size.height))
// CGContextDrawImage(bitmap, CGRectMake(-size.width / 2, -size.height / 2, size.width, size.height), CGImage)


let newImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()


return newImage
}

}

斯威夫特5-Xcode 11.5

水平旋转的最佳解决方案: 观看视频:

Https://m.youtube.com/watch?v=4kslbub-mlu

或者使用以下代码:


import UIKit
class FirstViewControl: UIViewController {
@IBOutlet weak var buttonAnim: UIButton!


@IBAction func ClickOnButtonAnim(_ sender: UIButton) {
UIView.transition(with: buttonAnim, duration: 0.4, options: .transitionFlipFromLeft, animation: nil , completion: nil)
}


}


您可以在此动画中使用任何 ui (按钮、标签、 uiview 或图像)。