• canvas图片自适应和居中显示


    前言:

    canvas实现百度AI图片多主体识别效果
    上篇文章已经说过使用canvas显示图片并在图片上画图的功能,细心的同学就会发现,这个效果是实现了,但还是有一点**的,那我们就一起来看一下。

    问题:

    1. canvas显示的图片会超出原定的canvas可视区域,并且画图的轨迹也会超出可视区域。
    2. canvas图片无法居中,永远显示在canvas可视区域的左上角。

    既然找到了问题点的所在,那我们就一一来排查,首先来解决第一个问题。

    canvas显示的图片会超出原定的canvas可视区域,并且画图的轨迹也会超出可视区域。

    原因分析:
    出现这种问题的原因其实只有一个,图片太大,大到超出了canvas的原定大小。这种情况的解决方法只有两个,要么让canvas去适应图片大小,要么让图片大小去使用canvas大小。
    canvas是用户的可视区域(容器),为了固定页面布局,我们不可能让canvas容器随意变化,必须把它宽高写死,所以我们能改变的只有图片的大小。

    解题思路:
    图片太大我们就把图片的宽高按照比例缩小,图片太小我们就按比例放大。所以我们得先算出图片与canvas盒子的大小比例,再根据比例放大或缩小尺寸。

    	/**
         * canvas显示图片
        */
        var imgMultiple = 0.5859375
        function showImg(imgUrl, data){
            //获得canvas画布
            var canvas = document.getElementById("canvas");
    		/**
    		  * 此处的canvas大小为900*500	
    		*/
            //得到画布的上下文
            var ctx = canvas.getContext("2d");
            ctx.clearRect(0, 0, 1000, 600)
            //创建一个image元素
            let image = new Image();
            //onload一下
            image.onload = function (res) {
                if (image.width > 900 || image.height > 500) {
                    if(900 / image.width > 500 / image.height){
                        if(900 / image.width < 1 && 500 / image.height < 1){
                            imgMultiple = 900 / image.width
                        } else if(900 / image.width > 1 && 500 / image.height < 1) {
                            imgMultiple = 500 / image.height
                        }
                    } else if(900 / image.width < 500 / image.height){
                        if(900 / image.width < 1 && 500 / image.height < 1){
                            imgMultiple = 500 / image.height
                        } else if(900 / image.width < 1 && 500 / image.height > 1) {
                            imgMultiple = 900 / image.width
                        }
                    } else {
                        imgMultiple = 900 / image.width
                    }
                } else if(image.width < 900 && image.height < 500){
                    if(900 / image.width > 500 / image.height){
                        imgMultiple = 500 / image.height
                    } else if(900 / image.width < 500 / image.height){
                        imgMultiple = 900 / image.width
                    } else {
                        console.log(1111, 900 / image.width, 500 / image.height, image.width, image.height);
                        imgMultiple = 1
                    }
                } else {
                    imgMultiple = 1
                }
                imgWigth = imgMultiple *  image.width
                imgHeight = imgMultiple *  image.height
                ctx.drawImage(image, 1, 1, imgWigth, imgHeight);
                drawSquare(data)
            }
            //用src设置图片的地址
            image.src = `${imgUrl}`;
        }
    
    • 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

    按照比例放大缩小后,就能在canvas中正常显示我们的图片了。所以第一个问题就解决了。
    接下来我们解决第二个问题。

    canvas图片无法居中,永远显示在canvas可视区域的左上角

    其实这个问题我也研究了好久,想过几种方法,比如定位,想办法获取到里面的图片并添加定位样式将其定位到canvas中间。把canvas的大小改成图片的自定义大小,然后将canvas定位到外部盒子中间去。个人觉得第一种不太靠谱,因为canvas获取里面的内容还是有点难度的。第二种还可以,但终究觉得这样做会对第一种问题有所影响,所以也不了了之了。

    后面,我仔细查看了 drawImage 这个方法的使用方式,发现它的参数是这样的。drawImage(图片源, 水平定位, 垂直定位, 图片宽度, 图片高度), 这不就是我一直在找的图片定位吗,原来它近在眼前。我们只需要算出图片需要偏移的量就可以达到图片在canvas上的定位了。

    imgX = (900 - imgWigth) / 2
    imgY = (500 - imgHeight) / 2
    ctx.drawImage(image, imgX, imgY, imgWigth, imgHeight);
    
    • 1
    • 2
    • 3

    效果图:
    在这里插入图片描述

  • 相关阅读:
    京东面试官:讲讲Redis各个数据类型的底层数据结构
    【iOS】—— RunLoop详解
    代码随想录 Day13 二叉树 LeetCode T104 二叉树的最大深度 T111 二叉树的最小深度 T222完全二叉树的节点个数
    Linux 建立链接文件:ln
    不是说人工智能是风口吗,那为什么工作还那么难找?
    计算机毕业设计(附源码)python智慧小区团购系统
    Spring6.1之RestClient分析
    ShardingSphere 集成 CosId 实战
    ssm框架之spring:xml配置再补充
    单片机练习题3
  • 原文地址:https://blog.csdn.net/qq_43942185/article/details/126462886