UIImage数据始终处于横向模式 [英] UIImage data always in landscape mode

查看:241
本文介绍了UIImage数据始终处于横向模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎当我在肖像模式下使用相机拍摄照片时, UIImage 具有正确的大小/宽高比(1536x2048 / 3:4) (右),导出到一个文件( UIImage.AsPNG()。Save()),它总是以横向模式(2048x1536,4:3) / p>

这是真的吗,还是我做错了什么?还有一个解决方法,例如。

更新:最初我认为这也发生在 ALAssetsLibrary.WriteImageToSavedPhotosAlbum code> UIImage.SaveToPhotosAlbum(),但是仔细检查我意识到, UIImage 在这种情况下不是从相机的原始,而是从早期 AsPNG()重新组建的已保存数据。



>看起来这是iPhone摄像机的一个通用功能,唯一的方法是通过手动旋转图像。我尝试将此代码移植到MT,如下所示,但是我似乎已经做了是发明一种新的方式来创建正确的大小和宽高比的空白图像。

  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;
}
}


解决方案

I终于得到这个工作。下面是一个有代码的提示:



https:// gist.github.com/890460



和我的博文:



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


It seems as though when I take a picture with the camera in portrait mode, the UIImage has the correct size/aspect ratio (1536x2048 / 3:4) and orientation (Right), 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, e.g. with ALAssetsLibrary.WriteImageToSavedPhotosAlbum?

Update: Originally I thought this also happened with UIImage.SaveToPhotosAlbum(), but on closer inspection I realize that the UIImage in that case was not the original from the camera, but rather one reconstituted from earlier AsPNG() saved data.

Update again: It looks like this is a general 'feature' of the iPhone camera, and the only way to fix it is by manually rotating the image. I tried porting this code to MT, as shown below, but what I seem to have done is invent a new way to create blank images of the right size and aspect ratio. Can anyone spot the bug?

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;
    }
}

解决方案

I finally got this to work. Here's a gist which has the code:

https://gist.github.com/890460

and my blog post about it:

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

这篇关于UIImage数据始终处于横向模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