一,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框架的版本
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/tech/pnotes/288491.html