底部有demo
<template>
<div>
<div>
<input
type="file"
id="upFile"
@change="upFile($event)"
accept="image/*"
multiple="multiple"
style="display:none"
/>
<label for="upFile">
<span class="choosefile-btn">选择文件</span>
</label>
</div>
<div v-if="isPreview">
<img :src="imgurl" style="width:100%" />
</div>
</div>
</template>
<script>
export default {
data() {
return {
returnData: null,
imgurl: null,
};
},
props: {
isPreview: {
type: Boolean,
required: false,
default: true,
},
isAutoDownload: {
type: Boolean,
required: false,
default: false,
},
returnType: {
type: String,
required: false,
default: "base64",
validator: (value) => {
return ["base64", "file"].indexOf(value) !== -1;
},
},
widths: {
type: [String, Number],
required: false,
default: 1366,
},
quality: {
type: [String, Number],
required: false,
default: 0.618,
},
},
methods: {
base64ToBlob(code) {
let parts = code.split(";base64,");
let contentType = parts[0].split(":")[1];
let raw = window.atob(parts[1]);
let rawLength = raw.length;
let uInt8Array = new Uint8Array(rawLength);
for (let i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: contentType });
},
downloadFile(fileName, content) {
let aLink = document.createElement("a");
let blob = this.base64ToBlob(content); // new Blob([content]);
let evt = document.createEvent("HTMLEvents");
evt.initEvent("click", true, true); // initEvent 不加后两个参数在FF下会报错 事件类型,是否冒泡,是否阻止浏览器的默认行为
aLink.download = fileName;
aLink.href = URL.createObjectURL(blob);
aLink.dispatchEvent(
new MouseEvent("click", {
bubbles: true,
cancelable: true,
view: window,
})
); // 兼容火狐
},
upFile() {
if (this.returnType !== "file") {
const files = Array.from(event.target.files);
this.filesToInstances(files);
} else {
this.returnData = event.target.files;
this.returnRes();
}
},
filesToInstances(files) {
const length = files.length;
let instances = [];
let finished = 0;
files.forEach((file, index) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = (e) => {
const image = new Image();
image.src = e.target.result;
image.onload = () => {
// 图片实例化成功后存起来
instances[index] = image;
finished++;
if (finished === length) {
this.drawImages(instances);
}
};
};
});
},
drawImages(images) {
const width = this.widths;
const heights = images.map((item) => (width / item.width) * item.height);
const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = heights.reduce((total, current) => total + current);
const context = canvas.getContext("2d");
let y = 0;
images.forEach((item, index) => {
const height = heights[index];
context.drawImage(item, 0, y, width, height);
y += height;
});
const base64Url = canvas.toDataURL("image/jpeg", this.quality);
this.dealImages(base64Url);
if (this.returnType == "base64" && this.isAutoDownload) {
this.downloadFile(this.createFileName(), base64Url);
}
},
dealImages(url) {
this.imgurl = url;
this.returnData = url;
this.returnRes();
},
returnRes() {
this.$emit("getRes", this.returnData);
},
createFileName() {
return "图片拼接" + new Date().getTime();
},
},
};
</script>
<style>
.choosefile-btn {
display: inline-block;
padding: 10px 20px;
margin-top: 40px;
background: rgb(83, 170, 148);
border-radius: 8px;
color: #efeefe;
}
</style>
使用
<Splicing :isPreview="true" @getRes="getSpellData"/>
...
import Splicing from '@/components/Splicing.vue';
components: {
Splicing
},
getSpellData(e){
//返回的base64或者file结果
console.log(e);
},
react拼接图片代码:react拼接图片代码
angular拼接图片代码:angular拼接图片代码
demo地址(vue):demo