首页 > 其他分享 >项目实践后的图片压缩完整使用过程【vue3+js】

项目实践后的图片压缩完整使用过程【vue3+js】

时间:2023-04-04 15:11:24浏览次数:48  
标签:canvas const 压缩 base64 js file vue3 image

van-uploader + 图片压缩 + 图片base64转成file

 compressImage.js

const ACCEPT = ['image/jpg', 'image/png', 'image/jpeg']
const MAXSIZE = 1024 * 1024 * 2;
const MAXTIP = "4"

// 压缩算法函数
/* 
1.首先拿到了base64的图片字符串 
2.创建一个image对象,获得原始图片的宽度和高度
3.对原始图片的宽度和高度进行压缩达到符合条件(第一次压缩-从尺寸压缩)
4.调用canvasAPI进行绘制新的图片
5.绘制成功之后调用canvasAPI进行绘制(canvasAPI支持压缩-二次压缩-从质量压缩)
6.得到压缩后的base64
 */
function compress(base64Image, file, callback) {
    let maxW = 1024;
    let maxH = 1024;
    const image = new Image() // 创建image对象 相当于创建a标签
    image.addEventListener('load', function (e) {
        // image加载完成后就会触发 也就是src加载后
        let radio; // 压缩比例
        let needCompress = false; // 是否需要压缩
        if (file.file.size > MAXSIZE) {
            needCompress = true;
            // 获得压缩宽高过后的大小(保证等比例缩放)
            radio = image.naturalWidth / maxW
            maxH = image.naturalHeight / radio
        }
        // 不需要压缩
        if (!needCompress) {
            maxW = image.naturalWidth;
            maxH = image.naturalHeight;
        }
        // 第一次压缩完成
        // 接下来使用canvas进行质量压缩
        const canvas = document.createElement('canvas')
        canvas.height = maxH;
        canvas.width = maxW;
        canvas.setAttribute("id", "_compress_")
        // visibility hidden 需要创建的canvas隐藏 而不是不渲染DOM
        canvas.style.visibility = 'hidden'
        document.body.appendChild(canvas)

        const ctx = canvas.getContext('2d')
        ctx.clearRect(0, 0, maxW, maxH)
        ctx.drawImage(image, 0, 0, maxW, maxH)
        // 接来下就是压缩canvas 通过API将canvas输出成base64格式

        const compressImage = canvas.toDataURL('image/jpeg', 0.8) // 通常压缩是0.8-0.9
        callback && callback(compressImage); // 压缩完成进行后台传输逻辑
        canvas.remove()

    })
    image.src = base64Image;
    // document.body.appendChild(image) // 挂载

}

function imgbase64Tofile(base64, fileName) {
    // 将base64按照 , 进行分割 将前缀  与后续内容分隔开
    let data = base64.split(',');
    // 利用正则表达式 从前缀中获取图片的类型信息(image/png、image/jpeg、image/webp等)
    let type = data[0].match(/:(.*?);/)[1];
    // 从图片的类型信息中 获取具体的文件格式后缀(png、jpeg、webp)
    let suffix = type.split('/')[1];
    // 使用atob()对base64数据进行解码  结果是一个文件数据流 以字符串的格式输出
    const bstr = window.atob(data[1]);
    // 获取解码结果字符串的长度
    let n = bstr.length
    // 根据解码结果字符串的长度创建一个等长的整形数字数组
    // 但在创建时 所有元素初始值都为 0
    const u8arr = new Uint8Array(n)
    // 将整形数组的每个元素填充为解码结果字符串对应位置字符的UTF-16 编码单元
    while (n--) {
        // charCodeAt():获取给定索引处字符对应的 UTF-16 代码单元
        u8arr[n] = bstr.charCodeAt(n)
    }
    // 利用构造函数创建File文件对象
    // new File(bits, name, options)
    const time = (new Date()).valueOf()
    const file = new File([u8arr], `${fileName}${time}.${suffix}`, {
        type: type
    })
    // 将File文件对象返回给方法的调用者
    return file;
}

export default { compress, imgbase64Tofile }

main.js

import compressImage from './utils/compressImage';
app.config.globalProperties.$compressImage = compressImage;
上传页面
 <van-uploader
                            :before-read="beforeRead"
                            :after-read="afterRead1"
                            :before-delete="beforeDelete1"
                            accept="image/*"
                            :max-count="1"
                            v-model="fileList1"
                            :max-size="maxSize"
                            image-fit="contain"
                            @oversize="onOversize" >
                            <div class="img_box upload_box1"></div>
</van-uploader>
<script setup>
   import { ref, reactive,getCurrentInstance} from 'vue'    const { proxy } = getCurrentInstance()
