应业务要求,要把使用canvas截取的app每一屏的图片拼接在一起。图片的地址存放在一个log文件中。
先了解一下drawImage() 方法:
drawImage() 方法在画布上绘制图像、画布或视频。
drawImage() 方法也能够绘制图像的某些部分,以及/或者增加或减少图像的尺寸。
JavaScript 语法 1
在画布上定位图像:
context.drawImage(img,x,y);
JavaScript 语法 2
在画布上定位图像,并规定图像的宽度和高度:
context.drawImage(img,x,y,width,height);
JavaScript 语法 3
剪切图像,并在画布上定位被剪切的部分:
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
参数值
参数 | 描述 |
---|---|
img | 规定要使用的图像、画布或视频。 |
sx | 可选。开始剪切的 x 坐标位置。 |
sy | 可选。开始剪切的 y 坐标位置。 |
swidth | 可选。被剪切图像的宽度。 |
sheight | 可选。被剪切图像的高度。 |
x | 在画布上放置图像的 x 坐标位置。 |
y | 在画布上放置图像的 y 坐标位置。 |
width | 可选。要使用的图像的宽度。(伸展或缩小图像) |
height | 可选。要使用的图像的高度。(伸展或缩小图像) |
log文件:
var jsonData = [{
"data": [{
"url": "./db/cache/a.jpg"
}, {
"url": "./db/cache/b.jpg"
}, {
"url": "./db/cache/c.jpg"
}]
}]
接下来就是根据log.js中的图片地址,把这些图片拼接在一起
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>拼长图</title>
</head>
<body>
<div id="image-container"></div>
<img src="" alt="" id="avatar">
<script language="javascript" type="text/javascript" src="../../assets/js/jquery-2.0.3.min.js"></script>
<script language="javascript" type="text/javascript" src="./db/log/log.js"></script>
<script>
// 拿到图片地址
var dataList = []
jsonData.forEach(item => {
item.data.forEach(ele => {
dataList.push(ele)
})
})
// 绘制图片
function draw(dataList, x, y) {
var canvas = document.createElement("canvas");
canvas.width = x
var context = canvas.getContext("2d");
const encoderOptions = 1
let length = dataList.length
dataList.forEach((ele, i) => {
canvas.height = y * (i + 1);
var myImage = new Image();
myImage.crossOrigin = '';
myImage.src = ele.url; //你自己本地的图片或者在线图片
myImage.onload = () => {
context.drawImage(myImage, 0, y * i,480,640);
var base64 = canvas.toDataURL("image/png", encoderOptions); //"image/png" 这里注意一下
var img = document.getElementById('avatar');
const imageDiv = document.getElementById('image-container')
imageDiv.innerHTML =
`<div><a download href=${base64} style="list-style: none;text-decoration: none;color:#000">点击下载长图</a><br><br><img src=${base64}></div>`
}
})
}
this.draw(dataList, 480, 640)
</script>
</body>
</html>
最后的效果:
这个是通过读取log文件中存放的图片地址进行拼接的,如果有的小伙伴想要自己在input框中上传图片,并把图片拼接起来可以试试下面这段代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>拼长图</title>
</head>
<body>
<input id="upload-input" type="file" accept="image/*" multiple="multiple" style="display: none;">
<label for="upload-input">点击选择图片</label>
<div id="image-container"></div>
<script>
// 拼出来的图片的宽度
const width = 300
// 拼出来的图片的质量,0-1之间,越大质量越好
const encoderOptions =1
const uploadInput = document.getElementById('upload-input')
const imageDiv = document.getElementById('image-container')
uploadInput.addEventListener('change', event => {
const files = Array.from(event.target.files)
filesToInstances(files, instances => {
drawImages(instances, finalImageUrl => {
imageDiv.innerHTML = `<div><a download href=${finalImageUrl}>点击下载</a><br><img src=${finalImageUrl}></div>`
})
})
})
// 根据图片文件拿到图片实例
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) => {
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/jpeg', encoderOptions))
}
</script>
</body>
</html>
效果和上面图片拼接出来的一样,大家各取所需。input框上传图片并拼接参考:https://segmentfault.com/a/1190000011684333
有不对的地方欢迎指出,一起进步呀~