此处图片拼接分为横向拼接与纵向拼接,
成品网站:https://www.onlinedo.cn/img-concat
直接上代码:
html
<h1 class="mainIndex_title">图片拼接</h1>
<div class="imgConcat_main">
<div class="dragImgBox" id="dropZone">请拖拽本地图片文件到此处</div>
<div class="imgConcat_btn">
<span class="imgConcat_btn_choose">选择文件</span>
<input id="upload-input" type="file" accept="image/*" multiple="multiple" style="display: none;">
<!-- <span class="imgConcat_btn_concat">拼接</span> -->
<a class="imgConcat_btn_download" style="display: none;">下载</a>
<p class="imgConcat_type">
拼接方向:
<select name="" id="">
<option value="1">纵向</option>
<option value="2">横向</option>
</select>
</p>
</div>
<div id="image-container"></div>
</div>
js
// 拼出来的图片的宽度
let width = 10;
// 拼出来的图片的高度
let height = 10;
// 拼出来的图片的质量,0-1之间,越大质量越好
const encoderOptions = 1
//横向拼接还是纵向拼接 1为纵向,2为横向
let concatStyle = 1;
let imgArr = []; //图片集合
let downLoadBase64;
const uploadInput = document.getElementById('upload-input')
const imageDiv = document.getElementById('image-container')
// 下载
$(".imgConcat_btn_download").click(function(){
if(u_login!==1){
no_login();
}else{
downLoad(downLoadBase64,"concat_img.png")
}
})
$(".imgConcat_btn_choose").click(function(){
$("#upload-input").click();
})
$(".imgConcat_type select").change(function(){
concatStyle = $(this).find("option:selected").val();
imgConcat(imgArr)
})
uploadInput.addEventListener('change', event => {
const files = Array.from(event.target.files)
for(var i=0;i<files.length;i++){
imgArr.push(files[i]);
}
imgConcat(imgArr)
})
// 拖拽文件
var dp = document.querySelector( '#dropZone' );
document.addEventListener('drop', function (e) {
e.preventDefault()
}, false)
document.addEventListener('dragover', function (e) {
e.preventDefault()
}, false)
if(dp==null){
return;
}
dp.addEventListener('dragover', function(e) {
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = '导入';
});
dp.addEventListener("drop", function(e) {
e.stopPropagation();
e.preventDefault();
// var file = e.dataTransfer.files;
const dpfiles = Array.from(e.dataTransfer.files)
// var fileName = file[0].name;
// var fileType = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
// if(fileType!=="png"&&fileType!=="jpg"&&fileType!=="webp"&&fileType!=="gif"&&fileType!=="jpeg"&&fileType!=="bmp"){
// alert("请上传图片格式")
// }else{
for(var i=0;i<dpfiles.length;i++){
imgArr.push(dpfiles[i]);
}
imgConcat(imgArr)
// }
});
function imgConcat(files){
var file = files[0];
var img = new Image();
var reader = new FileReader();
if (file.type.indexOf("image") == 0) {
reader.readAsDataURL(file);
}
// 文件base64化,以便获知图片原始尺寸
reader.onload = function(e) {
img.src = e.target.result;
img.onload = function(){
width = this.width;
height = this.height;
}
}
filesToInstances(files, instances => {
drawImages(instances, finalImageUrl => {
imageDiv.innerHTML = `<div><img src=${finalImageUrl}></div>`
// $(".imgConcat_btn_download").attr("href",finalImageUrl);
downLoadBase64 = finalImageUrl
console.log(downLoadBase64)
// $(".imgConcat_btn_download").attr("download","concat_img");
$(".imgConcat_btn_download").show();
})
})
}
function dataURIToBlob(dataURI) {
var binStr = atob(dataURI.split(',')[1]),
len = binStr.length,
arr = new Uint8Array(len);
for (var i = 0; i < len; i++) {
arr[i] = binStr.charCodeAt(i);
}
return new Blob([arr])
}
function downLoad(base,name){
const bloburl = dataURIToBlob(base)
var downloadElement = document.createElement("a");
downloadElement.href = URL.createObjectURL(bloburl);
downloadElement.download = name; //下载后文件名
document.body.appendChild(downloadElement);
downloadElement.click(); //点击下载
document.body.removeChild(downloadElement); //下载完成移除元素
window.URL.revokeObjectURL(downloadElement.href); //释放掉blob对象
}
// 根据图片文件拿到图片实例
const filesToInstances = (files, callback) => {
const length = files.length
let instances = []
let finished = 0
files.forEach((file, index) => {
const reader = new FileReader()
// 把文件读为 dataUrl
reader.readAsDataURL(file)
reader.onload = e => {
const image = new Image()
image.src = e.target.result
image.onload = () => {
// 图片实例化成功后存起来
instances[index] = image
finished ++
if (finished === length) {
callback(instances)
}
}
}
})
}
// 拼图
const drawImages = (images, callback) => {
if(concatStyle==1){
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
})
callback(canvas.toDataURL('image/png', encoderOptions))
}else{
const widths = images.map(item => height /item.height * item.width);
const canvas = document.createElement('canvas')
canvas.height = height
canvas.width = widths.reduce((total, current) => total + current)
const context = canvas.getContext('2d')
let x = 0
images.forEach((item, index) => {
const width = widths[index]
context.drawImage(item, x, 0, width, height)
x += width
})
callback(canvas.toDataURL('image/png', encoderOptions))
}
}
主要处理方法就是:
// 根据图片文件拿到图片实例
const filesToInstances = (files, callback) => {
const length = files.length
let instances = []
let finished = 0
files.forEach((file, index) => {
const reader = new FileReader()
// 把文件读为 dataUrl
reader.readAsDataURL(file)
reader.onload = e => {
const image = new Image()
image.src = e.target.result
image.onload = () => {
// 图片实例化成功后存起来
instances[index] = image
finished ++
if (finished === length) {
callback(instances)
}
}
}
})
}
// 拼图
const drawImages = (images, callback) => {
if(concatStyle==1){ //此处是纵向拼图处理
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
})
callback(canvas.toDataURL('image/png', encoderOptions))
}else{ //此处是横向拼图处理
const widths = images.map(item => height /item.height * item.width);
const canvas = document.createElement('canvas')
canvas.height = height
canvas.width = widths.reduce((total, current) => total + current)
const context = canvas.getContext('2d')
let x = 0
images.forEach((item, index) => {
const width = widths[index]
context.drawImage(item, x, 0, width, height)
x += width
})
callback(canvas.toDataURL('image/png', encoderOptions))
}
}
调用:
filesToInstances(files, instances => {
drawImages(instances, finalImageUrl => {
imageDiv.innerHTML = `<div><img src=${finalImageUrl}></div>`
// $(".imgConcat_btn_download").attr("href",finalImageUrl);
downLoadBase64 = finalImageUrl
console.log(downLoadBase64)
// $(".imgConcat_btn_download").attr("download","concat_img");
$(".imgConcat_btn_download").show();
})
})
只需要把图片文件数组传入即可