const fileList1 = ref([]);
const maxSize = ref(1024 *1024 * 4)
const beforeRead = (file)=> {// 上传身份证图片前的图片格式校验
  if (file.type !== 'image/jpeg' && file.type !== 'imagepng' && file.type !== 'image/jpg') {
        Toast.fail('请上传jpg或jpeg或png的格式图片');
    return false;
  } else {
    return true;
  }
}
const afterRead1 = (file)=> {
    // 调用身份证图文识别接口
    proxy.$compressImage.compress(file.content,file,(base64)=>{
        proxy.$compressImage.imgbase64Tofile(base64,'idcardfront')
    })
}
const onOversize = (file) => {//上传图片过大提示
  Toast('文件大小不能超过4M');
};
// 删除上传的文件
const beforeDelete1= (file)=>{
    fileList1.value = []
    delete idcardMsg.ID_Cardname
    delete idcardMsg.ID_Idno
}

</script>

 

  

    

标签:canvas,const,压缩,base64,js,file,vue3,image
From: https://www.cnblogs.com/meiyanstar/p/17286448.html

相关文章

  • js实现文字左右轮播
    <!DOCTYPEhtml><html><head><metacharset="utf-8"><title></title><styletype="text/css">.textDiv{position:relative;......
  • 如何编写高质量的 JS 函数(2) -- 命名/注释/鲁棒篇
    vivo互联网技术微信公众号 作者:杨昆上篇《如何编写高质量的JS函数(1)--敲山震虎篇》介绍了函数的执行机制,此篇将会从函数的命名、注释和鲁棒性方面,阐述如何编写高质量的JS函数。(一)函数命名一、目前前端的函数命名存在什么问题从上图可以知道,命名和缓存是计算机科学中的......
  • Wiki.js配置LDAP认证
    安装好wikijs之后,可以进行进一步的详细配置.这里介绍LDAP认证的配置.在管理->身份验证->添加策略->选择LDAP/AD,如下:接下来进行详细配置:显示名称:按需修改是否启用:是LDAPURL:格式为:ldap://serverhost:389orldaps://serverhost:636Admin......
  • Wiki.js配置LDAP认证
    安装好wikijs之后,可以进行进一步的详细配置.这里介绍LDAP认证的配置.在管理->身份验证->添加策略->选择LDAP/AD,如下:接下来进行详细配置:显示名称:按需修改是否启用:是LDAPURL:格式为:ldap://serverhost:389orldaps://serverhost:636Admin......
  • docker打包、压缩镜像并载入
    1、打包镜像#docker打包所有镜像dockersave$(dockerimages--format'{{.Repository}}:{{.Tag}}')-oallimages.tar#打包指定镜像,使用grep过滤dockersave$(dockerimages--format'{{.Repository}}:{{.Tag}}'|grepopenjdk)-oopenjdk.tar 2、打包并压......
  • Three.js 进阶之旅:全景漫游-初阶移动相机版
    Three.js进阶之旅:全景漫游-初阶移动相机版 声明:本文涉及图文和模型素材仅用于个人学习、研究和欣赏,请勿二次修改、非法传播、转载、出版、商用、及进行其他获利行为。摘要3D 全景技术可以实现日常生活中的很多功能需求,比如地图的街景全景模式、数字展厅、在线看房、社交......
  • 老代码考古,seajs为什么能够和CMD一样同步模式的方式使用require()方法
    我们知道在服务端的node可以同步block的方式加载别的js库文件,在服务端使用会block的require()函数来加载,就是所谓的CMD、CommonJS规范。而在浏览器端里的js则因为网络延迟等各种因素,不能使用同步block方式加载js库,而是异步回调callback加载的方式,也就是所谓的AMD模块规范。那么......
  • JS中 filter()方法的使用
    一、作用filter用于对数组进行过滤。它创建一个新数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。注意:filter()不会对空数组进行检测、不会改变原始数组二、语法Array.filter(function(currentValue,indedx,arr),thisValue)  其中,函数function为必须,数组......
  • JS 字符串补0
    padStart用另一个字符串填充当前字符串(如果需要的话,会重复多次),以便产生的字符串达到给定的长度。从当前字符串的左侧开始填充。语法padStart(targetLength)padStart(targetLength,padString)参数targetLength当前字符串需要填充到的目标长度。如果这个数值小于当前字......
  • js 递归遍历树形结构数据,返回新的数组
    工作中,我们经常会遇到这样的情况:后端返回的数组,只需要取name、value生成新的数组,或者是将某个属性名修改,生成新的数组。递归是一种常见的解决问题的方法,即把问题逐渐简单化。“递归”的基本思想是:自己调用自己。实例如下handleDg(arrs,that){arrs.map((item,index)......