【问题标题】:Draw on top of an image using javascript使用 javascript 在图像上绘制
【发布时间】:2015-01-15 01:57:41
【问题描述】:

对于某个图像,我有一个列表,其中包含一个多边形中所有点的像素坐标,该多边形分割了它包含的所有对象(请看下图)。

例如,对于人,我有一个列表 l1 = [x0,y0,x1,y1,...,xn,yn],对于猫,我有一个列表 l2 = [x0',y0',x1',y1',...,xk',yk'],对于所有对象也是如此。

我有两个问题:

  1. 最好的javascript 库是用来在图像上绘制的?鉴于原始图像,我想获得如下所示的结果。

  2. 我希望每个分段仅在鼠标悬停在其上方时才可视化。为此,我认为我应该将此绘图功能绑定到鼠标位置。

我正在考虑以下结构的东西,但不知道如何填补空白,请您给我一些指示吗?

$(.container).hover( function(e) {
    //get coordinates of mouse
    //if mouse is over one object
    //draw on top of image the segmentation for that object
});

container 是包含图像的 div 的类,因此我应该能够获取鼠标的坐标,因为图像从 container div 的左上角开始。

【问题讨论】:

  • 这是作业题吗?
  • 我会看看 ImageMapster 插件;它是基于 jQuery 的(我知道您没有说或标记您的问题,但您的示例脚本是 jQ)并且它支持您描述的用例。 outsharked.com/imagemapster
  • SVG 和 Canvas 都可以映射非矩形路径并在将鼠标悬停在这些路径上时显示文本。由于 SVG 是一个成熟的 DOM 元素,您可以要求每个非矩形 SVG 元素在悬停时做出反应。 Canvas 允许您使用context.isPointInPath 对非矩形路径进行命中测试。如果您的设计需要不超出在悬停非矩形路径时显示文本,我会选择 SVG,因为它可以与用户进行开箱即用的交互。
  • @AlexWeinstein - 不...
  • @Stevangelista - 可能有点晚了,但这是一个很好的指针。谢谢!您对如何使用这些演示来回答这个问题有什么建议吗?

标签: javascript jquery html image canvas


【解决方案1】:

检查此Link 可能会减缓您的问题。

包含必要的 javascript 库文件 jquery.min.js,raphael.min.js,json2.min.js,raphael.sketchpad.js

创建编辑器

<div id="editor"></div>
   <form action="save.php" method="post">
   <input type="hidden" name="data" />
   <input type="submit" value="Save" />
</form>

<script type="text/javascript">
    var sketchpad = Raphael.sketchpad("editor", {
    width: 400,
    height: 400,
    editing: true
});
// When the sketchpad changes, update the input field.
  sketchpad.change(function() {
  $("#data").val(sketchpad.json());
  });
</script>

【讨论】:

    【解决方案2】:

    只需从每个数组重建多边形并使用鼠标位置进行命中测试。

    首先:如果您有许多定义形状的数组,那么以更通用的方式处理它可能会更聪明,而不是为每个数组使用变量,因为这很快就会很难维护。更好的是,保存数组和例如 id 的对象可能会更好。

    使用您可以做的对象 - 示例:

    function Shape(id, points, color) {
        this.id = id;
        this.points = points;
        this.color = color;
    }
    
    // this will build the path for this shape and do hit-testing:
    Shape.prototype.hitTest = function(ctx, x, y) {
        ctx.beginPath();
    
        // start point
        ctx.moveTo(this.points[0], this.points[1]);
    
        // build path
        for(var i = 2, l = this.points.length; i < l; i += 2) {
            ctx.lineTo(this.points[i], this.points[i+1]);
        }
    
        ctx.closePath();
    
        return ctx.isPointInPath(x, y);
    };
    

    现在您可以使用各种点数组创建新实例,如下所示:

    var shapes = [];
    
    shapes.push(new Shape("Cat", [x0,y0,x1,y1, ...], "rgba(255,0,0,0.5)");
    shapes.push(new Shape("Woman", [x0,y0,x1,y1, ...], "rgba(0,255,0,0.5)"));
    ...
    

    当您获得鼠标位置时,只需点击测试每个形状:

    $(".container").hover( function(e) {
        //get corrected coordinates of mouse to x/y
        // redraw canvas without shapes highlighted
    
        for(var i = 0, shape; shape = shapes[i]; i++) { // get a shape from array
            if (shape.hitTest(ctx, x, y)) {             // is x/y inside shape?
                ctx.fillStyle = shape.color;            // we already have a path
                ctx.fill();                             // when testing so just fill
                // other tasks here...
                break;
            }
        }
    
    });
    

    【讨论】:

    • 感谢您的回答!澄清一下,ctx 到底是什么?它是 this 示例中的库还是变量?而且,我是否需要使用某种canvas 元素才能在图像上绘图,或者我可以在container 之上进行吗?
    • @Matteo 是的,ctx 是那个链接(画布上下文)。您将需要一个画布元素来绘制(如果您不选择使用 SVG)。这个网站上有很多关于如何设置和使用画布元素本身的例子。如果您不确定,我建议您研究一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多