IOS照片颠倒分析及移动/页面端的处理策略和思路
前言:
前几天, 写了一篇关于IOS手机上传照片颠倒的技术分析文章: IOS照片颠倒分析及PHP服务端的处理.
不过其思路是从服务器来进行处理的, 这种做法相当普遍.
今天来讲述下, 如何从移动端/页面端, 来解决这个问题, 侧重于讲讲思路.
意义:
但移动互联网有它独特的背景, 至今降耗电和省流量, 是很多移动端产品孜孜努力的方向.
再者移动端手机的照片大小, 普遍较大, 因此直接往服务器传, 往往会消耗很多流量, 在弱网环境下, 用户等待的时间也长, 时常会失败, 体验非常不好. 因此移动端/页面端(webapp)进行图片的压缩/缩放, 就非常有意义了.
同时, 既然已经做了图片的压缩和大小缩放, 何不一起把图片的旋转也一起搞定.
可行性分析:
由于IOS照片图片颠倒, 是以为IOS的不作为, 不过其写入了Orientation信息到EXIF信息头中(jpeg和tiff文件).
想要解决颠倒问题, 先要看, 能否在移动/页面端, 获取到EXIF信息.
幸好, 我们拥有exif.js, 这个开源的js工具库, 帮我们铺好了路.
这是资料链接: Exif.js 读取图像的元数据 http://code.ciaoca.com/javascript/exif-js/ .
其对图片EXIF信息头的处理, 非常的简洁:
*) html的相关代码:
1 | < input type="file" accept="image/*" capture="camera" onchange="selectFileImage(this);"> |
*) exif的使用代码片段:
1 2 3 4 5 6 7 8 | function selectFileImage(file) { var Orientation = null; //获取照片方向角属性,用户旋转控制 EXIF.getData(file, function() { EXIF.getAllTags(this); Orientation = EXIF.getTag(this, 'Orientation'); }); } |
这边变量file为, input控件选择具体图片文件后得到的对象, Orientation即是旋转信息.
Orientation的取值和含义:
旋转角度 |
参数 |
0° |
1 |
顺时针90° |
6 |
逆时针90° |
8 |
180° |
3 |
颠倒和缩放:
在页面端, 需要处理是的限制大小尺寸, 比如设置一个最大宽度值(限宽不限高), 同时又要解决图片旋转问题.
其思路是借助canvas重绘来实现, 1). 先确定旋转方向, 2). 图片尺寸缩小调整 3). 确定canvas大小, 4). 绘制过程.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | image = new Image(); image.onload = function () { var canvas = document.getElementById( "myCanvas" ); var expectWidth, expectHeight; // *) 确定目标的宽和高 if ( Orientation == 6 || Orientation == 8 ) { expectWidth = image.height; expectHeight = image.width; } else { expectWidth = image.width; expectHeight = image.height; } // *) 最大宽度限制及缩小变化 var MAX_WIDTH = 480; if ( expectWidth > MAX_WIDTH ) { expectHeight = expectHeight * MAX_WIDTH / expectWidth; expectWidth = MAX_WIDTH; } if ( Orientation == 6 ) { // 顺时针90° ctx.save(); ctx.translate(expectWidth/2, expectHeight/2); ctx.rotate(90 * Math.PI / 180.0); ctx.drawImage(image, -expectHeight/2, -expectWidth/2, expectHeight, expectWidth); } else if ( Orientation == 8 ) { // 逆时针90° ctx.save(); ctx.translate(expectWidth/2, expectHeight/2); ctx.rotate(270 * Math.PI / 180.0); ctx.drawImage(image, -expectHeight/2, -expectWidth/2, expectHeight, expectWidth); ctx.restore(); } else if ( Orientation == 3 ) { // 180° ctx.save(); ctx.translate(expectWidth/2, expectHeight/2); ctx.rotate(Math.PI); ctx.drawImage(image, -expectWidth/2, -expectHeight/2, expectWidth, expectHeight); ctx.restore(); } else { ctx.drawImage(image, 0, 0, expectWidth, expectHeight); } // *) 获取旋转和压缩后的图片数据. var imagedata = canvas.toDataURL( "image/png" ); } |
整个流程相对, 还是比较简单的.
这边讲讲canvas的drawImage, 如何去绘制旋转图片的思路的.
1). 先把原点移至canvas的中点, translate
2). 进行旋转操作, rorate
3). 进行绘制, 此时canvas的绘制区域坐标范围为(-w/2, -h/2, w/2, h/2), 需要注意下.
图片上传:
图片压缩和旋转后, 图片的数据上传, 又是怎么实现的呢?
一种思路, 就是上文提到的:
1 | var imageData = canvas.toDataURL( "image/png" ); |
其本质的工作, 就是把图片的二进制数据, 转换为了base64编码后的数据, 这样就可以通过普通的Ajax来上传了, 也就实现了文件的异步上传工作.
php和nginx文章的相关列表:
• nginx服务配置---php服务接入
• nginx+tomcat集群配置(1)---根目录设定和多后端分发配置
• nginx+tomcat集群配置(2)---静态和动态资源的分离
• nginx+tomcat集群配置(3)---获取真实客户端IP
• nginx+tomcat集群配置(4)--rewrite规则和多应用根目录设定思路
后记:
应该说有幸吧, 通过这个简单的例子, 追踪定位, 到最后的问题解决, 其实学到了很多. 以前确实犹如井底之蛙, 以为很多问题, 只是一时疏忽而已, 在小的问题, 在背后也有大学问, 感谢每一天, 无论晴雨, 都是美好的一天.
个人站点&公众号:
个人微信公众号: 小木的智慧屋
个人游戏作品集站点(尚在建设中...): www.mmxfgame.com
posted on 2016-05-26 11:53 mumuxinfei 阅读(2339) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构