Ist es möglich, die Bildorientierung UIImageView
einzurichten? Wenn ich das UIImageView
Bild auf Ausrichtung mit RECHTS einstelle (es ist ein Foto von der Kamerarolle), wird das Bild nach rechts gedreht, aber ich möchte es in der richtigen Ausrichtung anzeigen, wie es aufgenommen wurde.
Ich weiß, dass ich Bilddaten drehen kann, aber es ist möglich, es eleganter zu machen?
ios
uiimageview
uiimage
orientation
Martin Pilch
quelle
quelle
CGContext
mitCGBitmapContextCreate
(oder mit derUIGraphicsBeginImageContext
Kurzschrift) erstellenCGContextRotateCTM
, eine Drehung festlegen, entwederdrawInRect:
für die EigenschaftUIImage
oderCGContextDrawImage
für die Bildeigenschaft verwendenCGImage
und dann den Kontext entweder mitUIGraphicsGetImageFromCurrentImageContext
(und dannUIGraphicsEndImageContext
) in ein Bild konvertieren , wenn Sie dies tun hat UIKit verwendet, um den Kontext zu erstellen, oderCGBitmapContextCreateImage
wenn Sie sich an die Kerngrafiken gehalten haben . UIKit ist nicht sehr threadsicher, aber der Code wäre ordentlicher.Sie können es vollständig vermeiden, die Transformationen manuell durchzuführen und selbst zu skalieren, wie von an0 in dieser Antwort hier vorgeschlagen :
- (UIImage *)normalizedImage { if (self.imageOrientation == UIImageOrientationUp) return self; UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale); [self drawInRect:(CGRect){0, 0, self.size}]; UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return normalizedImage; }
In der Dokumentation zu den UIImage-Methoden size und drawInRect wird ausdrücklich angegeben, dass sie die Ausrichtung berücksichtigen.
quelle
Ich habe den Code in Anomies Antwort hier (oben von suvish valsan kopiert) in Swift konvertiert :
func fixOrientation() -> UIImage { if self.imageOrientation == UIImageOrientation.Up { return self } var transform = CGAffineTransformIdentity switch self.imageOrientation { case .Down, .DownMirrored: transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height) transform = CGAffineTransformRotate(transform, CGFloat(M_PI)); case .Left, .LeftMirrored: transform = CGAffineTransformTranslate(transform, self.size.width, 0); transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2)); case .Right, .RightMirrored: transform = CGAffineTransformTranslate(transform, 0, self.size.height); transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2)); case .Up, .UpMirrored: break } switch self.imageOrientation { case .UpMirrored, .DownMirrored: transform = CGAffineTransformTranslate(transform, self.size.width, 0) transform = CGAffineTransformScale(transform, -1, 1) case .LeftMirrored, .RightMirrored: transform = CGAffineTransformTranslate(transform, self.size.height, 0) transform = CGAffineTransformScale(transform, -1, 1); default: break; } // Now we draw the underlying CGImage into a new context, applying the transform // calculated above. let ctx = CGBitmapContextCreate( nil, Int(self.size.width), Int(self.size.height), CGImageGetBitsPerComponent(self.CGImage), 0, CGImageGetColorSpace(self.CGImage), UInt32(CGImageGetBitmapInfo(self.CGImage).rawValue) ) CGContextConcatCTM(ctx, transform); switch self.imageOrientation { case .Left, .LeftMirrored, .Right, .RightMirrored: // Grr... CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.height,self.size.width), self.CGImage); default: CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.width,self.size.height), self.CGImage); break; } // And now we just create a new UIImage from the drawing context let cgimg = CGBitmapContextCreateImage(ctx) let img = UIImage(CGImage: cgimg!) return img; }
(Ich habe alle Vorkommen des Parameters
image
durch ersetztself
, da mein Code eine Erweiterung ist.UIImage
)EDIT: Swift 3 Version.
Die Methode gibt eine Option zurück, da viele der Zwischenaufrufe fehlschlagen können und ich sie nicht gerne verwende
!
.func fixOrientation() -> UIImage? { guard let cgImage = self.cgImage else { return nil } if self.imageOrientation == UIImageOrientation.up { return self } let width = self.size.width let height = self.size.height var transform = CGAffineTransform.identity switch self.imageOrientation { case .down, .downMirrored: transform = transform.translatedBy(x: width, y: height) transform = transform.rotated(by: CGFloat.pi) case .left, .leftMirrored: transform = transform.translatedBy(x: width, y: 0) transform = transform.rotated(by: 0.5*CGFloat.pi) case .right, .rightMirrored: transform = transform.translatedBy(x: 0, y: height) transform = transform.rotated(by: -0.5*CGFloat.pi) case .up, .upMirrored: break } switch self.imageOrientation { case .upMirrored, .downMirrored: transform = transform.translatedBy(x: width, y: 0) transform = transform.scaledBy(x: -1, y: 1) case .leftMirrored, .rightMirrored: transform = transform.translatedBy(x: height, y: 0) transform = transform.scaledBy(x: -1, y: 1) default: break; } // Now we draw the underlying CGImage into a new context, applying the transform // calculated above. guard let colorSpace = cgImage.colorSpace else { return nil } guard let context = CGContext( data: nil, width: Int(width), height: Int(height), bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, space: colorSpace, bitmapInfo: UInt32(cgImage.bitmapInfo.rawValue) ) else { return nil } context.concatenate(transform); switch self.imageOrientation { case .left, .leftMirrored, .right, .rightMirrored: // Grr... context.draw(cgImage, in: CGRect(x: 0, y: 0, width: height, height: width)) default: context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height)) } // And now we just create a new UIImage from the drawing context guard let newCGImg = context.makeImage() else { return nil } let img = UIImage(cgImage: newCGImg) return img; }
(Note: Swift 3 version odes compile under Xcode 8.1, but haven't tested it actually works. There might be a typo somewhere, mixed up width/height, etc. Feel free to point/fix any errors).
quelle
func viewDidLoad
. This image is from samsung phone photos.google.com/share/… and has 270 CW orientation exif data. Here how i use itlet background: UIImage? = UIImage(named: "background_image")?.fixOrientation() backgroundImage.image = background
This method first checks the current orientation of UIImage and then it changes the orientation in a clockwise way and return UIImage.You can show this image as
func rotateImage(image:UIImage)->UIImage { var rotatedImage = UIImage(); switch image.imageOrientation { case UIImageOrientation.Right: rotatedImage = UIImage(CGImage:image.CGImage!, scale: 1, orientation:UIImageOrientation.Down); case UIImageOrientation.Down: rotatedImage = UIImage(CGImage:image.CGImage!, scale: 1, orientation:UIImageOrientation.Left); case UIImageOrientation.Left: rotatedImage = UIImage(CGImage:image.CGImage!, scale: 1, orientation:UIImageOrientation.Up); default: rotatedImage = UIImage(CGImage:image.CGImage!, scale: 1, orientation:UIImageOrientation.Right); } return rotatedImage; }
Swift 4 version
func rotateImage(image:UIImage) -> UIImage { var rotatedImage = UIImage() switch image.imageOrientation { case .right: rotatedImage = UIImage(cgImage: image.cgImage!, scale: 1.0, orientation: .down) case .down: rotatedImage = UIImage(cgImage: image.cgImage!, scale: 1.0, orientation: .left) case .left: rotatedImage = UIImage(cgImage: image.cgImage!, scale: 1.0, orientation: .up) default: rotatedImage = UIImage(cgImage: image.cgImage!, scale: 1.0, orientation: .right) } return rotatedImage }
quelle
Swift 3.1
func fixImageOrientation(_ image: UIImage)->UIImage { UIGraphicsBeginImageContext(image.size) image.draw(at: .zero) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage ?? image }
quelle
UIImage extension in Swift. You don't need to do all that flipping at all, really. Objective-C original is here, but I've added the bit that respects the alpha of the original image (crudely, but it works to differentiate opaque images from transparent images).
// from https://github.com/mbcharbonneau/UIImage-Categories/blob/master/UIImage%2BAlpha.m // Returns true if the image has an alpha layer private func hasAlpha() -> Bool { guard let cg = self.cgImage else { return false } let alpha = cg.alphaInfo let retVal = (alpha == .first || alpha == .last || alpha == .premultipliedFirst || alpha == .premultipliedLast) return retVal } func normalizedImage() -> UIImage? { if self.imageOrientation == .up { return self } UIGraphicsBeginImageContextWithOptions(self.size, !self.hasAlpha(), self.scale) var rect = CGRect.zero rect.size = self.size self.draw(in: rect) let retVal = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return retVal }
quelle
here is a workable sample cod, considering the image orientation:
#define rad(angle) ((angle) / 180.0 * M_PI) - (CGAffineTransform)orientationTransformedRectOfImage:(UIImage *)img { CGAffineTransform rectTransform; switch (img.imageOrientation) { case UIImageOrientationLeft: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -img.size.height); break; case UIImageOrientationRight: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -img.size.width, 0); break; case UIImageOrientationDown: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -img.size.width, -img.size.height); break; default: rectTransform = CGAffineTransformIdentity; }; return CGAffineTransformScale(rectTransform, img.scale, img.scale); } - (UIImage *)croppedImage:(UIImage*)orignialImage InRect:(CGRect)visibleRect{ //transform visible rect to image orientation CGAffineTransform rectTransform = [self orientationTransformedRectOfImage:orignialImage]; visibleRect = CGRectApplyAffineTransform(visibleRect, rectTransform); //crop image CGImageRef imageRef = CGImageCreateWithImageInRect([orignialImage CGImage], visibleRect); UIImage *result = [UIImage imageWithCGImage:imageRef scale:orignialImage.scale orientation:orignialImage.imageOrientation]; CGImageRelease(imageRef); return result; }
quelle
I converted the code from @Nicolas Miari answer to Swift 3 in case anybody needs it
func fixOrientation() -> UIImage { if self.imageOrientation == UIImageOrientation.up { return self } var transform = CGAffineTransform.identity switch self.imageOrientation { case .down, .downMirrored: transform = transform.translatedBy(x: self.size.width, y: self.size.height) transform = transform.rotated(by: CGFloat(M_PI)); case .left, .leftMirrored: transform = transform.translatedBy(x: self.size.width, y: 0); transform = transform.rotated(by: CGFloat(M_PI_2)); case .right, .rightMirrored: transform = transform.translatedBy(x: 0, y: self.size.height); transform = transform.rotated(by: CGFloat(-M_PI_2)); case .up, .upMirrored: break } switch self.imageOrientation { case .upMirrored, .downMirrored: transform = transform.translatedBy(x: self.size.width, y: 0) transform = transform.scaledBy(x: -1, y: 1) case .leftMirrored, .rightMirrored: transform = transform.translatedBy(x: self.size.height, y: 0) transform = transform.scaledBy(x: -1, y: 1); default: break; } // Now we draw the underlying CGImage into a new context, applying the transform // calculated above. let ctx = CGContext( data: nil, width: Int(self.size.width), height: Int(self.size.height), bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0, space: self.cgImage!.colorSpace!, bitmapInfo: UInt32(self.cgImage!.bitmapInfo.rawValue) ) ctx!.concatenate(transform); switch self.imageOrientation { case .left, .leftMirrored, .right, .rightMirrored: // Grr... ctx?.draw(self.cgImage!, in: CGRect(x:0 ,y: 0 ,width: self.size.height ,height:self.size.width)) default: ctx?.draw(self.cgImage!, in: CGRect(x:0 ,y: 0 ,width: self.size.width ,height:self.size.height)) break; } // And now we just create a new UIImage from the drawing context let cgimg = ctx!.makeImage() let img = UIImage(cgImage: cgimg!) return img; }
quelle
imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any] let imageCaptured:UIImage = info[UIImagePickerControllerOriginalImage] as! UIImage
image is always rightOrientation and this method is returning back image :(Thanks to Waseem05 for his Swift 3 translation but his method only worked for me when I wrapped it inside an extension to UIImage and placed it outside/below the parent class like so:
extension UIImage { func fixOrientation() -> UIImage { if self.imageOrientation == UIImageOrientation.up { return self } var transform = CGAffineTransform.identity switch self.imageOrientation { case .down, .downMirrored: transform = transform.translatedBy(x: self.size.width, y: self.size.height) transform = transform.rotated(by: CGFloat(M_PI)); case .left, .leftMirrored: transform = transform.translatedBy(x: self.size.width, y: 0); transform = transform.rotated(by: CGFloat(M_PI_2)); case .right, .rightMirrored: transform = transform.translatedBy(x: 0, y: self.size.height); transform = transform.rotated(by: CGFloat(-M_PI_2)); case .up, .upMirrored: break } switch self.imageOrientation { case .upMirrored, .downMirrored: transform = transform.translatedBy(x: self.size.width, y: 0) transform = transform.scaledBy(x: -1, y: 1) case .leftMirrored, .rightMirrored: transform = transform.translatedBy(x: self.size.height, y: 0) transform = transform.scaledBy(x: -1, y: 1); default: break; } // Now we draw the underlying CGImage into a new context, applying the transform // calculated above. let ctx = CGContext( data: nil, width: Int(self.size.width), height: Int(self.size.height), bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0, space: self.cgImage!.colorSpace!, bitmapInfo: UInt32(self.cgImage!.bitmapInfo.rawValue) ) ctx!.concatenate(transform); switch self.imageOrientation { case .left, .leftMirrored, .right, .rightMirrored: // Grr... ctx?.draw(self.cgImage!, in: CGRect(x:0 ,y: 0 ,width: self.size.height ,height:self.size.width)) default: ctx?.draw(self.cgImage!, in: CGRect(x:0 ,y: 0 ,width: self.size.width ,height:self.size.height)) break; } // And now we just create a new UIImage from the drawing context let cgimg = ctx!.makeImage() let img = UIImage(cgImage: cgimg!) return img; } }
Then called it with:
let correctedImage:UIImage = wonkyImage.fixOrientation()
And all was then well! Apple should make it easier to discard orientation when we don't need front/back camera and up/down/left/right device orientation metadata.
quelle
If you need to rotate and fix the image orientation below extension would be useful.
extension UIImage { public func imageRotatedByDegrees(degrees: CGFloat) -> UIImage { //Calculate the size of the rotated view's containing box for our drawing space let rotatedViewBox: UIView = UIView(frame: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)) let t: CGAffineTransform = CGAffineTransform(rotationAngle: degrees * CGFloat.pi / 180) rotatedViewBox.transform = t let rotatedSize: CGSize = rotatedViewBox.frame.size //Create the bitmap context UIGraphicsBeginImageContext(rotatedSize) let bitmap: CGContext = UIGraphicsGetCurrentContext()! //Move the origin to the middle of the image so we will rotate and scale around the center. bitmap.translateBy(x: rotatedSize.width / 2, y: rotatedSize.height / 2) //Rotate the image context bitmap.rotate(by: (degrees * CGFloat.pi / 180)) //Now, draw the rotated/scaled image into the context bitmap.scaleBy(x: 1.0, y: -1.0) bitmap.draw(self.cgImage!, in: CGRect(x: -self.size.width / 2, y: -self.size.height / 2, width: self.size.width, height: self.size.height)) let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() return newImage } public func fixedOrientation() -> UIImage { if imageOrientation == UIImageOrientation.up { return self } var transform: CGAffineTransform = CGAffineTransform.identity switch imageOrientation { case UIImageOrientation.down, UIImageOrientation.downMirrored: transform = transform.translatedBy(x: size.width, y: size.height) transform = transform.rotated(by: CGFloat.pi) break case UIImageOrientation.left, UIImageOrientation.leftMirrored: transform = transform.translatedBy(x: size.width, y: 0) transform = transform.rotated(by: CGFloat.pi/2) break case UIImageOrientation.right, UIImageOrientation.rightMirrored: transform = transform.translatedBy(x: 0, y: size.height) transform = transform.rotated(by: -CGFloat.pi/2) break case UIImageOrientation.up, UIImageOrientation.upMirrored: break } switch imageOrientation { case UIImageOrientation.upMirrored, UIImageOrientation.downMirrored: transform.translatedBy(x: size.width, y: 0) transform.scaledBy(x: -1, y: 1) break case UIImageOrientation.leftMirrored, UIImageOrientation.rightMirrored: transform.translatedBy(x: size.height, y: 0) transform.scaledBy(x: -1, y: 1) case UIImageOrientation.up, UIImageOrientation.down, UIImageOrientation.left, UIImageOrientation.right: break } let ctx: CGContext = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0, space: self.cgImage!.colorSpace!, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)! ctx.concatenate(transform) switch imageOrientation { case UIImageOrientation.left, UIImageOrientation.leftMirrored, UIImageOrientation.right, UIImageOrientation.rightMirrored: ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.height, height: size.width)) default: ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) break } let cgImage: CGImage = ctx.makeImage()! return UIImage(cgImage: cgImage) } }
quelle
extension UIImage { func fixImageOrientation() -> UIImage { UIGraphicsBeginImageContext(self.size) self.draw(at: .zero) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage ?? self } }
Call it:
imageView.image?.fixImageOrientation()
orUIImage(named: "someImage").fixImageOrientation()
Good luck all!
quelle
Swift 3.0 version of Tommy's answer
let imageToDisplay = UIImage.init(cgImage: originalImage.cgImage!, scale: originalImage.scale, orientation: UIImageOrientation.up)
quelle
Inspired from @Aqua Answer.....
in Objective C
- (UIImage *)fixImageOrientation:(UIImage *)img { UIGraphicsBeginImageContext(img.size); [img drawAtPoint:CGPointZero]; UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); if (newImg) { return newImg; } return img; }
quelle