• 基于SVG,在网页中绘制自适应居中图片及图片检测框


    背景

    最近有个项目,需要在html页面绘制目标检测的结果。类似这种:
    在这里插入图片描述这种在客户端(用Qt、c#等编写的本地软件)上很好绘制,但是在前端比较麻烦。

    解决方案

    但是好在功夫不负有心人,经过查阅一番资料,成功将我在Qt上使用算法移植过来了。基本实现了效果,但是还存在一些内存释放的问题,后面再慢慢完善。

    DOCTYPE html> 
    <html> 
    
    <body onload="initImg()"> 
        <div style="color:green;  background-color: rgb(0, 0, 0); width: 600px; height: 400px;  margin-left:10px;"> 
            <svg id ="imgView"  width="600" height="400" xmlns="http://www.w3.org/2000/svg" > 
                
    
                <image id="myImg" href="" x="0" y="0" width="600" transform=''>image>
                
                
            svg> 
        div> 
    body> 
    
    <script>
        function initImg() 
        {
    
        var image = new Image(); //创建一个image对象
        var path = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F2020-04-22%2F5ea002e78724a.jpg&refer=http%3A%2F%2Fpic1.win4000.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664357262&t=355f6b6bce479068239b441b1777f211"
        image.src=path;   //新创建的image添加src
        var imgWidth = image.width;  // 获取原始图片的宽
        var imgHeight = image.height; // 获取原始图片高
    
        // 设置图片尺寸
        var img = document.getElementById("myImg")
        img.setAttribute("href", path)
        img.setAttribute("width", imgWidth)
        img.setAttribute("heigth", imgHeight)
    
        // 视口尺寸
        var imgView = document.getElementById("imgView")
        var imgViewWidth = imgView.getAttribute("width")
        var imgViewHeight = imgView.getAttribute("height")
    
        console.log(imgWidth, imgHeight, imgViewWidth, imgViewHeight)
    
        // 计算缩放系数
        var scaleRatio = 1.0
        var ratioX =  1.0
        var rationY = 1.0
    
        // 目的是缩放图片至imgView的大小
        ratioX =  imgViewWidth / imgWidth
        rationY = imgViewHeight / imgHeight
    
        // 哪个小取哪个,因为不能超出imgView
        if(ratioX < rationY)
        {
            scaleRatio = ratioX
        }
        else
        {
            scaleRatio = rationY
        }
    
        // 计算偏移,让图片居中显示
        var offsetX = 0
        var offsetY = 0
    
        offsetX = (imgViewWidth - imgWidth * scaleRatio) / 2.0
        offsetY = (imgViewHeight - imgHeight * scaleRatio) / 2.0
    
        console.log(offsetX, offsetY)
    
        // 使图片居中显示
        var transform = "translate(" + offsetX + "," + offsetY + ")" + " " + 
        "scale(" + scaleRatio + "," + scaleRatio + ")"
    
        img.setAttribute("transform", transform)
    
        // 绘制框框
        
        // 
        var rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
        rect.setAttribute("x", imgWidth * 0.1)
        rect.setAttribute("y", imgHeight * 0.1)
        rect.setAttribute("width", imgWidth * 0.5)
        rect.setAttribute("height", imgHeight * 0.5)
        rect.setAttribute("style", "stroke:rgb(255, 0, 0); fill:transparent;")
        rect.setAttribute("transform", transform)
        imgView.appendChild(rect)
    
        console.log(rect, imgView)
    }
    
    script>
      
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

    效果

    上面代码得到的效果为:
    在这里插入图片描述
    可以适应任何尺寸的图片,以及基于图片坐标的矩形框。

    存在的问题

    1.绘制的框框的颜色很浅,不知道为啥。

    参考资料

    https://vimsky.com/examples/usage/svg-scale-attribute.html
    http://www.verydoc.net/svg/00007594.html

    // transform
    https://www.w3cplus.com/svg/transforms-on-svg-elements.html
    https://blog.csdn.net/qq_39492374/article/details/89356931

    // 绘制矩形
    http://t.zoukankan.com/tangyifeng-p-5208186.html
    http://t.zoukankan.com/yangpeixian-p-11359676.html

    preserveAspectRatio
    https://blog.csdn.net/weixin_43002479/article/details/103363480
    https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio

    // 图像原始大小
    https://blog.csdn.net/qq_30449567/article/details/80548489

    svg path
    https://blog.csdn.net/weixin_39868379/article/details/114403129

    // 动态创建svg子元素
    https://www.cnblogs.com/robin1009/p/6068378.html

  • 相关阅读:
    【算法设计实验三】动态规划解决01背包问题
    Hudi 数据湖的插入,更新,查询,分析操作示例
    数据结构与算法-(9)---双端队列(Deque)
    JAVA设计模式-观察者模式
    最最新Netty线程模型源码,它真的太细了【doge】一
    详谈mysql各种常用操作数据表结构的用法【建议收藏】
    TCR历史研究夏校申请详解
    新版Java面试专题视频教程——多线程篇②
    A. Prefix Sum Primes
    基于FPGA的超声波测距
  • 原文地址:https://blog.csdn.net/joyopirate/article/details/126589331