iOS:保存为PNG表示数据后,图像旋转90度

app*_*eak 38 iphone image-rotation uiimage landscape-portrait ios5.1

我已经研究了足够的工作,但无法修复它.只要我将图像存储为UIImage,从相机拍照后,它就可以了,但只要我将此图像存储为PNG表示,它就会旋转90度.

以下是我的代码和我尝试过的所有事情:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{
    NSString *mediaType = [info valueForKey:UIImagePickerControllerMediaType];

    if([mediaType isEqualToString:(NSString*)kUTTypeImage]) 
    {
        AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
        delegate.originalPhoto  = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
        NSLog(@"Saving photo");
        [self saveImage];
        NSLog(@"Fixing orientation");
        delegate.fixOrientationPhoto  = [self fixOrientation:[UIImage imageWithContentsOfFile:[delegate filePath:imageName]]];      
        NSLog(@"Scaling photo");
        delegate.scaledAndRotatedPhoto  =  [self scaleAndRotateImage:[UIImage imageWithContentsOfFile:[delegate filePath:imageName]]];
    }
    [picker dismissModalViewControllerAnimated:YES];
    [picker release];
}


- (void)saveImage
{
    AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSData *imageData = UIImagePNGRepresentation(delegate.originalPhoto);
    [imageData writeToFile:[delegate filePath:imageName] atomically:YES];
}
Run Code Online (Sandbox Code Playgroud)

这里分别从这里这里取得fixOrientation和scaleAndRotateImage函数.当我在UIImage上应用它们时,它们工作正常并旋转图像,但如果我将图像保存为PNG表示并应用它们则不起作用.

请执行以上功能后请参考以下图片:

第一张照片是原始的,第二张是保存的,第三张和第四张是在保存的图像上应用fixorientation和scaleandrotate功能后

Mud*_*pai 69

从iOS 4.0开始,当相机拍照时,它不会在保存之前旋转它

只需在JPEG的EXIF数据中设置旋转标志.如果将UIImage保存为JPEG,则为

将设置旋转标志.PNG不支持旋转标志,因此如果将UIImage保存为

PNG,它将被错误地旋转,并没有设置标志来修复它.所以,如果你想要PNG

您必须自己旋转图像,以便检查此链接.


And*_*eas 28

Rao发布的UIImage扩展的Swift 3.1版本:

extension UIImage {
    func fixOrientation() -> UIImage {
        if self.imageOrientation == UIImageOrientation.up {
            return self
        }
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        self.draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
        if let normalizedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext() {
            UIGraphicsEndImageContext()
            return normalizedImage
        } else {
            return self
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

let cameraImage = //image captured from camera
let orientationFixedImage = cameraImage.fixOrientation()
Run Code Online (Sandbox Code Playgroud)


Rao*_*Rao 19

对于Swift 2.1

添加以下作为UIImage扩展,

extension UIImage {
    func fixOrientation() -> UIImage? {
        if self.imageOrientation == UIImage.Orientation.up {
            return self
        }

        UIGraphicsBeginImageContext(self.size)
        self.draw(in: CGRect(origin: .zero, size: self.size))
        let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return normalizedImage
    }
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

let cameraImage = //image captured from camera
let orientationFixedImage = cameraImage.fixOrientation()
Run Code Online (Sandbox Code Playgroud)

  • 可能是迄今为止最好的答案,它没有一起使用黑客功能。非常漂亮。 (2认同)
  • 添加了解释。@bluewraith 和 xleon。 (2认同)

Fat*_*tie 6

我发现以下提示非常有用:

1.自然产出是景观

2. .width/.height受.imageOrientation影响

3使用短尺寸而不是.width


(1)摄像机的"自然"输出为剧照IS LANDSCAPE.

这是违反直觉的.肖像是UIImagePickerController等提供的唯一方法.但是当使用"普通"肖像相机时,你将获得UIImageOrientationRight作为"正常"方向

(我记得这一点 - 视频的自然输出是(当然)风景;所以剧照是一样的 - 即使iPhone完全是肖像.)


(2).width和.height 确实受.imageOrientation影响!!!!!!!!!

一定要这样做,并在iPhone上尝试两种方式,

NSLog(@"fromImage.imageOrientation is %d", fromImage.imageOrientation);
NSLog(@"fromImage.size.width  %f   fromImage.size.height  %f",
            fromImage.size.width, fromImage.size.height);
Run Code Online (Sandbox Code Playgroud)

你会看到.height和.width交换,"尽管"真正的像素是景观.


(3)简单地使用"短维"而不是.width,往往可以解决很多问题

我发现这非常有帮助.假设您想要图像的顶部正方形:

CGRect topRectOfOriginal = CGRectMake(0,0, im.size.width,im.size.width);
Run Code Online (Sandbox Code Playgroud)

这实际上是行不通的,当相机被("真的")保持风景时,你会得到一张压扁的图像.

但是,如果你只是这样做

float shortDimension = fminf(im.size.width, im.size.height);
CGRect topRectOfOriginal = CGRectMake(0,0, shortDimension,shortDimension);
Run Code Online (Sandbox Code Playgroud)

然后"一切都是固定的",你实际上"不需要担心"方向标志.点(3)并不是万灵药,但它经常解决所有问题.

希望它可以帮助别人节省一些时间.