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

关于 UIImage 以及 YYImage 的内存问题与解决方案 UIImage图片缓存, YYImage 图片无限创建, 如何更好的解决iOS中的图片内存管理, 做到最多创建一个图片, 不用的时候就会销毁呢? 本文详细分析了两种Image的管理方式, 列出其优缺点, 并提出两种方案, 结合UImage 和 YYImage 的两个优点, 将 UIImage 对象的内存消耗降到最低. 阅读详情

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
}
Fluent基于低氧舱气体交换仿真(氮气与空气混合) 一、背景概述 模拟低氧舱充氮气和排除混合气体的过程,假设注入95%的氮气,舱内原有气体为空气,压力为标准大气压,温度为300K。观察气体注入过程中,舱内平均氮气和氧气浓度的变化。 二、Fluent设置 Setup 1、General type选择压力基 绝对速度 瞬态 重力勾选 2、Model 能量方程开启 组分运输开启,设置方法如下: 选择后OK,view就会变成Edit,点击Edit。然后再次点击Edit。 将组分中的非氮气氧气和空气的气体移除,右边选项需要将空气放在最后一位。 3、Materi 阅读详情

相关推荐

eNSP-Pro配置又丢了?手把手教你用导出功能防患于未然

本文详细介绍了eNSP-Pro配置防丢失的全套方案,包括运行时内存、虚拟存储设备和宿主机文件系统的配置存储机制,以及多维度备份策略和特殊场景下的恢复技巧。通过优化保存流程、自动化定时导出和版本化管理,帮助网络工程师有效防止配置丢失,提升工作效率。

weixin_42665725的博客 239

复原图片镜像旋转的分类UIImage+FixOrientation.h

啥也不说了 上代码 #import "UIImage+FixOrientation.h" @implementation UIImage (fixOrientation) - (UIImage *)fixOrientation {          if (self.imageOrientation == UIImageOrientat

Clement_Gu的博客 988

LinuxCNC开发实战:从安装到EtherCAT配置全解析

本文详细解析LinuxCNC开发实战,从系统安装到EtherCAT总线配置全流程。涵盖实时内核优化、伺服驱动器PDO映射、HAL配置及自定义运动学开发,帮助开发者快速搭建工业级数控系统,提升运动控制精度与稳定性。

rgv234567的博客 352

image图片大小调整和方向调整(UIImageOrientation)

