当前位置: 首页 > news >正文

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的相关代码:

<input type="file" accept="image/*" capture="camera" οnchange="selectFileImage(this);">

  *) exif的使用代码片段:

function selectFileImage(file) {
  var Orientation = null;
  //获取照片方向角属性,用户旋转控制
  EXIF.getData(file, function() {
    EXIF.getAllTags(this);
    Orientation = EXIF.getTag(this, 'Orientation');
  });
}

  这边变量file为, input控件选择具体图片文件后得到的对象, Orientation即是旋转信息.
  Orientation的取值和含义:

旋转角度
参数
1
顺时针90°
6
逆时针90°
8
180°
3

 

颠倒和缩放:
  在页面端, 需要处理是的限制大小尺寸, 比如设置一个最大宽度值(限宽不限高), 同时又要解决图片旋转问题.
  其思路是借助canvas重绘来实现, 1). 先确定旋转方向, 2). 图片尺寸缩小调整 3). 确定canvas大小, 4). 绘制过程.

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), 需要注意下.

 

图片上传:
  图片压缩和旋转后, 图片的数据上传, 又是怎么实现的呢?
  一种思路, 就是上文提到的:

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

 

相关文章:

  • 熊猫热土-环汶川50公里越野赛赛记
  • HDFS学习之FileSystem
  • DDD实践问题之 - 关于论坛的帖子回复统计信息的更新的思考
  • HDU1230 火星A+B【进制】
  • tomcat下server.xml配置详解
  • BZOJ 2599 Race(树分治)
  • BI报表帮你轻松自如完成数据分析、业务数据探查
  • 第二次冲刺第二天
  • LintCode_389 判断数独是否合法
  • Android开发常见错误及技巧
  • 使用Markdown写文档
  • 普通pc安装懒人版的mac 10.10系统安装
  • mybatis-generator 基类继承
  • Spring MVC学习总结(5)——SpringMVC项目关于安全的一些配置与实现方式
  • 神奇的Android Studio Template
  • [ JavaScript ] 数据结构与算法 —— 链表
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • Android框架之Volley
  • C++入门教程(10):for 语句
  • DOM的那些事
  • ESLint简单操作
  • EventListener原理
  • java正则表式的使用
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • php中curl和soap方式请求服务超时问题
  • React中的“虫洞”——Context
  • Spark学习笔记之相关记录
  • use Google search engine
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 精彩代码 vue.js
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 通过npm或yarn自动生成vue组件
  • 赢得Docker挑战最佳实践
  • 主流的CSS水平和垂直居中技术大全
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • ​渐进式Web应用PWA的未来
  • ###项目技术发展史
  • (11)MSP430F5529 定时器B
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (9)YOLO-Pose:使用对象关键点相似性损失增强多人姿态估计的增强版YOLO
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (分布式缓存)Redis分片集群
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (三分钟)速览传统边缘检测算子
  • (学习日记)2024.01.19
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .net 4.0发布后不能正常显示图片问题
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .Net Web项目创建比较不错的参考文章
  • .net遍历html中全部的中文,ASP.NET中遍历页面的所有button控件