vue处理图片添加水印

elementui把上传的图片转为base64

<template>
    <div> 
         <el-upload
            class="upload-demo"
            drag
            action=""
            :on-change="getFile"
            :auto-upload="false"
            :on-exceed="handleExceed"
            :file-list="fileList"
            :limit="1"
           :on-remove="handremove"
            list-type="picture" >
            <i class="el-icon-upload"></i>
             <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
            <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过2M</div>
          </el-upload>
      <img :src="img" alt="">
    </div>
</template>

<script>
     export default {
        data() {
          return {
              fileList: [],
        img:''
            }
        },
        methods: {
            //自定义一个方法,用来把图片内容转为base64格式
            getBase64(file) {
                  return new Promise(function(resolve, reject) {
                    let reader = new FileReader();
                    let imgResult = "";
                    reader.readAsDataURL(file);
                    reader.onload = function() {
                      imgResult = reader.result;
                    };
                    reader.onerror = function(error) {
                      reject(error);
                    };
                    reader.onloadend = function() {
                      resolve(imgResult);
                    };
                  });
                },
            //获取文件的内容
            getFile(file, fileList) {
        
          //限制用户上传格式 和大小
        //截取上传文件后缀名判断格式
        var testmsg=file.name.substring(file.name.lastIndexOf('.')+1)
        const isJPG = testmsg === 'jpg';
        const isPNG = testmsg === 'png';
        //计算上传文件大小
        const isLt2M = file.size / 1024 / 1024 < 2;
                
        if (!isJPG && !isPNG) {
          this.$message.error('上传头像图片只能是 JPG或PNG 格式!');
          this.fileList=[]
          return
        }
        
        if (!isLt2M) {
          this.$message.error('上传头像图片大小不能超过 2MB!');
          this.fileList=[]
          return
        }
         
        
                //用file.raw就可以获取文件的内容了。
                console.log(file.raw)
                //调用方法
                 this.getBase64(file.raw).then(res => {
                       console.log(res)
             this.img=res
                       });
                },
          //提示限制的个数 :limit="1"  drag 拖拽
          handleExceed(files, fileList) {
                  this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
                },
   
    //文件列表移除文件时的钩子
    handremove(file, fileList){
      this.img=''
    },
        }
  }
</script>

图片压缩转码 在转回file

<template>
    <div>
        <!-- 预览压缩之后的文件图片 -->
        <div>
            <img src="" id="img">  
        </div>
        <input type="file"   @change="change" />
    </div>
</template>

<script>
    export default{
        methods:{
            // 监听上传文件的变化
            change(e){
                let fileObj=e.target.files[0]  //获取文件类型
                console.log(fileObj) //原文件类型 大小
                //调用方法
                this.compressFile(fileObj,function(files){
                    console.log(files)
                })  
            },
            //压缩图片
            compressFile(file,callback){
                let fileObj=file; //文件类型
                let reader=new FileReader();//创建读取文件对象
                reader.readAsDataURL(fileObj)//调用方法转base64
                reader.onload=function(e){ //文件读取成功完成的触发
                    let image=new Image(); //新建一个img标签(还没嵌入DOM节点)
                    image.src=e.target.result;//读取结果 下载图片
                    image.onload=function(){ //绑定事件 下载完成
                        let canvas=document.createElement('canvas');//新建canvas
                        let context=canvas.getContext('2d');//获取画笔对象
                        let imageWidth=image.width/2 //压缩后图片的大小  对半压缩
                        let imageHeight=image.height/2
                        let data=''
                        canvas.width=imageWidth  //画布的宽高
                        canvas.height=imageHeight
                        //使用drawImage重新设置img标签中的图片大小,实现压缩,
                        context.drawImage(image,0,0,imageWidth,imageHeight) //绘制图像
                        data=canvas.toDataURL('image/jpeg'); //输出压缩后的base64
                        //将压缩后的图片显示到页面上的img标签  预览图片
                        document.getElementById('img').src=data;
                        //重新转回file文件格式
                        let arr=data.split(',')
                        let mime=arr[0].match(/:(.*?);/)[1]
                        let bstr=atob(arr[1])
                        let n=bstr.length
                        let u8arr=new Uint8Array(n);
                        while (n--){
                            u8arr[n]=bstr.charCodeAt(n);
                        }
                        let files=new File([new Blob([u8arr],{type:mime})],'test.jpeg',{type:'image/jpeg'})
                        callback(files) //回调
                    }
                }
            }
        },
    }
