前言:
  前几天, 写了一篇关于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" onchange="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

IOS照片颠倒分析及移动/页面端的处理策略和思路的更多相关文章

  1. IOS照片颠倒分析及PHP服务端的处理

    前言: 因朋友的PHP小项目, 而去帮忙解决了一个小问题, 现在来总结概括一下. 也不知道大家在使用和开发的过程中有没有遇到类似的场景, IPhone手机上传照片后, 发现图片方向颠倒了, 甚至各种姿 ...

  2. iOS app内存分析套路

    iOS app内存分析套路 Xcode下查看app内存使用情况有2中方法: Navigator导航栏中的Debug navigator中的Memory Instruments 一.Debug navi ...

  3. 基于APNs最新HTTP/2接口实现iOS的高性能消息推送(服务端篇)

    1.前言 本文要分享的消息推送指的是当iOS端APP被关闭或者处于后台时,还能收到消息/信息/指令的能力. 这种在APP处于后台或关闭情况下的消息推送能力,通常在以下场景下非常有用: 1)IM即时通讯 ...

  4. 解决ios下的微信打开的页面背景音乐无法自动播放

    后面的项目发现,还有两个坑,需要注意下: ·本文的解决方案的核心是利用了 微信/易信 在ready的时候会有个 WeixinJSBridgeReady/YixinJSBridgeReady事件,通过监 ...

  5. iOS crash日志分析

    iOS crash日志分析 一. 寻找crash文件:手机崩溃后的ips或者crash文件(ips文件可以直接修改成crash文件,直接改后缀名就可以了),这里说下如何拿到crash文件 1. 把运行 ...

  6. iOS的内存分析和内存管理

    iOS的内存分析和内存管理 [内存管理]一直是iOS开发中的一个重点. 本文就带你从内存分析开始一步步了解内存的占用情况,从真实的情况中领悟真正项目开发过程中的内存的使用情况. 注:本文默认你熟悉 M ...

  7. iOS 崩溃日志分析(个人总结,最实用)

    iOS 崩溃日志分析(个人总结,最实用) 要分析奔溃日志需要三个文件:crash日志,symbolicatecrash分析工具,.dSYM符号集 0. 在桌面创建一个crash文件夹 1. 需要Xco ...

  8. 转: HTTP Live Streaming直播(iOS直播)技术分析与实现

    http://www.cnblogs.com/haibindev/archive/2013/01/30/2880764.html HTTP Live Streaming直播(iOS直播)技术分析与实现 ...

  9. amazeui页面分析之登录页面

    amazeui页面分析之登录页面 一.总结 1.tpl命名空间:tpl命名空间的样式都是从app.css里面来的,app.css用用来移动网站开发的样式 2.表单样式:am-form到am-form- ...

随机推荐

  1. checkbox

    $(document).ready(function(){ var page_id = {/$page_id/}; var location_id = {/$location_id/}; var lo ...

  2. pthreads 2.0.10 test

    CentOS 6.3 cd /root mkdir pthreads //get php-5.6 and install zts version wget cn2.php.net/get/php-5. ...

  3. Android中ActionBar的使用

    简介 从Android3.0开始(targetSdkVersion或者minSdkVersion为11或者更高),ActionBar被包括在了所有主题为Theme.holo(或者子类)的主题当中. 使 ...

  4. 在QtCreator 2.1.0 下使用opencv231库加载图片并显示

    在.pro中库连接如上图,具体规则正在学习,注意debug下连接*d.lib.release下链接.lib.没有d的. 如果出现imread不可以加载图片,cvloadImage却可以,则是上面说的连 ...

  5. HOJ 1004: Prime Palindromes

    问题:输入两个整数 a 和 b (5 <= a < b <= 1,000,000,000),输出 [a, b] 内的所有回文质数. 最简单的暴力解法是依次遍历 [a, b] 范围内的 ...

  6. C++ 为什么拷贝构造函数参数必须为引用?赋值构造函数参数也必须为引用吗?

    之前写拷贝构造函数的时候,以为参数为引用,不为值传递,仅仅是为了减少一次内存拷贝.然而今天看到一篇文章发现自己对拷贝构造的参数理解有误. 参数为引用,不为值传递是为了防止拷贝构造函数的无限递归,最终导 ...

  7. shared_ptr:资源管理利器

    如果你还在使用传统的C++,那么可以肯定堆内存的管理让你头痛过!在传统的C++领域,堆内存管理上我们能借用的现成工具就只有auto_ptr.但是很不幸用auto_ptr管理堆内存简直就是个错误.aut ...

  8. [置顶] Android 2016新技术

    版权声明:分享技术,传播快乐.如果本博客对你有帮助,请在我的博客首页为我打赏吧! 2016你需要了解Android有以下新兴的技术与框架,有些也许还不成熟,但是你应该去了解下,也许就是未来的方向. K ...

  9. Directory 与 DirectoryInfo 的区别

    Directory 与 DirectoryInfo 这两个能够实现大多数相同的功能.区别可分为两点:一.静态与实例调用前者必须被实例化后才能使用,而后者则只提供了静态的方法.如果多次使用某个对象一般使 ...

  10. iOS 3D Touch 适配开发

    3D Touch的主要应用 文档给出的应用介绍主要有两块: 1.A user can now press your Home screen icon to immediately access fun ...