关闭

解决UIImage显示方向和内存方向不一致的问题

标签: UIImage存储方向显示方向
283人阅读 评论(0) 收藏 举报
分类:

iOS中的UIImage中有imageOrientation属性,该属性决定了UIImage在手机上显示时的方向。如果imageOrientation的值为left或right,那么显示出来的图像和实际图像在内存中的存储就存在90度的旋转问题。比如显示出来的图片是720*1280的,实际上该图在内存中是按1280*720存储的。
在stackoverflow上折腾了一番,找到了下面靠谱的解决办法。

extension UIImage {
    func fixImageOrientation() -> UIImage? {

        guard let cgImage = self.cgImage else {
            return nil
        }

        if self.imageOrientation == UIImageOrientation.up {
            return self
        }

        let width  = self.size.width
        let height = self.size.height

        var transform = CGAffineTransform.identity

        switch self.imageOrientation {
        case .down, .downMirrored:
            transform = transform.translatedBy(x: width, y: height)
            transform = transform.rotated(by: CGFloat.pi)

        case .left, .leftMirrored:
            transform = transform.translatedBy(x: width, y: 0)
            transform = transform.rotated(by: 0.5*CGFloat.pi)

        case .right, .rightMirrored:
            transform = transform.translatedBy(x: 0, y: height)
            transform = transform.rotated(by: -0.5*CGFloat.pi)

        case .up, .upMirrored:
            break
        }

        switch self.imageOrientation {
        case .upMirrored, .downMirrored:
            transform = transform.translatedBy(x: width, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)

        case .leftMirrored, .rightMirrored:
            transform = transform.translatedBy(x: height, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)

        default:
            break;
        }

        // Now we draw the underlying CGImage into a new context, applying the transform
        // calculated above.
        guard let colorSpace = cgImage.colorSpace else {
            return nil
        }

        guard let context = CGContext(
            data: nil,
            width: Int(width),
            height: Int(height),
            bitsPerComponent: cgImage.bitsPerComponent,
            bytesPerRow: 0,
            space: colorSpace,
            bitmapInfo: UInt32(cgImage.bitmapInfo.rawValue)
            ) else {
                return nil
        }

        context.concatenate(transform);

        switch self.imageOrientation {

        case .left, .leftMirrored, .right, .rightMirrored:
            // Grr...
            context.draw(cgImage, in: CGRect(x: 0, y: 0, width: height, height: width))

        default:
            context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))
        }

        // And now we just create a new UIImage from the drawing context
        guard let newCGImg = context.makeImage() else {
            return nil
        }

        let img = UIImage(cgImage: newCGImg)

        return img;
    }
 }

上面的代码能根据UIImage中的imageOrientation去翻转图像的实际存储布局。

如果想任意角度旋转图像,比如来个30度?下面的函数可以实现。

func imageRotatedByDegrees(oldImage: UIImage, deg degrees: CGFloat) -> UIImage {
    //Calculate the size of the rotated view's containing box for our drawing space

    var rotatedViewBox: UIView = UIView(frame: CGRect(x: 0, y: 0, width: oldImage.size.width, height: oldImage.size.height))

    print(oldImage.size.height)
    if (oldImage.imageOrientation == .right)
    {
        rotatedViewBox = UIView(frame: CGRect(x: 0, y: 0, width: oldImage.size.height, height: oldImage.size.width))
    }

    let t: CGAffineTransform = CGAffineTransform(rotationAngle: degrees * CGFloat.pi / 180)
    rotatedViewBox.transform = t
    let rotatedSize: CGSize = rotatedViewBox.frame.size
    //Create the bitmap context
    UIGraphicsBeginImageContext(rotatedSize)
    let bitmap: CGContext = UIGraphicsGetCurrentContext()!
    //Move the origin to the middle of the image so we will rotate and scale around the center.
    bitmap.translateBy(x: rotatedSize.width / 2, y: rotatedSize.height / 2)
    //Rotate the image context
    bitmap.rotate(by: (degrees * CGFloat.pi / 180))
    //Now, draw the rotated/scaled image into the context
    bitmap.scaleBy(x: 1.0, y: -1.0)
    bitmap.draw(oldImage.cgImage!, in: CGRect(x: -oldImage.size.height / 2, y: -oldImage.size.width / 2, width: oldImage.size.height, height: oldImage.size.width))
    let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return newImage
}
0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

