一,js代码:
<template>
<div>
<div style="width:800px;margin: auto;display: flex;flex-direction: column;">
<div>请选择上传图片:
<input type="file" id="back" ref="backfile" accept="image/*" @change="handleFile" /></div>
<div id="imgContainer" <br>style="position: relative;margin-left:150px;margin-top:10px;width:500px;height:500px;overflow: hidden;background: lightgray;" >
<img id="img" :src="imgSrc" style="" />
</div>
<div style="margin-left:150px;">
<template v-for='(items, index) in imgList' :key="index">
<div style="font-size:0;">
<template v-for='(itemOne, indexOne) in items' :key="indexOne">
<img :src="itemOne" style="width:200px;display: block;float:left;margin-left: 5px;margin-top: 5px;" />
<!--{{itemOne}}-->
</template>
</div>
</template>
</div>
<div id="dpiBtn" style="display: none;">
<input type="button" value="分割图片" @click="split" />
<input type="button" value="打包下载图片" @click="downZip" style="margin-left: 20px;" />
</div>
</div>
</div>
</template>
<script>
import {ref} from "vue";
export default {
name: "ImageSplit",
setup() {
//图片的原宽高
const imgWidth = ref(0);
const imgHeight = ref(0);
//图片内容
const imgSrc = ref("");
//选中的图片文件,保存在数组中
const imgFile = ref();
const roundMax = ref(0);
//选中图片后的处理
const handleFile = () => {
let filePaths = window.event.target.files;
//清空原有缩略图
if (filePaths.length === 0) {
//未选择,则返回
return
}
//把新选中的图片加入数组
imgFile.value = filePaths[0];
imgSrc.value = URL.createObjectURL(imgFile.value);
let reader = new FileReader();
reader.readAsDataURL(imgFile.value);
reader.onload = () =>{
//显示图片
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) {
roundMax.value = img.height/2;
let rate = 500 / img.width;
let left = (500-img.width) / 2;
let top = (500 -img.height) / 2;
let styleStr = 'display: inline-block;position:absolute;transform:scale('+rate+');left:'+left+'px;display: block;top:'+top+'px;';
document.getElementById('img').style = styleStr;
} else {
roundMax.value = img.width/2;
let rate = 500 / img.height;
let left = (500-img.width) / 2;
let top = (500 -img.height) / 2;
let styleStr = 'display: inline-block;position:absolute;transform:scale('+rate+');left:'+left+'px;display: block;top:'+top+'px;';
document.getElementById('img').style = styleStr
}
//显示btn
document.getElementById('dpiBtn').style.display="";
}
}
}
const imgList = ref([]);
//行数
const rows = ref(2);
//列数
const columns = ref(2);
//拆分图片
const split = () => {
var canvas = document.createElement("canvas");
canvas.width = imgWidth.value;
canvas.height = imgHeight.value;
let ctx = canvas.getContext('2d');
let img = document.getElementById('img');
ctx.drawImage(img, 0, 0, imgWidth.value, imgHeight.value);
let list = getList(ctx);
imgList.value = list;
console.log(imgList.value);
}
//得到切割后的图片列表
const getList = (ctx) => {
let destWidth = ctx.canvas.width / columns.value;
let destHeight = ctx.canvas.height / rows.value;
let list = [];
for (let i=0;i<rows.value;i++) {
let listOne = [];
for (let k=0;k<columns.value;k++) {
console.log("i:"+i+";k:"+k);
let url = getPart(ctx,k*destWidth,i*destHeight,destWidth,destHeight);
listOne.push(url);
}
list.push(listOne);
}
return list;
}
//得到canvas的指定部分
const getPart = (ctx,x,y,w,h) => {
let canvas = document.createElement("canvas");
canvas.width = w;
canvas.height = h;
console.log("x:"+x+";y:"+y+";w:"+w+";h:"+h);
let data = ctx.getImageData(x,y,w,h);
let context = canvas.getContext("2d");
context.putImageData(data,0,0);
return canvas.toDataURL("image/png",1);
}
return {
handleFile,
imgSrc,
imgList,
rows,
columns,
split,
}
}
}
</script>
<style scoped>
</style>
二,测试效果
原图:
2×2
3×3
说明:刘宏缔的架构森林—专注it技术的博客,
网址:https://imgtouch.com
本文: https://blog.imgtouch.com/index.php/2023/06/03/vue-js3-fen-ge-tu-pian-wei-si-gong-ge-jiu-gong-ge-deng-xing/
代码: https://github.com/liuhongdi/ 或 https://gitee.com/liuhongdi
说明:作者:刘宏缔 邮箱: 371125307@qq.com
三,查看vue框架的版本:
root@lhdpc:/data/vue/imgtouch# npm list vue imgtouch@0.1.0 /data/vue/imgtouch ├─┬ @vue/cli-plugin-babel@5.0.6 │ └─┬ @vue/babel-preset-app@5.0.6 │ └── vue@3.2.37 deduped └─┬ vue@3.2.37 └─┬ @vue/server-renderer@3.2.37 └── vue@3.2.37 deduped