首页 web前端 js教程 移动端图片上传旋转、压缩问题的解决方案

移动端图片上传旋转、压缩问题的解决方案

Oct 15, 2018 pm 05:20 PM
图片上传 图片压缩 图片旋转 移动端

本篇文章就给大家带来移动端图片上传旋转、压缩问题的解决方案。有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助。

前言

在手机上通过网页 input 标签拍照上传图片,有一些手机会出现图片旋转了90度d的问题,包括 iPhone 和个别三星手机。这些手机竖着拍的时候才会出现这种问题,横拍出来的照片就正常显示。因此,可以通过获取手机拍照角度来对照片进行旋转,从而解决这个问题。

Orientation

这个参数并不是所有图片都有的,不过手机拍出来的图片是带有这个参数的。

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

参数为 1 的时候显示正常,那么在这些横拍显示正常,即 Orientation = 1 的手机上,竖拍的参数为 6。

想要获取 Orientation 参数,可以通过 exif.js 库来操作。exif.js 功能很多,体积也很大,未压缩之前足足有 30k,这对手机页面加载来说是非常大影响的。而我只需要获取 Orientation 信息而已,所以我这里删减了 exif.js 库的一些代码,将代码缩小到几KB。

exif.js 获取 Orientation :

EXIF.getData(file, function() {  
    var Orientation = EXIF.getTag(this, 'Orientation');
});
登录后复制

file 则是 input 文件表单上传的文件。上传的文件经过 fileReader.readAsDataURL(file) 就可以实现预览图片了,这方面不清楚的可以查看:HTML5 进阶系列:文件上传下载

旋转

旋转需要用到 canvas 的 rotate() 方法。

ctx.rotate(angle);
登录后复制

rotate 方法的参数为旋转弧度。需要将角度转为弧度:degrees * Math.PI / 180

旋转的中心点默认都在 canvas 的起点,即 ( 0, 0 )。旋转的原理如下图:

 

旋转原理图  
   旋转原理图

旋转之后,如果从 ( 0, 0 ) 点进行 drawImage(),那么画出来的位置就是在左图中的旋转 90 度后的位置,不在可视区域呢。旋转之后,坐标轴也跟着旋转了,想要显示在可视区域呢,需要将 ( 0, 0 ) 点往 y 轴的反方向移 y 个单位,此时的起始点则为 ( 0, -y )。

同理,可以获得旋转 -90 度后的起始点为 ( -x, 0 ),旋转 180 度后的起始点为 ( -x, -y )。

压缩

手机拍出来的照片太大,而且使用 base64 编码的照片会比原照片大,那么上传的时候进行压缩就非常有必要的。现在的手机像素这么高,拍出来的照片宽高都有几千像素,用 canvas 来渲染这照片的速度会相对比较慢。

因此第一步需要先对上传照片的宽高做限制,判断宽度或高度是否超出哪个范围,则等比压缩其宽高。

var ratio = width / height;if(imgWidth > imgHeight && imgWidth > xx){
    imgWidth = xx;
    imgHeight = Math.ceil(xx / ratio);
}else if(imgWidth < imgHeight && imgHeight > yy){
    imgWidth = Math.ceil(yy * ratio);
    imgHeight = yy;
}
登录后复制

第二步就通过 canvas.toDataURL() 方法来压缩照片质量。

canvas.toDataURL("image/jpeg", 1);
登录后复制

toDataURL() 方法返回一个包含图片展示的 data URI 。使用两个参数,第一个参数为图片格式,默认为 image/png。第二个参数为压缩质量,在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。

总结

综合以上,例子的代码包括精简的exif.js库地址:file-demo

主要的核心代码如下:

<input type="file" id="files" ><img src="blank.gif" id="preview">
<script src="small-exif.js"></script>
<script>
    var ipt = document.getElementById('files'),
    img = document.getElementById('preview'),
    Orientation = null;
    ipt.onchange = function () {    
        var file = ipt.files[0],
    reader = new FileReader(),
    image = new Image();    
    if(file){
        EXIF.getData(file, function() {  
            Orientation = EXIF.getTag(this, 'Orientation');
        });
        reader.onload = function (ev) {
            image.src = ev.target.result;
            image.onload = function () {     
                var imgWidth = this.width,
                imgHeight = this.height;                // 控制上传图片的宽高 
                if(imgWidth > imgHeight && imgWidth > 750){
                    imgWidth = 750;
                    imgHeight = Math.ceil(750 * this.height / this.width);
                }else if(imgWidth < imgHeight && imgHeight > 1334){
                    imgWidth = Math.ceil(1334 * this.width / this.height);
                    imgHeight = 1334;
                }                
                var canvas = document.createElement("canvas"),
                ctx = canvas.getContext('2d');
                canvas.width = imgWidth;
                canvas.height = imgHeight; 
                if(Orientation && Orientation != 1){
                    switch(Orientation){                        
                    case 6: // 旋转90度
                        canvas.width = imgHeight;    
                        canvas.height = imgWidth;    
                        ctx.rotate(Math.PI / 2);                            
                        // (0,-imgHeight) 从旋转原理图那里获得的起始点
                        ctx.drawImage(this, 0, -imgHeight, imgWidth, imgHeight); 
                        break;                        
                     case 3: // 旋转180度
                        ctx.rotate(Math.PI);    
                        ctx.drawImage(this, -imgWidth, -imgHeight, imgWidth, imgHeight); 
                        break;                        
                     case 8: // 旋转-90度
                        canvas.width = imgHeight;
                        canvas.height = imgWidth; 
                        ctx.rotate(3 * Math.PI / 2);
                        ctx.drawImage(this, -imgWidth, 0, imgWidth, imgHeight);
                        break;
                    }
                }else{
                    ctx.drawImage(this, 0, 0, imgWidth, imgHeight);
                }
                img.src = canvas.toDataURL("image/jpeg", 0.8);
            }
        }
        reader.readAsDataURL(file);
    }
}</script>
登录后复制

