vue.js3: 图片的反色/灰度(黑白)/褐色并保存(vue@3.2.37)


一,js代码:

<template>
  <div style="position:relative;">
    <div style="width: 700px;margin: auto;">
      <h1>反色/灰度/褐色</h1>
      <div><input type="file" accept="image/*" @change="open" />
        <button @click="reset">重置</button>
      </div>
      <div style="display: flex;margin-top: 5px;"><span style="width:40px;">反色</span>
        <el-slider style="margin-left:10px;width:640px;" v-model="slideInvert" :min="0" :max="100"  show-input /></div>
      <div style="display: flex;margin-top: 5px;"><span style="width:40px;">灰度</span>
        <el-slider style="margin-left:10px;width:640px;" v-model="slideGray" :min="0" :max="100"  show-input /></div>
      <div style="display: flex;margin-top: 5px;"><span style="width:40px;">褐色</span>
        <el-slider style="margin-left:10px;width:640px;" v-model="slideSepia" :min="0" :max="100"  show-input /></div>
      
      <div :style="{marginLeft:imgLeft+'px',width:imgDispWidth+'px',height:imgDispHeight+'px',overflow:'hidden',marginTop:'10px'}">

      <div :width="imgWidth" :height="imgHeight" 
           :style="{transform: 'scale('+scale+')',transformOrigin: originLeft+'% 0% 0px'}">
      <svg id="mysvg" :width="imgWidth" :height="imgHeight" class="mysvg"
           :style="{transformOrigin: '50% 50% 0px',filter: 'invert('+valueInvert+') grayscale('+valueGray+') sepia('+valueSepia+')'}">
        <defs>
        </defs>
        <image id="img" :xlink:href="imgSrc" :width="imgWidth" :height="imgHeight" />
      </svg>
      </div>
      </div>

      <div style="margin-top: 10px;"><button @click="save">保存</button></div>

    </div>
  </div>
</template>

<script>
import {computed, ref} from "vue";

export default {
  name: "grayScale",
  setup() {
    //反色的滑杆值
    const slideInvert = ref(0);
    //灰度的滑杆值
    const slideGray = ref(0);
    //褐色的滑杆值
    const slideSepia = ref(0);

    //反色的值
    let valueInvert = computed( ()=> {
          return slideInvert.value / 100;
        }
    );
    //灰度的值
    let valueGray = computed( ()=> {
          return slideGray.value / 100;
        }
    );
    //褐色的值
    let valueSepia = computed( ()=> {
          return slideSepia.value / 100;
        }
    );

    //保存修改
    const save = () => {
      var str = document.getElementById("mysvg")
      let serializer = new XMLSerializer()
      var source = serializer.serializeToString(str);
      source = '<?xml version = "1.0" standalone = "no"?>/r/n' + source;
      var url = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(source);

      var canvas = document.createElement("canvas")
      canvas.width = imgWidth.value;
      canvas.height = imgHeight.value;
      var context = canvas.getContext("2d");

      var image = new Image;
      image.src = url;
      image.crossOrigin = '';
      image.onload = function () {
        context.drawImage(image, 0, 0,imgWidth.value,imgHeight.value);
        downJpgByCanvas(canvas);
      }
    }

    //下载图片
    const downJpgByCanvas = (canvas) => {
      var oA = document.createElement("a");
      let time = timeFormat();
      oA.download = "img_"+time+'.jpg';// 设置下载的文件名,默认是'下载'
      oA.href = canvas.toDataURL("image/jpeg");
      document.body.appendChild(oA);
      oA.click();
      oA.remove(); // 下载之后把创建的元素删除
    }

    //重置
    const reset = () => {
      slideInvert.value = 0;
      slideGray.value = 0;
      slideSepia.value = 0;
    };

    //补0
    const add0 = (m) => {
      return m<10?'0'+m:m
    }
    //格式化时间
    const timeFormat = ()=>{
      var time = new Date();
      var y = time.getFullYear();
      var m = time.getMonth()+1;
      var d = time.getDate();
      var h = time.getHours();
      var mm = time.getMinutes();
      var s = time.getSeconds();
      let res = y+add0(m)+add0(d)+add0(h)+add0(mm)+add0(s);
      return res;
    }

    //图片的src
    const imgSrc = ref("");
    //图片的原宽高
    const imgWidth = ref(0);
    const imgHeight = ref(0);
    //图片的显示宽高
    const imgDispWidth = ref(0);
    const imgDispHeight = ref(0);
    //svg显示时缩放的比例
    const scale = ref(0);
    //图片的left
    const imgLeft = ref(0);
    //svg显示位置的left:
    const originLeft = ref(0);
    //读取图片的信息
    const open = (e) => {
      let file = e.target.files[0];
      let reader = new FileReader();
      reader.readAsDataURL(file);
      //文件加载成功
      reader.onload = () =>{
        //重置
        reset();
        //显示图片
        imgSrc.value = reader.result;
        //得到宽高
        let img = new Image();
        img.src= reader.result;
        img.onload = () => {
          //保存原始宽高
          imgWidth.value = img.width;
          imgHeight.value = img.height;

          if (img.width >= img.height) {
            imgDispWidth.value = 700;
            imgDispHeight.value = (700 * img.height) / img.width;
            scale.value = 700 / img.width;
            imgLeft.value = 0;
          } else {
            imgDispHeight.value = 500;
            imgDispWidth.value = (500 * img.width) / img.height;
            scale.value = 500 / img.height;
            imgLeft.value = (700-imgDispWidth.value) / 2;
          }

          if (scale.value > 1) {
            originLeft.value = 50;
          } else {
            originLeft.value = 0;
          }
        }
      }
    }

    return {
      valueInvert,
      valueGray,
      valueSepia,
      slideInvert,
      slideGray,
      slideSepia,

      save,
      open,
      imgSrc,
      imgWidth,
      imgHeight,
      imgDispWidth,
      imgDispHeight,
      imgLeft,
      originLeft,
      scale,
      reset,
    }
  }
}
</script>

<style scoped>
.mysvg {
  background: rgba(255, 255, 255, 0);
  border-radius: 0px;
  transform: scale(1, 1);
}
</style>

说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

         对应的源码可以访问这里获取: https://github.com/liuhongdi/
         或: https://gitee.com/liuhongdi

说明:作者:刘宏缔 邮箱: 371125307@qq.com

二,测试效果

vue.js3: 图片的反色/灰度(黑白)/褐色并保存(vue@3.2.37)

 vue.js3: 图片的反色/灰度(黑白)/褐色并保存(vue@3.2.37)

vue.js3: 图片的反色/灰度(黑白)/褐色并保存(vue@3.2.37)

三,查看vue框架的版本

liuhongdi@lhdpc:/data/vue/pdf/image2pdf$ npm list vue
image2pdf@0.1.0 /data/vue/pdf/image2pdf
├─┬ @vue/cli-plugin-babel@5.0.8
│ └─┬ @vue/babel-preset-app@5.0.8
│   ├─┬ @vue/babel-preset-jsx@1.3.0
│   │ └── vue@3.2.37 deduped invalid: "2.x" from node_modules/@vue/babel-preset-jsx
│   └── vue@3.2.37 deduped
└─┬ vue@3.2.37
  └─┬ @vue/server-renderer@3.2.37
    └── vue@3.2.37 deduped

 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/288491.html

(0)
上一篇 2022年9月9日
下一篇 2022年9月9日

相关推荐

发表回复

登录后才能评论