image

您所在的位置:网站首页 jpg白底怎么转换成png image

image

2024-01-22 04:29| 来源: 网络整理| 查看: 265

首先说一下,压缩主要是通过减低清晰度和缩小图片宽高进行的。

使用这里不讲,请看官方结束: https://www.npmjs.com/package/image-conversion

1.问题分析

由于项目需要压缩图片上传oss,一开始使用image-conversion库,但是发现某写png格式图片透明背景压缩后会变成黑色,看了源码,其实问题就出现在canvas转base64的方法上

/** * 将一个Canvas对象转变为一个dataURL字符串 * 该方法可以做压缩处理 * * @param {canvas} canvas * @param {number=} quality - 传入范围 0-1,表示图片压缩质量,默认0.92 * @param {string=} type - 确定转换后的图片类型,选项有 "image/png", "image/jpeg", "image/gif",默认"image/jpeg" * @returns {Promise(string)} Promise含有一个dataURL字符串参数 */ export default async function canvastoDataURL(canvas: HTMLCanvasElement, quality: number = 0.92, type: EImageType = EImageType.JPEG): Promise { if (!checkImageType(type)) { type = EImageType.JPEG; // 没有指定类型默认是jpeg } console.log('122 canvastoDataURL',type) return canvas.toDataURL(type, quality); };

可以看到不指定类型的话默认是使用image/jpeg格式转的,但是jpeg格式不能没有底色, 所以默认会填充黑色

2.解决思路

(1) 设置type和width 一开始想到的是官方设置提供配置参数 type, 设置成’image/png’ 在这里插入图片描述 但是问题来了,设置了这个确实不会出现黑底的情况了, 但是压缩效果又没了, 原因就是我们设置了 image/png 格式后, 那么cavans转base646就是按照png格式转,但png格式不管怎么转,转出的大小还是和原来一样,也就是png格式不支持设置清晰度,也即是这个方法中

canvas.toDataURL(type, quality);

这个quality参数是指定清晰度的,只支持jpeg格式,不支持png,png设置了没用

那么,不能通过设置清晰度方式进行压缩,那只能指定最大宽度了 所以,当我们要指定输出是png格式, 一定要指定宽度, 这样才会有压缩效果。 在这里插入图片描述 但是哦,这样又有问题了,这样size参数又没有效果了,没有达到预期想法,因为我想的是直接压缩到指定大小。

(2) 手动对透明图片进行转换 既然透明图片会出现黑底,那么我们压缩前通过canvas把图片底色变成 白色不就可以了吗 有两种思路,一种是通过读取图片数据,设置透明的部分颜色成白色,一种是直接将canvas画一层白色底色再绘画图片 第一种: 这个我没有封装,需要的自行封装

// 将canvas的透明背景设置成白色 var imageData = context.getImageData(0, 0, canvas.width, canvas.height); for(var i = 0; i imageData.data[i] = 255; imageData.data[i + 1] = 255; imageData.data[i + 2] = 255; imageData.data[i + 3] = 255; } } context.putImageData(imageData, 0, 0);

第二种:我现在用这个方式 关键代码:

// 在canvas绘制前填充白色背景 context.fillStyle = "#fff"; context.fillRect(0, 0, canvas.width, canvas.height); 完整的一个文件处理方法: pngToWhiteBg(file) { let read = new FileReader(); read.readAsDataURL(file); // 文件转base64 return new Promise((resolve, reject) => { read.onload = (e) => { let img = new Image(); img.src = e.target.result; img.onload = async () => { // 生成canvas let canvas = document.createElement("canvas"); let context = canvas.getContext("2d"); // 绘制图片到canvas上 canvas.width = img.width; canvas.height = img.height; // 在canvas绘制前填充白色背景 context.fillStyle = "#fff"; context.fillRect(0, 0, canvas.width, canvas.height); context.drawImage(img, 0, 0); let base64 = canvas.toDataURL(file["type"], 1); let newFile = this.dataUrlToFile(base64); resolve(newFile); }; }; }); }, dataUrlToFile(dataurl) { let arr = dataurl.split(","), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); },

因为我后面自己重新写了一份压缩代码工具,思路参考image-conversion库,所以我直接在image转canvas时进行透明图转白色底,工具库我写在公司的,暂时不贴出来。

总结

这里只讨论了png问题,入坑了,花了两天时间研究。。😂😂😂,不过,问题和思路大家都知道了,那就知道怎么做了,如果你不想重写一个工具,也不想通过设置type和width这种方式,那么,就用第二种哦, 现将图片转成白色底再调用image-conversion压缩方法。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3