【问题标题】:Rotate UIImage Monotouch旋转 UIImage 单点触控
【发布时间】:2012-09-09 06:17:14
【问题描述】:

我正在尝试将图像从手机上传到我的网络服务,但我注意到上传图像时图像方向丢失了。在上传之前我需要做些什么来确保图像以正确的方向上传吗?

我还查看了其他地方并找到了用于旋转图像的 Objective-C 代码,我将其转换为 C#,但每次使用旋转方法时,图像都会变黑,即我猜什么都不会显示。

我附上我的代码供您参考,如果有人能告诉我我做错了什么,我将非常非常感激。谢谢!

    public static UIImage RotateImage(this UIImage image)
    {
        UIImage imageToReturn = null;
        if(image.Orientation == UIImageOrientation.Up)
        {
            imageToReturn = image;
        }
        else 
        {
            CGAffineTransform transform = CGAffineTransform.MakeIdentity();

            switch (image.Orientation) {
                case UIImageOrientation.Down:
                case UIImageOrientation.DownMirrored:
                    transform.Translate(image.Size.Width, image.Size.Height);
                    transform.Rotate((float)Math.PI);
                    break;

                case UIImageOrientation.Left:
                case UIImageOrientation.LeftMirrored:
                    transform.Translate(image.Size.Width, 0);
                    transform.Rotate((float)Math.PI/2);
                    break;

                case UIImageOrientation.Right:
                case UIImageOrientation.RightMirrored:
                    transform.Translate(0, image.Size.Height);
                    transform.Rotate((float)-Math.PI/2);
                    break;
                case UIImageOrientation.Up:
                case UIImageOrientation.UpMirrored:
                    break;
            }

            switch (image.Orientation) {
                case UIImageOrientation.UpMirrored:
                case UIImageOrientation.DownMirrored:
                    transform.Translate(image.Size.Width, 0);
                    transform.Scale(-1, 1);
                    break;

                case UIImageOrientation.LeftMirrored:
                case UIImageOrientation.RightMirrored:
                    transform.Translate(image.Size.Height, 0);
                    transform.Scale(-1, 1);
                    break;
                case UIImageOrientation.Up:
                case UIImageOrientation.Down:
                case UIImageOrientation.Left:
                case UIImageOrientation.Right:
                    break;
            }

            //now draw image
            using(var context = new CGBitmapContext(IntPtr.Zero,
                                                    (int)image.Size.Width, 
                                                    (int)image.Size.Height, 
                                                    image.CGImage.BitsPerComponent,
                                                    image.CGImage.BytesPerRow,
                                                    image.CGImage.ColorSpace,
                                                    image.CGImage.BitmapInfo)){
                context.ConcatCTM(transform);
                switch (image.Orientation) 
                {
                    case UIImageOrientation.Left:
                    case UIImageOrientation.LeftMirrored:
                    case UIImageOrientation.Right:
                    case UIImageOrientation.RightMirrored:
                        // Grr...
                        context.DrawImage(new RectangleF(PointF.Empty,new SizeF(image.Size.Height, image.Size.Width)), image.CGImage);
                        break;
                    default:
                        context.DrawImage(new RectangleF(PointF.Empty, new SizeF(image.Size.Width, image.Size.Height)), image.CGImage);
                        break;
                }

                using(var imageRef = context.ToImage())
                {
                    imageToReturn = new UIImage(imageRef);
                }
            }
        }

        return imageToReturn;
    }

【问题讨论】:

  • 通过上传“丢失”方向这一事实似乎表明 EXIF 方向标签不再附加到图像上,或者接收软件不支持它。您是否探索过这种可能性?
  • 我会先探讨 Jacob Foshee 关于 EXIF 方向标签的建议。见stackoverflow.com/questions/9766394/…
  • 你拯救了我的一天。谢谢

标签: ios xamarin.ios


【解决方案1】:

你得到黑色图像的原因是 translate 和 rotate 调用是向后的。 iPod/iphone 上的正常人像图片是“右”方向。转换它们的正确代码使用:

        case UIImageOrientation.Right:
        case UIImageOrientation.RightMirrored:
            transform.Rotate (-(float)Math.PI / 2);
            transform.Translate (0, input.Size.Height);
            break;

