我已经研究了足够的工作,但无法修复它。只要我将图像存储为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];
}
这里的fixOrientation和scaleAndRotateImage函数分别来自here和here。当我在UIImage上应用它们时,它们可以正常工作并旋转图像,但如果我将图像保存为PNG表示并应用它们则无效。
执行上述功能后请参考以下图片:
答案 0 :(得分:67)
从相机拍照后的iOS 4.0开始,在保存之前它不会旋转它,
只需在JPEG的EXIF数据中设置旋转标志。如果将UIImage保存为JPEG,则
将设置旋转标志.PNG不支持旋转标志,因此如果将UIImage保存为
PNG,它将被错误旋转,并且没有设置标志来修复它。所以如果你想要PNG
图片必须自行旋转,为此检查link。
答案 1 :(得分:23)
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
}
}
}
用法:
let cameraImage = //image captured from camera
let orientationFixedImage = cameraImage.fixOrientation()
答案 2 :(得分:18)
对于Swift 2.1
将以下内容添加为UIImage扩展名
extension UIImage {
func fixOrientation() -> UIImage {
if self.imageOrientation == UIImageOrientation.Up {
return self
}
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
self.drawInRect(CGRectMake(0, 0, self.size.width, self.size.height))
let normalizedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return normalizedImage;
}
}
使用示例:
let cameraImage = //image captured from camera
let orientationFixedImage = cameraImage.fixOrientation()
答案 3 :(得分:6)
我发现以下提示非常有用:
(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);
你会看到.height和.width交换,“即使”真正的像素是风景。
(3)简单地使用“短维度”而不是.width,通常可以解决很多问题
我发现这非常有帮助。假设您想要图像的顶部正方形:
CGRect topRectOfOriginal = CGRectMake(0,0, im.size.width,im.size.width);
实际上无法正常工作,当相机被(“真的”)保持风景时,你会得到一张压扁的图像。
然而,如果你只是这样做
float shortDimension = fminf(im.size.width, im.size.height);
CGRect topRectOfOriginal = CGRectMake(0,0, shortDimension,shortDimension);
然后“一切都已修复”,你实际上“不需要担心”方向标志。再说一点(3)并不是万灵药,但它经常解决所有问题。
希望能帮助别人节省一些时间。
答案 4 :(得分:3)
试试这个, 你可以使用
NSData *somenewImageData = UIImageJPEGRepresentation(newimg,1.0);
而不是
NSData *somenewImageData = UIImagePNGRepresentation(newimg);
答案 5 :(得分:2)
我找到了这段代码here,它实际上是为我修复的。对于我的应用程序,我拍了一张照片并保存了,每次加载它时,它都会附加恼人的旋转(我抬起头来,这显然与EXIF以及iPhone拍摄和存储图像的方式有关)。这段代码为我修好了。我不得不说,它最初是作为类/扩展/类别的补充(你可以从链接中找到原文。我使用它像下面的一个简单的方法,因为我真的不想做一个整体这个类或类别。我只使用肖像,但我认为代码适用于任何方向。我不确定
Rant over,这是代码:
Collection<Person> selectedPeople = filterWhenMultipleOccurance(people, p -> p.getAge(), 3);
System.out.println("---------------");
selectedPeople.forEach(p -> System.out.println(p.getName()));
我不确定这对你有多大帮助,但我希望它有所帮助:)
答案 6 :(得分:1)
请尝试以下代码
UIImage *sourceImage = ... // Our image
CGRect selectionRect = CGRectMake(100.0, 100.0, 300.0, 400.0);
CGImageRef resultImageRef = CGImageCreateWithImageInRect(sourceImage.CGImage,
selectionRect);
UIImage *resultImage = [[UIImage alloc] initWithCGImage:resultImageRef];
并且
CGRect TransformCGRectForUIImageOrientation(CGRect source, UIImageOrientation orientation, CGSize imageSize) {
switch (orientation) {
case UIImageOrientationLeft: { // EXIF #8
CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate,M_PI_2);
return CGRectApplyAffineTransform(source, txCompound);
}
case UIImageOrientationDown: { // EXIF #3
CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate,M_PI);
return CGRectApplyAffineTransform(source, txCompound);
}
case UIImageOrientationRight: { // EXIF #6
CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(0.0, imageSize.width);
CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate,M_PI + M_PI_2);
return CGRectApplyAffineTransform(source, txCompound);
}
case UIImageOrientationUp: // EXIF #1 - do nothing
default: // EXIF 2,4,5,7 - ignore
return source;
}
}
...
UIImage *sourceImage = ... // Our image
CGRect selectionRect = CGRectMake(100.0, 100.0, 300.0, 400.0);
CGRect transformedRect = TransformCGRectForUIImageOrientation(selectionRect, sourceImage.imageOrientation, sourceImage.size);
CGImageRef resultImageRef = CGImageCreateWithImageInRect(sourceImage.CGImage, transformedRect);
UIImage *resultImage = [[UIImage alloc] initWithCGImage:resultImageRef];
我从以下链接中引用了更多detail
最诚挚的问候: - )
答案 7 :(得分:0)
试试这段代码:
NSData *imageData = UIImageJPEGRepresentation(delegate.originalPhoto,100);