</script>

给上传的照片添加水印

<template>
    <div>
        <!-- 预览压缩之后的文件图片 -->
        <el-upload
          class="upload-demo"
          drag
          :before-upload="allFileBeforeUpload"
          list-type="picture"
          action="/api/upload"
          multiple>
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
          <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
        </el-upload>
    </div>
</template>

<script>
    export default{
        methods:{
            // 上传前
                  allFileBeforeUpload(file){
                    var fileType = file.type
                    //console.log(fileType)   //image/jpeg
                     //includes() 方法用于判断字符串是否包含指定的子字符串
                    if(fileType.includes('image')){
                      var uid = file.uid
                     return new Promise((resolve, reject) => {
                      this.transformFile(file).then(res => {
                       console.log(res)
                        //装换之后 file的uid丢失
                          res.uid = uid
                          resolve(res)
                      }).catch(error => {
                          reject(error)
                      })
                    }) 
                    }
                  },
        //转换文件  添加水印
              transformFile(file) {
                  //promise执行多步操作非常好用,这个过程是有一定的顺序的,你必须保证上一步完成,才能顺利进行下一步。
                  //有两个参数 resolve同意的意思  reject拒绝的意思
                return new Promise(resolve => {
                  const reader = new FileReader();//创建读取文件对象
                  reader.readAsDataURL(file);//调用方法转base64
                  reader.onload = () => { //文件读取成功完成的触发
                    const canvas = document.createElement('canvas'); //新建canvas 画布
                    const img = document.createElement('img'); //新建一个img标签
                    img.src = reader.result; //读取结果 下载图片
                    img.onload = () => { //绑定事件 下载完成
                      const ctx = canvas.getContext('2d');//获取画笔对象
                      let width = img.width; //图片的宽高
                      let height = img.height;
                      canvas.width = width;//画布的宽高
                      canvas.height = height;
                      ctx.drawImage(img, 0, 0, width, height);//绘制图像 图片大小没变
                      ctx.fillStyle = '#ffffff';// 设置填充字号和字体,样式
                      ctx.textBaseline = 'middle';
                      // 设置右对齐
                      ctx.textAlign = 'right'
                      ctx.rotate(0*Math.PI/180);//旋转画笔 角度
                      ctx.globalAlpha = 0.4; //透明度
                      if(2000000 < width * height && width * height < 4000000){
                        ctx.font="80px Arial";
                      }else if(width * height > 4000000){
                        ctx.font="100px Arial";  // 设置文本大小和字体
                        ctx.fillText('仅 供 测 试 使 用', width/1.5, height/8); //绘制填充文本(str,x,y) 填充字体的 坐标
                        ctx.fillText('仅 供 测 试 使 用', width-20, height-20);// 在指定位置绘制文字,这里指定距离右下角20坐标的地方
                      }else{
                        ctx.font="30px Arial";
                      }
                      ctx.fillText('仅 供 测 试 使 用', width/8, height/8);
                      ctx.fillText('仅 供 测 试 使 用', width-20, height-20);// 在指定位置绘制文字,这里指定距离右下角20坐标的地方
                      /* canvas.toBlob(resolve); */
                      //压缩图片质量 范围 0~1
                      let dataUrl = canvas.toDataURL("image/jpeg", 0.5) //输出压缩后的base64
                      //执行下一步操作  将裁剪base64的图片转换为file文件
                      resolve(this.dataURLtoFile(dataUrl, file.name))
                    };
                  };
                });
              },
            // 将裁剪base64的图片转换为file文件
                  dataURLtoFile(dataurl, filename) {
                      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 File([u8arr], filename, {type: mime});
                  },
        }
    }
</script>

你可能感兴趣的:(vue.js,javascript,前端)