图片转换base64或blob(对图片旋转进行校正)并在页面显示

背景:

最近项目需求需要使用到base64的图片格式,需要对用户上传的图片压缩处理,所以打算自己动手写一个图片选择、压缩、转换的方法(需要压缩到指定大小)。

思路:

  1. 调用 FileReader的 reader.readAsDataURL(img)方法, reader.readAsDataURL 读取图片信息。
  2. 在reader.onload的事件中,新建Image对象,并将reader.result的值赋给img.src,在img.onload中判断尺寸大小,并且根据 exif-js 判断图片角度是否需要校正,再通过canvs 将图片压缩至合适尺寸。

既然思路已经有了,那么接下来就可以动手去尝试操作了…

  1. 第一步先引入项目所需要的依赖文件,因为写的时候我是本地直接原生js做的所以使用的 cdn的方式引入。

    
    
  2. 创建项目,编写基础代码

    
    图片压缩转换base64
  3. 开始写获取图片、处理图片方法 (大概的思路以及逻辑如下)

    1. 首先获取到按钮以及 input 并且给按钮添加点击事件,同时触发 input 的点击事件达到选择文件的目的。
    2. 定义 imageCompression 文件压缩方法,方法需要接收三个参数( file 文件 、处理完成的 callBack 回调、 params {绘制 canvas 需要的参数、图片压缩的大小、返回文件的格式} )
    3. 因为需要使用到 FileReader 方法 所以在处理之前先判断浏览器是否支持 不支持就直接返回文件并打印错误信息,如果浏览器支持,那就使用 FileReader 读取传入的文件
    4. 在 FileReader.onload 方法中进行 img 创建,
    5. 监听 img.onload 事件 在图片加载完成后进行 canvas 绘制
    6. 绘制完之后我们就需要根据 orientation 值判断图片是否需要旋转
    7. 在将图片旋转正常后,使用递归将突破压缩至设置的大小
    function imageCompression(file,callBack = () => {},params = {width: 1000,LIMIT_SIZE: 0.5 * 1024 * 2014,isBase64: true,}) {let compressCount = 0;const { width, LIMIT_SIZE, isBase64 } = params;const orientation = EXIF.getTag(file, "Orientation") || 1;// 图片压缩出错函数const errorFn = (e) => {console.error("图片压缩出问题了", e);callBack(file);};if (!window.FileReader) {console.error("浏览器不支持 window.FileReader 方法哦");callBack(file);} else {try {let reader = new FileReader();reader.readAsDataURL(file);reader.onload = function () {let img = new Image();img.src = reader.result;img.onload = function () {try {const canvas = document.createElement("canvas");const context = canvas.getContext("2d");const canvasWidth = width;const canvasHeight = canvasWidth / (img.width / img.height);canvas.width = canvasWidth;canvas.height = canvasHeight;let angle = 0;switch (orientation) {case 1:break;case 6:// 逆时针90°,需要顺时针旋转90°angle = (90 * Math.PI) / 180;canvas.width = canvasHeight;canvas.height = canvasWidth;context.rotate(angle);context.translate(0, -canvas.width);break;case 8:// 顺时针90°,需要顺时针旋转270°angle = (270 * Math.PI) / 180;canvas.width = canvasHeight;canvas.height = canvasWidth;context.rotate(angle);context.translate(-canvas.height, 0);break;case 3:// 顺时针180°,需要顺时针旋转180°angle = (180 * Math.PI) / 180;canvas.width = canvasWidth;canvas.height = canvasHeight;context.rotate(angle);context.translate(-canvas.width, -canvas.height);break;default:break;}context.drawImage(img, 0, 0, canvasWidth, canvasHeight);context.setTransform(1, 0, 0, 1, 0, 0);canvas.toBlob((blob) => {if (blob.size > LIMIT_SIZE) {compressCount += 1;imageCompression(blob, callBack);} else {compressCount = 0;if (isBase64) {callBack(canvas.toDataURL( 'image/png', 1 ));} else {callBack(blob);}}},"image/jpeg",0.9 - compressCount * 0.1);} catch (error) {errorFn(error);}};};reader.onerror = (error) => {errorFn(error);};} catch (error) {errorFn(error);}}}
    
  4. 示例代码,复制至页面可以直接查看效果

    
    图片压缩转换base64
  5. 效果图

    效果图片


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部