旋转UIImage Monotouch

4
我试图从手机上传图片到我的网络服务,但是当我上传图片时发现图片方向丢失了。在上传之前,我需要做些什么来确保图片以正确的方向上传吗?
我还在其他地方找到了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;
    }

2
上传后方向“丢失”这一事实似乎表明,要么EXIF方向标签不再附加到图像上,要么接收软件不予以尊重。您是否探索过这种可能性? - Jacob Foshee
我会先探索Jacob Foshee关于EXIF方向标签的建议。请参见https://dev59.com/HGkw5IYBdhLWcg3wm74h - Diego
你救了我的一天。谢谢。 - Anton Tropashko
3个回答

3
您得到黑色图像的原因是翻译和旋转调用相反。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,将很容易显示更改这些函数顺序时所获得的差异,因为一些原始图像始终可见。

1

根据@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;
        }
    }

非常有用的代码片段。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接