小程序h5图片压缩问题(紧急求取,老板只给24小时,夺命call)
发布于 7 年前 作者 chaozou 6835 次浏览 来自 问答

请教各位大神,本人有个项目在小程序中运行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);

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

10 回复

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

给你个提示:

lossless compression

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

 为什么不修改图片质量呢

 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);
                    }
                }

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

跳点取像素点,在canvas 重绘

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

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

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

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

回到顶部