我正在iOS 3.1.3 iPhone上测试我的iPhone应用程序。我正在使用UIImagePickerController选择/捕获图像:
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[imagePicker setDelegate:self];
[self.navigationController presentModalViewController:imagePicker animated:YES];
[imagePicker release];
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
imageView.image = self.image;
[self.navigationController dismissModalViewControllerAnimated:YES];
submitButton.enabled = YES;
}
然后在某个时候,我使用ASI类将它发送到我的web服务器:
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://example.com/myscript.php"]];
[request setDelegate:self];
[request setStringEncoding:NSUTF8StringEncoding];
[request setShouldContinueWhenAppEntersBackground:YES];
//other post keys/values
[request setFile:UIImageJPEGRepresentation(self.image, 100.0f) withFileName:[NSString stringWithFormat:@"%d.jpg", [[NSDate date] timeIntervalSinceNow]] andContentType:@"image/jpg" forKey:@"imageFile"];
[request startAsynchronous];
存在的问题:
当我拿着iPhone拍照时,照片会被上传到服务器,就像你期望的那样。手持竖屏拍照时,上传的照片是旋转90度后观看的。
我的应用程序被设置为只在纵向模式(倒置和常规)下工作。
我怎样才能使图像始终显示正确的方向后上传?
在UIImageView中显示的图像是正确的(直接在拍照后),但在服务器上查看则不然。
这是swift的UIImage扩展:
extension UIImage {
func fixOrientation() -> UIImage {
// No-op if the orientation is already correct
if ( self.imageOrientation == UIImageOrientation.Up ) {
return self;
}
// 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 = CGAffineTransformIdentity
if ( self.imageOrientation == UIImageOrientation.Down || self.imageOrientation == UIImageOrientation.DownMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
}
if ( self.imageOrientation == UIImageOrientation.Left || self.imageOrientation == UIImageOrientation.LeftMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
}
if ( self.imageOrientation == UIImageOrientation.Right || self.imageOrientation == UIImageOrientation.RightMirrored ) {
transform = CGAffineTransformTranslate(transform, 0, self.size.height);
transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2));
}
if ( self.imageOrientation == UIImageOrientation.UpMirrored || self.imageOrientation == UIImageOrientation.DownMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformScale(transform, -1, 1)
}
if ( self.imageOrientation == UIImageOrientation.LeftMirrored || self.imageOrientation == UIImageOrientation.RightMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
var ctx: CGContextRef = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage));
CGContextConcatCTM(ctx, transform)
if ( self.imageOrientation == UIImageOrientation.Left ||
self.imageOrientation == UIImageOrientation.LeftMirrored ||
self.imageOrientation == UIImageOrientation.Right ||
self.imageOrientation == UIImageOrientation.RightMirrored ) {
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)
} else {
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
}
// And now we just create a new UIImage from the drawing context and return it
return UIImage(CGImage: CGBitmapContextCreateImage(ctx))!
}
}
基于MetalHeart2003的早期工作。
以下是@an0给出的答案的Swift版本:
func normalizedImage() -> UIImage {
if (self.imageOrientation == UIImageOrientation.Up) {
return self;
}
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale);
let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
self.drawInRect(rect)
let normalizedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return normalizedImage;
}
也可以用在更一般的函数中:
func fixOrientation(img:UIImage) -> UIImage {
if (img.imageOrientation == UIImageOrientation.Up) {
return img;
}
UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale);
let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
img.drawInRect(rect)
let normalizedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return normalizedImage;
}
Swift 3版本:
func fixOrientation(img: UIImage) -> UIImage {
if (img.imageOrientation == .up) {
return img
}
UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale)
let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
img.draw(in: rect)
let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return normalizedImage
}
我把这个换成了Xamarin:
private static UIImage FixImageOrientation(UIImage image)
{
if (image.Orientation == UIImageOrientation.Up)
{
return image;
}
var transform = CGAffineTransform.MakeIdentity();
float pi = (float)Math.PI;
switch (image.Orientation)
{
case UIImageOrientation.Down:
case UIImageOrientation.DownMirrored:
transform = CGAffineTransform.Translate(transform, image.Size.Width, image.Size.Height);
transform = CGAffineTransform.Rotate(transform, pi);
break;
case UIImageOrientation.Left:
case UIImageOrientation.LeftMirrored:
transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
transform = CGAffineTransform.Rotate(transform, pi / 2);
break;
case UIImageOrientation.Right:
case UIImageOrientation.RightMirrored:
transform = CGAffineTransform.Translate(transform, 0, image.Size.Height);
transform = CGAffineTransform.Rotate(transform, -(pi / 2));
break;
}
switch (image.Orientation)
{
case UIImageOrientation.UpMirrored:
case UIImageOrientation.DownMirrored:
transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
transform = CGAffineTransform.Scale(transform, -1, 1);
break;
case UIImageOrientation.LeftMirrored:
case UIImageOrientation.RightMirrored:
transform = CGAffineTransform.Translate(transform, image.Size.Height, 0);
transform = CGAffineTransform.Scale(transform, -1, 1);
break;
}
var ctx = new CGBitmapContext(null, (nint)image.Size.Width, (nint)image.Size.Height, image.CGImage.BitsPerComponent,
image.CGImage.BytesPerRow, image.CGImage.ColorSpace, image.CGImage.BitmapInfo);
ctx.ConcatCTM(transform);
switch (image.Orientation)
{
case UIImageOrientation.Left:
case UIImageOrientation.LeftMirrored:
case UIImageOrientation.Right:
case UIImageOrientation.RightMirrored:
ctx.DrawImage(new CGRect(0, 0, image.Size.Height, image.Size.Width), image.CGImage);
break;
default:
ctx.DrawImage(new CGRect(0, 0, image.Size.Width, image.Size.Height), image.CGImage);
break;
}
var cgimg = ctx.ToImage();
var img = new UIImage(cgimg);
ctx.Dispose();
ctx = null;
cgimg.Dispose();
cgimg = null;
return img;
}