web 图片合成 图片拖动合成

web 图片合成

1. 展示

在这里插入图片描述

2.原理

浏览器上一张图片作为背景,一张图片进行拖动。
然后点击下面按钮合成后,生成一张新的图片

  1. 前端通过拖动确定图片的位置
  2. 后端通过图片位置将两张图片合并成一张新的图片
  3. 前端通过下载,得到一张新的图片

3.前端

  1. 实现原理:将一张图片最为背景,另一张图片进行绝对定位,然后通过获取鼠标位置来确定图片的left 和top位置
  2. 背景图片有大有小,所以可以设定一个固定的宽和高,然后和实际的大小计算得到一个比值,然后传个后端
  3. 其他的就是元素位置的计算

代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图片合成</title>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script th:src="@{/imgView/index.js}"></script>
    <style>
        body{
            margin: 0;
        }
        .source{
            width: 60%;
            margin-left: 20%;
        }
        img{
            object-fit: contain;
        }
        .submit-btn{
            width: 200px;
            height: 70px;
        }
    </style>
</head>
<body>
    <div class="source" id="source">
        <img id="sourceImg">
    </div>
<div style="width: 100%;text-align: center">
    <button id="submit-btn" class="submit-btn">合成</button>
</div>
</body>
</html>
var w_width,w_height,ratio
var result_x,result_y
window.onload = function () {
    w_width = window.innerWidth
    w_height = window.innerHeight
    setSource()
        .then(setTarget)

    submitResult()

}

function setTarget(){
    http('/img/action/getSrc', {'name': 'b.png'})
        .then(function (res) {
            var ret = res.data.data
            var imgSrc = 'data:image/jpeg;base64,' + ret.baseStr
            var img = document.createElement('img')
            img.setAttribute('src',imgSrc)
            img.style.width = (ret.width * ratio) + 'px'
            console.log('target width=',ret.width,(ret.width * ratio))
            img.style.position = 'absolute'
            img.style.top = '0px'
            img.style.left = (w_width * 0.2) + 'px'
            var source = document.getElementById('source')
            source.append(img)
            var moveFlag = false
            img.onmousedown = function (ev){
                moveFlag = !moveFlag
                result_x = ev.clientX - w_width * 0.2
                result_y = ev.clientY

                if(moveFlag){
                    img.style.opacity = 0.8
                    img.style.filter = 'alpha(opacity=80)'
                }else{
                    img.style.opacity = 1
                    img.style.filter = 'alpha(opacity=100)'
                }
            }

            source.onmousemove = function (ev){
                if(!moveFlag){
                    return
                }
                var imgTop = ev.clientY - ret.height/2 * ratio
                var imgLeft = ev.clientX - ret.width/ 2* ratio
                var imgWidth2 = ret.width/ 2* ratio
                var imgHeight2 = ret.height/2 * ratio
                if(imgLeft < w_width * 0.2){
                    imgLeft = w_width * 0.2
                }
                if(imgLeft +  imgWidth2*2 > w_width * 0.8){
                    imgLeft = w_width * 0.8 - imgWidth2*2
                }

                if(imgTop  <= 0){
                    imgTop = 0
                }

                if(imgTop + imgHeight2*2 > source.offsetHeight){
                    imgTop = source.offsetHeight - ret.height * ratio
                }

                img.style.top =   imgTop + 'px'
                img.style.left = imgLeft + 'px'
            }




        })
}


function setSource(){
    return new Promise(function(resolve, reject){
        http('/img/action/getSrc', {'name': 'bg.jpg'})
            .then(function (res) {
                var ret = res.data.data
                var imgSrc = 'data:image/jpeg;base64,' + ret.baseStr
                var img = document.getElementById('sourceImg')
                img.setAttribute('src',imgSrc)
                img.style.width = (w_width*0.6) + 'px'
                ratio = (w_width*0.6)/ret.width
                console.log('w_width=',w_width,'w_width*0.6=',w_width*0.6,'width=',ret.width,'ratio=',ratio)
                //img.style.height = ret.height + 'px'
                resolve()
            })
    })
}

function http(path, data) {
    return axios.post(path, data)
}

function submitResult(){
    document.getElementById('submit-btn')
        .onclick = function(){
        http('/img/action/submit', {'result_x':result_x,'result_y':result_y,'ratio':ratio,sourceImg:'bg.jpg',targetImg:'b.png'})
            .then(function(){

            })
    }
}

4.后端

  1. 获取到位置进行合并,这里使用的是java 相对比较简单
      double x = body.getDouble("result_x");
        double y = body.getDouble("result_y");
        double ratio = body.getDouble("ratio");
        String sourceImg = body.getString("sourceImg");
        String targetImg = body.getString("targetImg");

        BufferedImage source = ImageIO.read(getFile(sourceImg));
        BufferedImage target = ImageIO.read(getFile(targetImg));
        Graphics2D graphics2D = source.createGraphics();
        int width = (int) (x / ratio);
        int height = (int) (y / ratio);
        int tarWidth = target.getWidth();
        int tarHeight = target.getHeight();
        int start_x = width - tarWidth / 2;
        int start_y = height - tarHeight / 2;
        if (start_x < 0) {
            start_x = 0;
        }
        if (start_y < 0) {
            start_y = 0;
        }
        graphics2D.drawImage(target, start_x, start_y, tarWidth, tarHeight, null);
        graphics2D.dispose();
        ByteOutputStream out = new ByteOutputStream();
        ImageIO.write(source, "png", out);
        byte[] data = out.getBytes();
        out.close();
        Files.write(Paths.get("testImg.png"), data);

5.最后

最后就是做好的图片传给前端就好了

有需要源码的可以私信我,或留下邮箱

上一篇:Nginx可视化管理工具 Nginx UI


下一篇:深入探讨指令调优的局限性