前言:

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}`;
    }

按照比例放大缩小后,就能在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);

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

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