我想从UIImagePickerController加载图片,然后将所选照片保存到我应用的文档目录中。
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
NSData *data1 = UIImagePNGRepresentation(image);
NSString *fileName = "1.png";
NSString *path = //get Document path, then add fileName
BOOL succ = [data1 writeToFile:path atomically:YES];
但是在我将图像保存到我的文档后,我发现,图像旋转了90度,然后我将方法UIImagePNGRepresentation更改为UIImageJPEGRepresentation,这次没关系,有谁知道这是什么问题?
答案 0 :(得分:86)
我遇到了同样的问题并且弄清楚了原因:从iOS 4.0开始,当相机拍照时它不会在保存之前旋转它,它只是在JPEG的EXIF数据中设置一个旋转标记。
如果将UIImage保存为JPEG,则会设置旋转标记。
PNG不支持旋转标志,因此如果将UIImage保存为PNG,它将被错误地旋转,并且没有设置标志来修复它。因此,如果你想要PNG,你必须自己旋转它们。
我会把这称为PNG保存功能中的一个错误,但这只是一个意见(他们至少应该警告你)。
答案 1 :(得分:18)
试试这个:
func rotateImage(image: UIImage) -> UIImage {
if (image.imageOrientation == UIImageOrientation.Up ) {
return image
}
UIGraphicsBeginImageContext(image.size)
image.drawInRect(CGRect(origin: CGPoint.zero, size: image.size))
let copy = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return copy
}
答案 2 :(得分:3)
以下swift功能可以解决问题。
var rotatedCopy: UIImage {
if (imageOrientation == UIImageOrientation.Up) {
return self
}
UIGraphicsBeginImageContext(size)
drawInRect(CGRect(origin: CGPoint.zeroPoint, size: size))
let copy = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return copy
}
是的,就是这么简单,因为drawInRect
功能会考虑图像方向。
答案 3 :(得分:2)
我创建了这个UIImage扩展,用UIImagePNGRepresentation来解决这个问题,基于this response。所以我建议使用这个类func UIImage.PNGRepresentation(img: UIImage)
而不是UIKit func UIImagePNGRepresentation。
Swift 3代码:
// MyUIImage.swift
// MyEasyMovie-Public-App
//
// Created by Ahmed Zahraz on 19/12/2016.
// Copyright © 2016 AhmedZahraz. All rights reserved.
import Foundation
import UIKit
extension UIImage {
public class func PNGRepresentation(_ img: UIImage) -> Data? {
// No-op if the orientation is already correct
if (img.imageOrientation == UIImageOrientation.up) {
return UIImagePNGRepresentation(img);
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform:CGAffineTransform = CGAffineTransform.identity
if (img.imageOrientation == UIImageOrientation.down
|| img.imageOrientation == UIImageOrientation.downMirrored) {
transform = transform.translatedBy(x: img.size.width, y: img.size.height)
transform = transform.rotated(by: CGFloat(M_PI))
}
if (img.imageOrientation == UIImageOrientation.left
|| img.imageOrientation == UIImageOrientation.leftMirrored) {
transform = transform.translatedBy(x: img.size.width, y: 0)
transform = transform.rotated(by: CGFloat(M_PI_2))
}
if (img.imageOrientation == UIImageOrientation.right
|| img.imageOrientation == UIImageOrientation.rightMirrored) {
transform = transform.translatedBy(x: 0, y: img.size.height);
transform = transform.rotated(by: CGFloat(-M_PI_2));
}
if (img.imageOrientation == UIImageOrientation.upMirrored
|| img.imageOrientation == UIImageOrientation.downMirrored) {
transform = transform.translatedBy(x: img.size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
}
if (img.imageOrientation == UIImageOrientation.leftMirrored
|| img.imageOrientation == UIImageOrientation.rightMirrored) {
transform = transform.translatedBy(x: img.size.height, y: 0);
transform = transform.scaledBy(x: -1, y: 1);
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
let ctx:CGContext = CGContext(data: nil, width: Int(img.size.width), height: Int(img.size.height),
bitsPerComponent: img.cgImage!.bitsPerComponent, bytesPerRow: 0,
space: img.cgImage!.colorSpace!,
bitmapInfo: img.cgImage!.bitmapInfo.rawValue)!
ctx.concatenate(transform)
if (img.imageOrientation == UIImageOrientation.left
|| img.imageOrientation == UIImageOrientation.leftMirrored
|| img.imageOrientation == UIImageOrientation.right
|| img.imageOrientation == UIImageOrientation.rightMirrored
) {
ctx.draw(img.cgImage!, in: CGRect(x:0,y:0,width:img.size.height,height:img.size.width))
} else {
ctx.draw(img.cgImage!, in: CGRect(x:0,y:0,width:img.size.width,height:img.size.height))
}
// And now we just create a new UIImage from the drawing context
let cgimg:CGImage = ctx.makeImage()!
let imgEnd:UIImage = UIImage(cgImage: cgimg)
return UIImagePNGRepresentation(imgEnd)
}
}
答案 4 :(得分:0)
Stefan的答案已针对Swift 4:
func rotateImage(image: UIImage) -> UIImage {
if (image.imageOrientation == UIImage.Orientation.up) {
return image
}
UIGraphicsBeginImageContext(image.size)
image.draw(in: CGRect(origin: .zero, size: image.size))
let copy = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return copy!
}
然后:
var originalImage = yourImage.image!
image = rotateImage(image: originalImage)