前端使用canvas拼接多张图片

应业务要求,要把使用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

有不对的地方欢迎指出,一起进步呀~

 

 

 

 

 

 

 

 

 

 

 

  • 13
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
在UniApp中,你可以使用`<canvas>`标签来将多张图片拼接成一张图片,然后将其显示在`<image>`标签上。以下是一个简单的示例代码: 1. 首先,在你的页面中添加`<canvas>`和`<image>`标签: ```html <template> <view> <canvas id="myCanvas" style="display: none;"></canvas> <image :src="mergedImage" mode="aspectFit"></image> </view> </template> ``` 2. 在页面的`<script>`标签中,定义相关的数据和方法: ```javascript <script> export default { data() { return { mergedImage: '' // 用于显示拼接后的图片 } }, methods: { mergeImages() { const ctx = uni.createCanvasContext('myCanvas') // 加载图片 const image1 = uni.createImage() image1.src = 'path/to/image1.jpg' const image2 = uni.createImage() image2.src = 'path/to/image2.jpg' // 等待图片加载完成 Promise.all([this.loadImage(image1), this.loadImage(image2)]) .then(() => { // 绘制图片canvas上 ctx.drawImage(image1, 0, 0, 100, 100) // 假设图片大小为100x100 ctx.drawImage(image2, 100, 0, 100, 100) // 导出图片数据 ctx.toTempFilePath({ success: (res) => { this.mergedImage = res.tempFilePath // 将拼接后的图片路径赋值给mergedImage,用于显示在<image>标签上 } }) }) }, loadImage(image) { return new Promise((resolve, reject) => { image.onload = () => resolve() image.onerror = (e) => reject(e) }) } }, mounted() { this.mergeImages() } } </script> ``` 在上面的示例中,我们使用`uni.createCanvasContext`创建一个画布上下文,并调用`drawImage`方法将图片绘制到画布上。最后,我们使用`toTempFilePath`方法导出拼接后的图片,并将其路径赋值给`mergedImage`变量,以便在`<image>`标签中显示。 请注意替换示例代码中的图片路径为你自己的图片路径。另外,这只是一个简单的示例,你可以根据实际需求进行调整和扩展。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值