图片大小调整: 此处是写在UIImage分类中的方法self即为image,size为自己传入的大小,根据size生成图片图片不会被剪裁,但可能会被拉伸变形。 - (UIImage *)thumWithSize:(CGSize)size{ UIGraphicsBeginImageContext(size); [self drawInRect:CGRectMake(0, 0, ...

weixin_39339407的博客 1万+

专题一:Labview表格控件 及 应用(三)在表格中插入一行数据

专题一:Labview表格控件 及 应用(三) 在表格中插入一行数据 最近一段时间,做试验台上位机编程,老是用到表格控件,这几天抽时间专门写一个表格控件的专题。有用到的朋友可以参考一下。 今天接着讲一下,表格控件的数据插入,和相关的操作 1.表格控件的数据插入原理: 表格控件是一个 2D 字符串数组。 在表格插入一行,就是在2D数组插入一行。 行、列插入类似** 以下以成绩录入为例说明 2.1 不要表头直接插入 知识点1:创建数组:把数学,语文,英语三个数值,连成一个一位数组(数值型)。 知

Labview十年工控_702老师的博客 1万+

【电脑技巧】CPU正常运行时间过长,怎么解决?

目录 问题描述 解决方案 1、问题描述 不少同志都遇到过这样的问题:按【Ctrl + alt + delete】打开任务管理器,切到“性能”选项卡下,发现自己电脑的CPU正常运行时间竟然为好几十天!很多人担心这会不会影响电脑的寿命?于是很想知道这是怎么回事,以及如何解决这个问题。 我在此解答一下,这是由于你的电脑开启了“快速启动”这一选项的缘故,只要把这一选项关闭,问题就解决了。 2、解决方案 怎样关闭“快速启动”呢?按照如下的步骤来即可。 顺便声明一下,笔者的电脑配置: 使用电脑:联想Yoga 14

橄榄树下的孩子 3万+

EastWave应用案例:机箱屏蔽效能仿真

如何使用EastWave对机箱的电磁屏蔽效能进行仿真

2201_76034687的博客 1392

iOS 修改UIImage的尺寸

- (UIImage *)image:(UIImage*)image byScalingToSize:(CGSize)targetSize {     UIImage *sourceImage = image;     UIImage *newImage = nil;          UIGraphicsBeginImageContext(targetSize);         

糖醋里脊 1064

【Camera2教程一】Camera2的框架Pipeline和framework中核心类和接口的详细介绍

Camera2 的 API 模型被设计成一个 Pipeline(管道),它按顺序处理每一帧的请求并返回请求结果给客户端。

jiangchaobing_2017的博客 790

流体动力学仿真软件:CFX_(10).案例实践:复杂流场分析

在“Phases”选项卡中,定义参与仿真的不同相。例如,如果您要分析气液两相流,可以定义“Air”和“Water”两个相。

kkchenjj的博客 1683

别忽视UIImage中的方向属性, imageOrientation

这几天写个拍照,或者从相册中选择照片,进行剪切,然后分享.结果出现了,剪切后图片颠倒或者旋转90度的问题. 找了很久才发现是忽略imageOrientation这个属性. 以下为解决方法: + (UIImage *)fixOrientation:(UIImage *)aImage { // No-op if the orientation is already corr

习习路263号 1万+

12、无人机系统的建模与仿真

本文深入探讨了无人机系统的建模与仿真技术,涵盖其发展需求、历史演变、动力学建模方法、常用参考框架与状态变量表示,并分析了在控制系统设计、操作员培训和子系统测试中的关键应用。文章还介绍了不同类型无人机(固定翼、旋翼、混合翼)在建模与仿真中的差异,提出了多学科融合、高精度实时仿真及VR/AR技术等未来发展趋势,并给出了实际建模与仿真的标准操作流程,为无人机系统的设计与优化提供了全面的技术支持与展望。

websocket5live的博客 196

UIImage 图像-IOS开发

声明 欢迎转载,但是请尊重作者劳动成果,转载请保留此框内声明,谢谢。 文章出处:http://blog.youkuaiyun.com/iukey UIKit中有一些类可以用来操纵单个图像,还有一个图像类可以用来显示图像。Apple还提供了一种特殊的导航控制器,用于从图像库中选择图像。 UIImage类对图像及其底层数据进行封装。它可以直接绘制在一个视图内,或者作为一个图像容器在另一个更

潇洒的程序员 1万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

UIImage的加载和显示

UIImage支持如下几种图片格式: jpg  jpeg  png  gif tiff tif  bmp bmpf  ice  cur  xbm  当系统内存紧张的时候UIImage所承载的iamge元素会被清理出内存,当回事uiimage对象并不会被清理出去,当程序再次使用这个被清理过的图片资源的时候将自动从原始文件中加载图片数据 图片的创建: 如果用UIIma

fang8380的专栏 784

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

关于UIImage自动释放问题

在做iPhone和iPad应用中,可能很多人都会用到xib和storyboard。 在写代码时,我们在加载一张图片时,经常会这样写到[UIImage imageNamed:@"text.png"];用于图片的加载。而在xib和storyboard中使用UIImageView控件时,一般会在这里放图片名字。 但是注意内存的小伙伴就会知道,在这里添加图片名字后,切换场景或者界面时,内存不能

新的开始,新的启程 2015

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

浅析 UIImage 的2种加载方式对内存的影响

A、 UIImage的2种加载方式: 方式一:有缓存(图片所占用的内存会一直停留在程序中) + (nullable UIImage *)imageNamed:(NSString *)name;  // name是图片的文件名 解析: 1. 该方法会自动地做缓存,一般用于给控件添加素材图片,比如背景图片、placeHolder等。  2. 使用( 

HenryZhang的博客 3598

iOS-UIImage的创建和简单使用

UIKit中有一些类可以用来操纵单个图像,还有一个图像类可以用来显示图像。Apple还提供了一种特殊的导航控制器,用于从图像库中选择图像。 UIImage类对图像及其底层数据进行封装。它可以直接绘制在一个视图内,或者作为一个图像容器在另一个更大的图像视图容器中使用。这个类类提供的方法可以用来从各种来源中载入图像,在屏幕上设置图片的方向,以及提供有关图像的信息。对于简单的图形应用,可以将UII

huangqiwa的专栏 638

UIImageView和UIImage,CGContextRef 的一些知识点

1.UIImageView不支持内部图片平铺(tile) 2.资源中的图片要用小写的,模拟器中可能不区分大小写,但在真机中区分.    [UIImage imageNamed:@""]; 在设备中区分大小写 3.UIView没有背景图属性,有背景色属性.设置背景图可以用addSubView(backgroundImage);,推荐的是设置背景色。 4.[UIImage imageNamed

程序人生 1万+

iOS之UIImage详情

iOS之UIImage详情 UIKit中有一些类可以用来操纵单个图像,还有一个图像类可以用来显示图像。Apple还提供了一种特殊的导航控制器,用于从图像库中选择图像。 UIImage类对图像及其底层数据进行封装。它可以直接绘制在一个视图内,或者作为一个图像容器在另一个更大的图像视图容器中使用。这个类类提供的方法可以用来从各种来源中载入图像,在屏幕上设置图片的方向,以及提供有关图像的信息。对于简

WANGYURUI_wyr的博客 738

UIImage imageNamed引起的内存问题1

你还在使用myImage = [UIImage imageNamed:@"icon.png"];吗???!!!    如题,是不是大家为了方便都这样加载图片啊 myImage = [UIImage imageNamed:@"icon.png"]; 那么小心了 这种方法在一些图片很少,或者图片很小的程序里是ok的。 但是,在大量加载图片的程序里,请千万不要这样做。

SpeedBoy007的专栏 1210

UIImage imageNamed引起的内存问题2

UIImage imageNamed引起的内存问题 2012-07-18 01:45 126人阅读 评论(0) 收藏 举报 前段时间开发的时候总是遇到莫名其妙的崩溃。最后终于找出来是什么鬼原因:  1 [UIImage imageNamed:]; 缓存了过多的大图片导致内存用尽,最后崩溃。最后解决这个问题的方法如下:  首先只缓存减小了大小的图片,

SpeedBoy007的专栏 1831

UIImage 详解

UIKit中有一些类可以用来操纵单个图像,还有一个图像类可以用来显示图像。Apple还提供了一种特殊的导航控制器,用于从图像库中选择图像。 UIImage类对图像及其底层数据进行封装。它可以直接绘制在一个视图内,或者作为一个图像容器在另一个更大的图像视图容器中使用。这个类类提供的方法可以用来从各种来源中载入图像,在屏幕上设置图片的方向,以及提供有关图像的信息。对于简单的图形应用,可以将UIIma

zyd141124的专栏 505

iOS UIImage加载图片的问题

[UIImage imageNamed:@"icon.png"] 用上面的方法加载图片有问题。该方法即可以从bundle中读取图片。 这种方法在application bundle的顶层文件夹寻找由供应的名字的图象 。 如果找到图片,装载到iPhone系统缓存图象。那意味图片是(理论上)放在内存里作为cache的。因此如果图片资源多了或大了,此方式容易引起发生内存警告从而导致自动退出

sandouchan的博客 1024

UIImage

转自:http://www.oschina.net/question/213217_40627 UIKit中有一些类可以用来操纵单个图像,还有一个图像类可以用来显示图像。Apple还提供了一种特殊的导航控制器,用于从图像库中选择图像。 UIImage类对图像及其底层数据进行封装。它可以直接绘制在一个视图内,或者作为一个图像容器在另一个更大的图像视图容器中使用。这个类

张中峰的专栏 3295

UIImage和UIImageView的区别

1.UIImage 更接近是一个内存中存储的图片对象, 而UIImageView是一个主要用于显示图片的类; 2.把UIImage想成一个在内存中存储的对象,就像数据对象如字典一样;

阿明 3338
上一篇: 在ncnn上把玩mobileNet
下一篇: Image-to-Image Translation with Conditional Adversarial Networks笔记
IT修道者
IT修道者 领域专家: 人工智能技术领域 领域专家: 人工智能技术领域
博客等级 码龄17年 326粉丝 95原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值