变换函数是顺序相关的。此代码将其旋转到正确的方向,但由于旋转大约是左下角的 0,0 坐标,因此图像现在刚好离开框架的底部。然后翻译将它推到它所属的位置。

原始代码会将侧向图像推离框架顶部,然后旋转将转动物体,使图像向右转,但远离框架右侧。

使用较小的高度值(如 100 或 200 和 pi/4)将很容易显示更改这些函数的顺序时得到的差异,因为某些原始图像始终可见。

【讨论】:

    【解决方案2】:

    使用@Random 提供的信息,我更正了原始代码以使其正常工作:

        private byte[] RotateImage(UIImage image)
        {
            UIImage imageToReturn = null;
            if (image.Orientation == UIImageOrientation.Up)
            {
                imageToReturn = image;
            }
            else
            {
                CGAffineTransform transform = CGAffineTransform.MakeIdentity();
    
                switch (image.Orientation)
                {
                    case UIImageOrientation.Down:
                    case UIImageOrientation.DownMirrored:
                        transform.Rotate((float)Math.PI);
                        transform.Translate(image.Size.Width, image.Size.Height);
                        break;
    
                    case UIImageOrientation.Left:
                    case UIImageOrientation.LeftMirrored:
                        transform.Rotate((float)Math.PI / 2);
                        transform.Translate(image.Size.Width, 0);
                        break;
    
                    case UIImageOrientation.Right:
                    case UIImageOrientation.RightMirrored:
                        transform.Rotate(-(float)Math.PI / 2);
                        transform.Translate(0, image.Size.Height);
                        break;
                    case UIImageOrientation.Up:
                    case UIImageOrientation.UpMirrored:
                        break;
                }
    
                switch (image.Orientation)
                {
                    case UIImageOrientation.UpMirrored:
                    case UIImageOrientation.DownMirrored:
                        transform.Translate(image.Size.Width, 0);
                        transform.Scale(-1, 1);
                        break;
    
                    case UIImageOrientation.LeftMirrored:
                    case UIImageOrientation.RightMirrored:
                        transform.Translate(image.Size.Height, 0);
                        transform.Scale(-1, 1);
                        break;
                    case UIImageOrientation.Up:
                    case UIImageOrientation.Down:
                    case UIImageOrientation.Left:
                    case UIImageOrientation.Right:
                        break;
                }
    
                //now draw image
                using (var context = new CGBitmapContext(IntPtr.Zero,
                                                        (int)image.Size.Width,
                                                        (int)image.Size.Height,
                                                        image.CGImage.BitsPerComponent,
                                                        image.CGImage.BytesPerRow,
                                                        image.CGImage.ColorSpace,
                                                        image.CGImage.BitmapInfo))
                {
                    context.ConcatCTM(transform);
                    switch (image.Orientation)
                    {
                        case UIImageOrientation.Left:
                        case UIImageOrientation.LeftMirrored:
                        case UIImageOrientation.Right:
                        case UIImageOrientation.RightMirrored:
                            // Grr...
                            context.DrawImage(new RectangleF(PointF.Empty, new SizeF((float)image.Size.Height, (float)image.Size.Width)), image.CGImage);
                            break;
                        default:
                            context.DrawImage(new RectangleF(PointF.Empty, new SizeF((float)image.Size.Width, (float)image.Size.Height)), image.CGImage);
                            break;
                    }
    
                    using (var imageRef = context.ToImage())
                    {
                        imageToReturn = new UIImage(imageRef);
                    }
                }
            }
    
            using (NSData imageData = imageToReturn.AsJPEG())
            {
                Byte[] byteArray = new Byte[imageData.Length];
                System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, byteArray, 0, Convert.ToInt32(imageData.Length));
                return byteArray;
            }
        }
    

    非常有用的一段代码

    【讨论】:

      【解决方案3】:

      我通过this question 找到了this gist。希望这段代码对你有用!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-15
        • 2023-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-29
        • 2010-12-17
        相关资源
        最近更新 更多