UIImage改变图片方向

+ (UIImage *)imageWithCGImage:(CGImageRef)cgImage scale:(CGFloat)scale orientation:(UIImageOrientati...
  • qq_25737881
  • qq_25737881
  • 2016-09-20 00:50
  • 640

UIImage的imageOrientation属性 修改图片旋转了的bug

本回要从我们项目说起,今天测试的给我叫去,问我这个图片裁剪是不是有BUG,从手机相册里选的图(iOS设备)裁剪出来怎么就.....(省略好多字)。 当时本大侠就想 NND当时我做的时候就用模...
  • u013430014
  • u013430014
  • 2015-05-28 15:23
  • 2869

iOS:图片的旋转方向问题

【你知道吗?】iOS 6 默认相机程序让你的 iPhone 照片自带方向信息 可能几乎很少的人会知道在 iOS 6中有一项新的功能是用 iPhone 拍出的照片会记录该照片的方向信息。 ...
  • u013929312
  • u013929312
  • 2015-03-10 12:41
  • 2896

UIImage的imageOrientation属性 修改图片旋转了的bug

本回要从我们项目说起,今天测试的给我叫去,问我这个图片裁剪是不是有BUG,从手机相册里选的图(iOS设备)裁剪出来怎么就.....(省略好多字)。 当时本大侠就想 NND当时我做的时候就用模...
  • u013430014
  • u013430014
  • 2015-05-28 15:23
  • 2869

iOS开发 UIimage旋转,得到旋转后的Image图片,解决imageView旋转,内部图片不跟着旋转问题

一:前言  1.0  : 图片处理中,比如对一个ImageView进行旋转,那么旋转后图片缺还是原来的样子,本文就是解决图片旋转的问题  1.0 :无demo说话不硬气,上github地址:htt...
  • horisea
  • horisea
  • 2017-04-21 15:21
  • 1887

android 解决View的滑动冲突:滑动方向不一致的滑动

  • 2016-03-03 15:19
  • 7.01MB
  • 下载

程序员求职之道(《程序员面试笔试宝典》)之自己的强项或是研究方向与中意的工作岗位不一致怎么办?

戏如人生,人生如戏,只要找对了角色,何妨一直畅演下去? ——《新龙门客栈》 无论是本科生还是研究生,很多人在毕业求职的时候,都会发现一个奇怪的现象:自己对C语言很熟悉,很擅长,...
  • u012463017
  • u012463017
  • 2014-09-30 20:37
  • 521

TankWar 单机(JAVA版)优化炮杆和坦克移动方向不一致

在上篇文章中我们发现炮杆方向和移动方向不一致  如图: 那么要怎么优化呢? 也就是在画炮杆时根据当前坦克的方向画。所以需要一个枚举变量Direction 来监视当前坦克的方向 新建一个枚举变量: ...
  • su20145104009
  • su20145104009
  • 2016-10-05 13:22
  • 1666

解决mapgis6.7出图jpg面填充方向颠倒与内存不足问题

  • 2010-08-21 09:59
  • 575KB
  • 下载

关于ArcGIS Engine开发过程中版本不一致问题的参考解决方案

  • 2017-06-21 18:09
  • 483KB
  • 下载
    个人资料
    • 访问:182630次
    • 积分:2760
    • 等级:
    • 排名:第15013名
    • 原创:86篇
    • 转载:6篇
    • 译文:0篇
    • 评论:73条
    文章分类
    最新评论