收藏
回答

小程序h5图片压缩问题(紧急求取,老板只给24小时,夺命call)

请教各位大神,本人有个项目在小程序中运行h5页面,需要使用h5进行图片压缩,目前大量用户遇到了安卓上压缩后的图片是黑图(设置底色为白色),ios上传的是白图,部分oppo手机的图片为上半张图正常,下半张图类似绿色蒙层,源码如下:

let canvas = document.createElement("canvas");

let ctx = canvas.getContext('2d');

let initSize = img.src.length;

let width = img.width;

let height = img.height;

//如果图片大于四百万像素,计算压缩比并将大小压至400万以下

let ratio;

if ((ratio = width * height / 4000000) > 1) {

ratio = Math.sqrt(ratio);

width /= ratio;

height /= ratio;

} else {

ratio = 1;

}

canvas.width = width;

canvas.height = height;

//        铺底色

ctx.fillStyle = "#fff";

ctx.fillRect(0, 0, canvas.width, canvas.height);

//如果图片像素大于100万则使用瓦片绘制

let count;

if ((count = width * height / 1000000) > 1 && Util.isIOS()) {

count = Math.ceil(Math.sqrt(count)); //计算要分成多少块瓦片

//            计算每块瓦片的宽和高

var nw = ~~(width / count);

var nh = ~~(height / count);

//    瓦片canvas

for (var i = 0; i < count; i++) {

for (var j = 0; j < count; j++) {

let tCanvas = document.createElement("canvas");

let tCtx = tCanvas.getContext("2d");

tCanvas.width = nw;

tCanvas.height = nh;

tCtx.drawImage(img, Math.ceil(i * nw * ratio), Math.ceil(j * nh * ratio), Math.ceil(nw * ratio), Math.ceil(nh * ratio), 0, 0, nw, nh);

ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);

}

}

} else {

ctx.drawImage(img, 0, 0, width, height);

}

let data = canvas.toDataURL('image/jpeg', 0.7);


跪谢各位大神,急急急!!!


回答关注问题邀请回答
收藏

26 个回答

  • 拾忆
    拾忆
    2018-10-24

    还有7个小时,围观案发现场~

    2018-10-24
    有用 6
    回复
  • 走出五千年
    走出五千年
    2018-10-24

    让服务器处理啊,前端处理个毛线~~~~~

    2018-10-24
    有用 1
    回复 5
    • kliwin
      kliwin
      2018-10-24

      历史遗留原因,不知道前人出于什么目的

      2018-10-24
      回复
    • 小茶
      小茶
      2018-10-24

      上传大图到服务器需要长时间。所以需要前端处理。但你就是想实现图片的压缩么?你这个写法。真是诡异。这么多for效率高不到哪去。

      把你的原图和期望效果发上来。

      2018-10-24
      回复
    • 小茶
      小茶
      2018-10-24回复kliwin

      上传大图到服务器需要长时间。所以需要前端处理。但你就是想实现图片的压缩么?你这个写法。真是诡异。这么多for效率高不到哪去。

      把你的原图和期望效果发上来。


      2018-10-24
      回复
    • kliwin
      kliwin
      2018-10-24回复小茶

      分块压缩是因为ios上的问题,非ios是没有for循环的,原图就是一般的手机拍出来10m左右的照片就可以了,选完第一张压缩,不等结果,立刻选第二张,试个两三次基本都能看到效果了

      2018-10-24
      回复
    • 小茶
      小茶
      2018-10-24回复kliwin

      1、如果都使用分块。每次只做一块看看会不会有问题。

      2、如果有问题说明你的方法有问题需要改近。

      3、如果只做1块没问题。都正常的话。如果一个图分成9块做9个按钮触发一下压缩。

      4、如果上面的方式也没问题。说明你需要并用到HTML5 Web Workers了。但如果简单想测试的话可以使用setTimeout...


      以上通过问题分析。不知道实际业务是否如此。但我始终感觉你把一个压缩成小图这个事搞复杂了。

      2018-10-24
      回复
  • English Wang
    English Wang
    2018-10-23

    能不能用类似html2canvas的插件截图来搞个伪压缩,光截图片区域

    2018-10-23
    有用 1
    回复 1
    • kliwin
      kliwin
      2018-10-24

      这个方法没试过,我试下

      2018-10-24
      回复
  • 长征🌻
    长征🌻
    2018-10-24

     为什么不修改图片质量呢

     function dealImage(path, obj, callback){                    var img = new Image();
                        img.src = path;
                        img.onload = function(){                        var that = this;                        // 默认按比例压缩
                            var w = that.width,
                                h = that.height,
                                scale = w / h;
                                w = obj.width || w;
                                h = obj.height || (w / scale);                        var quality = 0.7;        // 默认图片质量为0.7                        
                            //生成canvas
                            var canvas = document.createElement('canvas');                        var ctx = canvas.getContext('2d');                        
                            // 创建属性节点
                            var anw = document.createAttribute("width");
                            anw.nodeValue = w;                        var anh = document.createAttribute("height");
                            anh.nodeValue = h;
                            canvas.setAttributeNode(anw);
                            canvas.setAttributeNode(anh);
                                  
                            ctx.drawImage(that, 0, 0, w, h);                        // 图像质量
                            if(obj.quality && obj.quality <= 1 && obj.quality > 0){
                                quality = obj.quality;
                            }                        // quality值越小,所绘制出的图像越模糊
                            var base64 = canvas.toDataURL('image/jpeg', quality );                        // 回调函数返回base64的值                        callback(base64);
                        }
                    }


    2018-10-24
    有用
    回复
  • 🐈 大爷
    🐈 大爷
    2018-10-24

    建议在导出图片的时候做一下延时处理试试,很多情况下是因为安卓机来不及绘制图片然后就导出来了给整的

    2018-10-24
    有用
    回复
  • 猫5号
    猫5号
    2018-10-24

    客户端一般不做图片处理,或者只做简单处理,原因是服务端可以保留更好质素的图片,以便以后在碎片化的使用场景下可以更灵活处理

    2018-10-24
    有用
    回复
  • 差不多先生
    差不多先生
    2018-10-24

    https://github.com/think2011/localResizeIMG可以用这个库试试,我h5里面压缩图片都是用的这个,没什么毛病

    2018-10-24
    有用
    回复
  • vingo
    vingo
    2018-10-24

    跳点取像素点,在canvas 重绘

    2018-10-24
    有用
    回复
  • 龙
    2018-10-24

    给你个提示:

    lossless compression

    2018-10-24
    有用
    回复
  • Davin
    Davin
    2018-10-24

    你这个是上传时的图片压缩么?如果是的话可以用 canvas 配合 base64,另外,如果是手机拍摄的照片,在 iOS 和部分三星机型上有图片旋转的问题,需要借助 exif.js 来修正旋转角度。或者像楼上们说的,把锅甩给后端 :dogged:

    2018-10-24
    有用
    回复

正在加载...

登录 后发表内容