UIImagePNGRepresentation问题? /图像旋转90度

时间:2010-08-24 07:20:46

标签: iphone cocoa-touch uiimagepngrepresentation

我想从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,这次没关系,有谁知道这是什么问题?

5 个答案:

答案 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)