博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
H5拍照、预览、压缩、上传采坑记录
阅读量:6324 次
发布时间:2019-06-22

本文共 2696 字,大约阅读时间需要 8 分钟。

H5拍照、预览、压缩、上传采坑记录

公司项目前段时间需要实现手机拍照上传的功能,本来以为用和canvas可以很轻松的实现,结果发现问题多多,特此记录下来。

图片预览

在IOS上,竖着拍照片时,图片预览会旋转90°,横着拍照就没问题,我实验了一下,在IOS上,只有当图片的分辨率过大会出现这种情况。

最后实现图片预览效果借助了和,exif-js负责读取图片的EXIF信息,获取orientation信息,然后用megapix-image把图片数据渲染在img标签上,代码如下:

import EXIF from '../utils/exif';import MegaPixImage from '../utils/megapix-image';     /**     *      * @param file file对象     * @param resImg 预览IMG标签     * @returns {Promise}     */    renderPreviewImg(file, resImg) {        return new Promise(function (resolve, reject) {            EXIF.getData(file, _=> {                var allMetaData = EXIF.getAllTags(file);                var orientation = allMetaData.Orientation;                var mpImg = new MegaPixImage(file);                mpImg.render(resImg, {                    maxWidth: 1024,                    maxHeight: 1024,                    // quality: 0.6,                    orientation: orientation                }, resolve);            });        });    }

无刷新压缩上传

思路有两种:

  1. 用canvas的API,直接将base64文本传递过去

  2. 自己构造File对象,ajax上传

第一种方法需要服务器端做工作,而且上传数据量会增大4/3,因此此方法只作为回退方案。

第二种方法的原理是用Uint8Array来构造Blob,再使用formData上传。

这里要注意的是:ArrayBuffer不能被直接操作,必须通过typed array来存取,而且的构造函数也是typed array

完整代码如下:

this.renderPreviewImg(file, resImg)            .then(() => {                try {                    var binaryData = null;                    if (!Blob || !ArrayBuffer || !Uint8Array) {                        // alert(123);                        binaryData = file;//如果不支持压缩,直接上传原始图片                    } else {                        //组装二进制                        var base64Data = $(resImg).attr('src');                        var byteString = atob(base64Data.split(',')[1]);                        var ab = new ArrayBuffer(byteString.length);                        var ia = new Uint8Array(ab);                        for (var i = 0; i < byteString.length; i++) {                            ia[i] = byteString.charCodeAt(i);                        }                        binaryData = new Blob([ia], {                            "type": file.type                        });                    }                    this.setState({                        uploadProgress: 0                    });                    //组装formData                    var fd = new FormData();                    fd.append('file', binaryData, 'img.jpg');                    fd.append('token', uploadToken);                    console.log(fd);                    return this.uploadBinaryDataToQiniu(fd, this.uploadSuccess.bind(this), this.handleUploadProgress.bind(this))                } catch (e) {                    alert(e.message);                }            }).catch(function (e) {            console.log(e);        })

参考文章

转载地址:http://aqvaa.baihongyu.com/

你可能感兴趣的文章
linux设置和用户一样的密码,linux设置用户密码
查看>>
linux进程q是什么意思,Linux zombie进程
查看>>
linux 中重启 关机命令,Linux关机与重启命令详解
查看>>
linux 设置默认目录结构,Linux目录结构的介绍以及强制位、冒险位
查看>>
obs在linux下的离线安装教程,OBS手动安装插件教程
查看>>
linux ls 切换,Linux常用命令:路径切换的好基友:cd、ls、ll、pwd
查看>>
linux中awk命令是什么,Linux awk命令详解
查看>>
多个控制台登录linux,跨越控制台登录
查看>>
linux事件循环机制eventloop,理解EventLoop(事件循环)
查看>>
linux认虚拟带库驱动器,mhvtl1.5.4虚拟带库安装与配+NBU备份.doc
查看>>
逻辑运算符在c语言里的作用,C语言逻辑运算符有哪些
查看>>
amd做linux系统黑屏,计算机安装AMD官网显卡驱动后出现黑屏或Windows自动修复现象...
查看>>
vs2017 c语言大作业,用VS2017编写C语言的Hello World
查看>>
c语言在线电子词典的实验报告,电子词典系统设计实验报告.doc
查看>>
c语言 在一行中输出n个*号,在一行中输出N的位数及其各位数字之和,中间用一个空格隔开....
查看>>
C语言正方体的体积和表面积,五年级奥数.几何.长方体与正方体表面积与体积(C级).学生版...
查看>>
android的wifi开发,【移动开发】Android中WIFI开发总结(一)
查看>>
华为鸿蒙系统再公测,华为鸿蒙系统开启第二轮公测,新增七款机型!
查看>>
华为荣耀老机型鸿蒙,曝荣耀手机计划升级鸿蒙:共5款老机型 有你的吗?
查看>>
android手机 电话报名,国产第一个手机品牌开启Android 12尝鲜,你报名了吗?
查看>>