简体   繁体   English

canvas drawimage在具有CSS高度和宽度的图像上无法正常工作

[英]canvas drawimage is not working properly on image with css height and width

I am trying to write a image magnifier with canvas, It works fine but the problem is when I mouseover the image the image drawn on the canvas is not positioned correctly based on the mouse position on the image. 我试图用画布写一个图像放大镜,它工作正常,但是问题是当我将鼠标悬停在图像上时,基于图像上的鼠标位置,画布上绘制的图像未正确定位。

You can see the problem here 你可以在这里看到问题

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Magnifier</title>

<style type="text/css">
canvas
{
    border:1px solid #000;
    width:150px;
    height:150px;
    border-radius:80px;
    position:absolute;
}
</style>
</head>
<body>
<img src="natural.jpg" height="400" id="image" width="600" onMouseMove="move(event);">
<canvas id="magnifier"></canvas>
<input type="button" name="magnify" id="magnify" value="magnify" onClick="magnify()" />
</body>
</html>
<script type="text/javascript">
var flag = 0;
var lens = document.getElementById('magnifier');
var img = document.getElementById('image');
var ctx=lens.getContext("2d");
function magnify()
{
    flag = 1;
}
function move(e)
{
    if(flag == 1)
    {
        var co_ord = getImageCoords(e,img);

        var x = co_ord['x']+img.offsetLeft;
        var y = co_ord['y']+img.offsetTop;
        draw(x,y);
        /*lens.style.top = y+"px";
        lens.style.left = x+"px";*/

    }
}
 function getImageCoords(event,img) {
        var cords = new Array;
        cords['x'] = event.offsetX?(event.offsetX):event.pageX-img.offsetLeft;
        cords['y'] = event.offsetY?(event.offsetY):event.pageY-img.offsetTop;
        return cords;
    }
    function draw(a,b)
    {
    ctx.clearRect(0,0,lens.width,lens.height);
    ctx.drawImage(img,a,b,150,150,0,0,300,150);
    }
</script>

The main problem is that you are scaling the original image by forcing it into a 640 by 400 img element. 主要问题是您要通过将原始图像强制为640 x 400 img元素来缩放原始图像。 The actual image is quite a bit larger. 实际图像要大得多。 The width and height are just presentation settings, so when you draw the image ctx.drawImage(img,a,b,150,150,0,0,300,150); 宽度和高度只是演示设置,因此当您绘制图像时ctx.drawImage(img,a,b,150,150,0,0,300,150); it is drawing the original unsized image. 它正在绘制原始的未缩放图像。 This means that your mouse coordinates do not match the location on the original image. 这意味着您的鼠标坐标与原始图像上的位置不匹配。

I can see two options: 我可以看到两个选项:

1. Resize original by drawing to canvas 1.通过绘画到画布来调整原件的大小

See update here . 在这里查看更新。 I haven't used cssdeck before, so here is a fiddle in case I didn't save it properly. 我以前没有使用过cssdeck,所以这里是一个小提琴 ,以防万一我没有正确保存它。 Basically, it resizes the image to a canvas (resizeCanvas) and then uses this canvas for the drawing: 基本上,它将图像调整为画布大小(resizeCanvas),然后将此画布用于绘图:

Relevant HTML: 相关HTML:

<canvas id='resizeCanvas' height='400' width='600' onMouseMove="move(event);"></canvas>

Relevant JavaScript: 相关JavaScript:

var ctxR=resizeCanvas.getContext("2d");
ctxR.drawImage(theImg,0,0,600,400);

There were a few other tweaks I made. 我还有其他一些调整。 First, you should specify the width and height attributes directly on the magnifier canvas. 首先,您应该直接在放大镜画布上指定width和height属性。 Otherwise, if this is different from the css then this will cause scaling. 否则,如果这与CSS不同,则将导致缩放。 Then you can do the scaling to double the size by: 然后,您可以缩放以将大小增加一倍,方法是:

ctx.drawImage(img,a,b,150,150,0,0,300,300);

The only drawback of that approach is that you have a high res image that you are uploading and then losing some quality when you maginify which seems a pity. 这种方法的唯一缺点是您上传的是高分辨率图像,然后放大后失去一些质量,这似乎很可惜。 So, a better approach might be to load the original image without adding to the dom and then translate the x,y coords appropriately for the original image. 因此,更好的方法可能是在不添加dom的情况下加载原始图像,然后为原始图像适当地转换x,y坐标。 Which is the second approach: 第二种方法是:

2. Scale x,y coordinates (better quality) 2.缩放x,y坐标(更好的质量)

See the update here (fiddle here as well). 请参阅更新这里 (小提琴这里也一样)。 As you can see, the quality is much better. 如您所见,质量要好得多。

Here, we load the original image: 在这里,我们加载原始图像:

var origImage = document.createElement('img');
var origImage.src = '<image source>'

Then, just scale accordingly: 然后,相应地缩放:

scaleX = origImage.width/img.width;
scaleY = origImage.height/img.height;
    ctx.clearRect(0,0,lens.width,lens.height);
    ctx.drawImage(img,a*scaleX,b*scaleY,150,150,0,0,150,150);

Note that we are not actually doing any resizing of the original image at all when we draw it to the canvas (width and height are 150 in all cases), instead we are just showing it at its larger native size. 请注意,当我们将原始图像绘制到画布上时,实际上并没有对它进行任何尺寸调整(在所有情况下,宽度和高度均为150),而只是将其显示为更大的原始尺寸。 For smaller images, you may want to resize according to some fudge factor. 对于较小的图像,您可能需要根据一些软糖因素调整大小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM