【问题标题】:Using Image instead of Canvas使用图像而不是画布
【发布时间】:2014-11-26 15:34:05
【问题描述】:

我有一个图像,我想在它上面画一些正方形。但我在getContext('2d') 上不断收到未定义的函数。我必须补充一点,var img 是一个已经加载到页面上的图像,我试图将其解释为画布,因为我正在使用另一个脚本,它可以选择图像上的区域,如果我使用画布,脚本不管用。那么在我无法将图像解释为画布的情况下,您有什么建议?

js函数

function drawInput(dx1,dy1,dx2,dy2) {
    var img = document.getElementById('home:tempImg');

    var canvas = img;
    console.log(canvas);
    var context = canvas.getContext('2d');
    var imageObj = new Image();

    imageObj.onload = function() {
      context.drawImage(imageObj, dx1, dy1,dx2-dx1,dy2-dy1);
    };
    imageObj.src = 'images/selected.png';
}

HTML

<h:body>


    <h:form onsubmit="#{getComponents.getAllComponents()}" id="home">

        <div>

            <p:graphicImage id="tempImg" rendered="true" value="#{imageView.selectedImg}">
            </p:graphicImage>

        </div>
</h:form>
</h:body>
    <script type="text/javascript">
        var myJSONStr ='{ "area" : #{areaInputView.areaListString}}';

        console.log(myJSONStr);


        var json = JSON.parse(myJSONStr);
        //console.log(json.area[1].x1);
        for(var i=0;myJSONStr.length >i ; i++) {
            console.log(json.area[i].x1, json.area[i].y1, json.area[i].x2, json.area[i].y2);
            drawInput(json.area[i].x1, json.area[i].y1, json.area[i].x2, json.area[i].y2);
        };
    </script>
</html>

【问题讨论】:

  • 我认为您将不得不完全想出一种新方法。 AFAIK 你不能使用img 作为canvas。您可以做的是在画布内绘制图像。它会做更多的工作,你必须找到一种在脚本中访问#{imageView.selectedImg} 的方法;但它绝对有可能。我建议重新考虑您的方法。
  • 嘿乔丹,感谢您的回复。您是否无法考虑图像的尺寸并在其上绘制另一个图像,但要在第一个图像尺寸的边界内?
  • 你绝对可以做到这一点——我不确定怎么做,但是看看 HTMLImageElementCanvas.drawImage 周围的 MDN 文档。捕获对原始图像的引用,并将其属性用作边界。如果我今天有时间,我会试着为你举个例子。
  • 谢谢,您不必这样做,但如果您愿意,请继续。感谢您的提示! :)

标签: javascript jquery html jsf canvas


【解决方案1】:

通过利用自定义 JS“类”(在本例中为 app.Image 类型),我们可以构建一个非常简洁的包装器,允许我们根据我们跟踪的其他实例动态地绘制图像。

查看 this Codepen 以获取工作示例。

window.app = window.app || {};
app.Canvas = document.getElementById('myCanvas').getContext('2d');
app.Image = function(source, x, y) {
  this.x = x;
  this.y = y;
  this.data = new Image();
  this.data.addEventListener('load', this.draw.bind(this));
  this.data.src = source;
};

app.Image.prototype.draw = function() {
    app.Canvas.drawImage(this.data, this.x, this.y);
};

app.Image.prototype.getImageBounds = function() {
    return {
      height: this.data.height,
      width: this.data.width
    }
};

var myImage = new app.Image('http://placehold.it/250x250', 10, 10);
var mySecondImage = new app.Image('http://placesheen.com/100/100', myImage.x + 10, myImage.y + 10);

最重要的一行是最后一行。请注意我们如何使用xy 与第一张图像坐标相对 初始化一个新的app.Image。通过使用跟踪此信息的自定义包装类,我们能够轻松访问在各种情况下所需的必要数据。

我希望这有助于您走上正轨!如果您对代码有任何疑问,请告诉我,我很乐意为您解释。

【讨论】:

  • 不错的答案!这是一个用画布元素替换原始 img 元素的替代想法:jsfiddle.net/w1srxtyk
  • @markE 太棒了!简单得多,而且绝对更符合原始问题的精神。我建议对此做出回答:)
  • 标记如果图像将被画布替换,我将无法使用我的选择脚本,因为它只允许选择图像而不是画布。 @JordanForeman 非常感谢,我将尝试实现您的代码。希望它会很好。 :) 编辑:我检查了示例代码。正如我所说,我不能在示例中使用画布,画布标签正在使用中
  • @FancyPants。很公平。您可以通过创建一个新的 img 元素并将画布用作图像源来“完成循环”:myNewImage.src = canvas.toDataURL(),然后将原始 img 元素替换为 myNewImage。
  • value="#{imageView.selectedImg}" selectedImg 在您在家中选择行中的图像时呈现。它从从数据库获取的字节码中呈现它。所以它必须是通用的。我想也许你可以将值分配给画布,然后将画布用作 img 或类似的东西,但我不相信这是可能的
猜你喜欢
  • 2020-09-22
  • 2019-05-29
  • 1970-01-01
  • 1970-01-01
  • 2013-10-03
  • 2018-11-25
  • 1970-01-01
  • 1970-01-01
  • 2015-02-02
相关资源
最近更新 更多