总结:以上就是本篇文的全部内容,希望能对大家的学习有所帮助。更多相关教程请访问JavaScript视频教程jQuery视频教程bootstrap教程

以上是移动端图片上传旋转、压缩问题的解决方案的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

使用PHP保存远程图片时如何处理图片压缩? 使用PHP保存远程图片时如何处理图片压缩? Jul 15, 2023 pm 03:57 PM

使用PHP保存远程图片时如何处理图片压缩?在实际开发中,我们经常需要从网络上获取图片并保存到本地服务器。然而,有些远程图片可能太大,这就需要我们对它们进行压缩以减少存储空间和提高加载速度。PHP提供了一些功能强大的扩展来处理图片压缩,其中最常用的是GD库和Imagick库。GD库是一个流行的图像处理库,它提供了许多功能用于创建、编辑和保存图像。下面是一个使用

如何在Vue项目中使用移动端的手势操作 如何在Vue项目中使用移动端的手势操作 Oct 08, 2023 pm 07:33 PM

如何在Vue项目中使用移动端的手势操作随着移动设备的普及,越来越多的应用程序需要在移动端上提供更加友好的交互体验。而手势操作是移动设备上常见的交互方式之一,它能够让用户通过触摸屏幕来完成各种操作,如滑动、缩放等。在Vue项目中,我们可以通过第三方库来实现移动手势操作,下面将介绍如何在Vue项目中使用手势操作,并提供具体的代码示例。首先,我们需要引入一个专门用

解决Vue移动端多触点问题 解决Vue移动端多触点问题 Jun 30, 2023 pm 01:06 PM

在移动端开发中,我们经常会遇到多手指触控的问题。当用户在移动设备上使用多个手指滑动或缩放屏幕时,如何准确地识别和响应这些手势是一个重要的开发难题。在Vue开发中,我们可以采取一些措施来解决移动端多手指触控问题。一、使用vue-touch插件vue-touch是一个用于Vue的手势插件,它可以方便地处理移动端的多手指触控事件。我们可以通过npm安装vue-to

微信小程序实现图片上传功能 微信小程序实现图片上传功能 Nov 21, 2023 am 09:08 AM

微信小程序实现图片上传功能随着移动互联网的发展,微信小程序已经成为了人们生活中不可或缺的一部分。微信小程序不仅提供了丰富的应用场景,还支持开发者自定义功能,其中包括图片上传功能。本文将介绍如何在微信小程序中实现图片上传功能,并提供具体的代码示例。一、前期准备工作在开始编写代码之前,我们需要先下载并安装微信开发者工具,并注册成为微信开发者。同时,还需要了解微信

使用CakePHP框架实现图片上传和显示的步骤 使用CakePHP框架实现图片上传和显示的步骤 Jul 29, 2023 pm 04:21 PM

使用CakePHP框架实现图片上传和显示的步骤引言:在现代Web应用程序中,图片上传和显示是常见的功能需求。CakePHP框架为开发者提供了强大的功能和便捷的工具,使得实现图片上传和显示变得简单高效。本文将向您介绍如何使用CakePHP框架来实现图片上传和显示。步骤1:创建文件上传表单首先,我们需要在视图文件中创建一个表单,用于用户上传图片。以下是一个示例的

使用uniapp实现图片旋转功能 使用uniapp实现图片旋转功能 Nov 21, 2023 am 11:58 AM

使用uniapp实现图片旋转功能在移动应用开发中,经常遇到需要对图片进行旋转的场景,比如拍摄照片后需要进行调整角度,或者实现类似相机拍照后旋转的效果。本文将介绍如何使用uniapp框架实现图片旋转功能,并提供具体的代码示例。uniapp是一个基于Vue.js的跨平台开发框架,可以同时开发和发布iOS、Android、H5等多个平台的应用。在uniapp中实现

如何使用 JavaScript 实现图片旋转效果? 如何使用 JavaScript 实现图片旋转效果? Oct 20, 2023 pm 07:09 PM

如何使用JavaScript实现图片旋转效果?在网页开发中,经常会遇到需要实现图片旋转效果的场景,比如展示产品360°旋转图、实现图片轮播效果等。而JavaScript是一种强大的脚本语言,可以轻松地实现这种图片旋转效果。下面将介绍一种基于JavaScript实现图片旋转效果的方法,并提供具体的代码示例。首先,我们创建一个简单的HTML结

Vue技术开发中如何处理图片上传和压缩 Vue技术开发中如何处理图片上传和压缩 Oct 08, 2023 am 10:58 AM

Vue技术开发中如何处理图片上传和压缩在现代web应用中,图片上传是一个非常常见的需求。然而,由于网络传输和存储等方面的原因,直接上传原始的高分辨率图片可能会导致上传速度慢和存储空间的大量浪费。因此,对于图片的上传和压缩是非常重要的。在Vue技术开发中,我们可以使用一些现成的解决方案来处理图片上传和压缩。下面将介绍如何使用vue-upload-compone

See all articles