手机浏览器图像压缩上传

最近项目中遇到需要用手机拍照、浏览器上传的功能,刚开始以为问题很简单,仔细做才发现是一个大坑。主要问题有:

  1. 手机浏览器,特别是微信浏览器对图像内存的限制,实测2M的图像基本就无法显示了。
  2. 手机上网的速度问题,3G和WIFI情况下还勉强凑合,但是GPRS情况下,上传1M左右的图像基本会等上30秒。

由于上述两个原因,必须在浏览器端进行压缩处理。自然想到用HTML5 Canvas对图像进行重绘压缩。Canvas绘图是如此简单,基本思路是:

  1. 通过普通的文件上传框的onchange事件,获取图像路径
  2. 通过File API获取读取文件内容
  3. 用Canvas重绘

网上到处转载的是一篇译文,翻译自某洋人的文章,关键代码如下:

<!-- lang: js -->
    // 加载 图像文件(url路径)
function loadImage(src){
    // 过滤掉 非 image 类型的文件
    if(!src.type.match(/image.*/)){
        if(window.console){
            console.log("选择的文件类型不是图片: ", src.type);
        } else {
            window.confirm("只能选择图片文件");
        }
        return;
    }

    // 创建 FileReader 对象 并调用 render 函数来完成渲染.
    var reader = new FileReader();
    // 绑定load事件自动回调函数
    reader.onload = function(e){
        // 调用前面的 render 函数
        render(e.target.result);
    };
    // 读取文件内容
    reader.readAsDataURL(src);
};

    // 参数,最大高度
var MAX_HEIGHT = 100;
// 渲染
function render(src){
    // 创建一个 Image 对象
    var image = new Image();
    // 绑定 load 事件处理器,加载完成后执行
    image.onload = function(){
        // 获取 canvas DOM 对象
        var canvas = document.getElementById("myCanvas");
        // 如果高度超标
        if(image.height > MAX_HEIGHT) {
            // 宽度等比例缩放 *=
            image.width *= MAX_HEIGHT / image.height;
            image.height = MAX_HEIGHT;
        }
        // 获取 canvas的 2d 环境对象,
        // 可以理解Context是管理员,canvas是房子
        var ctx = canvas.getContext("2d");
        // canvas清屏
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        // 重置canvas宽高
        canvas.width = image.width;
        canvas.height = image.height;
        // 将图像绘制到canvas上
        ctx.drawImage(image, 0, 0, image.width, image.height);
        // !!! 注意,image 没有加入到 dom之中
    };
    // 设置src属性,浏览器会自动加载。
    // 记住必须先绑定事件,才能设置src属性,否则会出同步问题。
    image.src = src;
};

如果目标用户都是使用PC浏览器,那么到此问题解决。部署之后,我用iPhone 5S一测,傻眼,图片被压缩成什么鬼样子了!PC端用Chrome测试完全没问题啊,于是,开始百度,找到下面文章:HTML5+Canvas手机拍摄,本地压缩上传图片,案例实测报告
除了iPhone5s之外,还有别的问题,不过这篇文章的解决方案感觉像打补丁,不是很满意啊,于是继续搜索,终于找到号称兼容Android和IOS6的,而且都已经封装好了,很貌美都样子,那就是jQuery canvasResize

实测,5S没问题了。搞定!

在和服务端配合都时候发现一个奇怪都问题,希望有经验的朋友解答下:

我将压缩后的图像数据保存到一个隐藏的input里,post到服务器时发现$POST里这个值是空的,$REQUEST里倒是有,很奇怪,难道PHP有什么潜规则?

你可能感兴趣的:(html5,canvas,浏览器端压缩图像)