UIImage data is always in landscape mode

It seems that when I take a picture with the camera in portrait mode, UIImage has the correct size / aspect ratio (1536x2048 / 3: 4) and orientation (right), is exported to a file (with UIImage.AsPNG().Save() ), it always comes out in landscape mode (2048x1536, 4: 3).

Is this for real, or am I doing something wrong? And is there a workaround, for example. with ALAssetsLibrary.WriteImageToSavedPhotosAlbum ?

Update: Initially, I thought this also happened with UIImage.SaveToPhotosAlbum() , but upon closer inspection, I understand that UIImage in this case was not the original from the camera, but rather was restored from previously AsPNG() data.

Update again: This seems to be a common β€œfeature” of the iPhone camera, and the only way to fix it is to manually rotate the image. I tried porting this code to MT, as shown below, but what I seemed to do was invent a new way to create blank images on the right with size and aspect ratio. Can anyone spot an error?

 public static class ImageUtils { static float DefaultMaxSize = 960; public static UIImage ScaleAndRotateImage (UIImage image) { return ScaleAndRotateImage(image, DefaultMaxSize); } public static UIImage ScaleAndRotateImage (UIImage image, float maxSize) { CGImage imgRef = image.CGImage; float width = imgRef.Width; float height = imgRef.Height; CGAffineTransform transform = CGAffineTransform.MakeIdentity(); RectangleF bounds = new RectangleF (0, 0, width, height); if (width > maxSize || height > maxSize) { float ratio = width / height; if (ratio > 1) { bounds.Width = maxSize; bounds.Height = bounds.Width / ratio; } else { bounds.Height = maxSize; bounds.Width = bounds.Height * ratio; } } float scaleRatio = bounds.Width / width; SizeF imageSize = new SizeF (imgRef.Width, imgRef.Height); float boundHeight; UIImageOrientation orient = image.Orientation; if (orient == UIImageOrientation.Up) { //EXIF = 1 transform = CGAffineTransform.MakeIdentity(); } else if (orient == UIImageOrientation.UpMirrored) { //EXIF = 2 transform = CGAffineTransform.MakeTranslation (imageSize.Width, 0); transform.Scale (-1.0f, 1.0f); } else if (orient == UIImageOrientation.Down) { //EXIF = 3 transform = CGAffineTransform.MakeTranslation (imageSize.Width, imageSize.Height); transform.Rotate ((float) Math.PI); } else if (orient == UIImageOrientation.DownMirrored) { //EXIF = 4 transform = CGAffineTransform.MakeTranslation (0, imageSize.Height); transform.Scale (1.0f, -1.0f); } else if (orient == UIImageOrientation.LeftMirrored) { //EXIF = 5 boundHeight = bounds.Height; bounds.Height = bounds.Width; bounds.Width = boundHeight; transform = CGAffineTransform.MakeTranslation (imageSize.Height, imageSize.Width); transform.Scale (-1.0f, 1.0f); transform.Rotate ((float)(3.0f * Math.PI / 2.0)); } else if (orient == UIImageOrientation.Left) { //EXIF = 6 boundHeight = bounds.Height; bounds.Height = bounds.Width; bounds.Width = boundHeight; transform = CGAffineTransform.MakeTranslation (0, imageSize.Width); transform.Rotate ((float)(3.0f * Math.PI / 2.0)); } else if (orient == UIImageOrientation.RightMirrored) { //EXIF = 7 boundHeight = bounds.Height; bounds.Height = bounds.Width; bounds.Width = boundHeight; transform = CGAffineTransform.MakeScale (-1.0f, 1.0f); transform.Rotate ((float)(Math.PI / 2.0)); } else if (orient == UIImageOrientation.Right) { //EXIF = 8 boundHeight = bounds.Height; bounds.Height = bounds.Width; bounds.Width = boundHeight; transform = CGAffineTransform.MakeTranslation (imageSize.Height, 0); transform.Rotate ((float)(Math.PI / 2.0)); } else { throw new InvalidOperationException ("Invalid image orientation"); } UIGraphics.BeginImageContext(bounds.Size); CGContext context = UIGraphics.GetCurrentContext (); if (orient == UIImageOrientation.Right || orient == UIImageOrientation.Left) { context.ScaleCTM (-scaleRatio, scaleRatio); context.TranslateCTM (-height, 0f); } else { context.ScaleCTM (scaleRatio, -scaleRatio); context.TranslateCTM (0f, -height); } context.ConcatCTM(transform); context.DrawImage (new RectangleF(0, 0, width, height), imgRef); UIImage imageCopy = UIGraphics.GetImageFromCurrentImageContext (); UIGraphics.EndImageContext (); return imageCopy; } } 
+2
source share
3 answers

I finally got it to work. Here is the gist that has the code:

https://gist.github.com/890460

and my blog post about this:

http://www.fastchicken.co.nz/2011/03/28/scaling-and-rotating-an-image-in-monotouch/

+3
source

Found the answer here: CGContextDrawImage draws the image upside down when passing UIImage.CGImage : use UIImage.Draw() , not CGContext.DrawImage() . Received code:

 public static UIImage Rotate(UIImage orig) { float w0 = orig.Size.Width; float h0 = orig.Size.Height; UIGraphics.BeginImageContext(new SizeF(w0, h0)); orig.Draw(new RectangleF(0, 0, w0, h0)); UIImage imageCopy = UIGraphics.GetImageFromCurrentImageContext (); UIGraphics.EndImageContext (); return imageCopy; } 

This creates an image of the correct size, proportion and orientation, but with the orientation always "up".

+3
source

Try converting UIImage to NSData through UIImageJPEGRepresentation , since the PNG image does not preserve the image orientation value.

0
source

Source: https://habr.com/ru/post/1434520/


All Articles