在HTML5画布上添加背景图像

3

我希望使用 HTML 5 canvas 生成一张可分享的图片,但是我在向画布添加图像时遇到了问题:

以下是我的代码:

HTML:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <div id="the_text" style="display: none;width:100%;height:1000px;background-color:red;">
    CERTIFICATE OF ATTENDANCE

  </div>
  <button id="show_img_btn">Search</button>
  <div class=" center-screen" id="show_img_here" style="">

  </div>

</body>

<script async src="https://static.addtoany.com/menu/page.js"></script>

Javascript:

window.onload = function() {
  $("#show_img_btn").on("click", function() {
    var canvas = document.createElement("canvas");
    canvas.width = 800;
    canvas.height = 500;
    var ctx = canvas.getContext('2d');

    var img1 = new Image();

    //drawing of the test image - img1
    img1.onload = function() {
      //draw background image
      ctx.drawImage(img1, 0, 0);
      //draw a box over the top
      ctx.fillStyle = "rgba(200, 0, 0, 0.5)";
      ctx.fillRect(0, 0, 800, 500);

    };

    img1.src = 'http://cdn.playbuzz.com/cdn/503aeb8a-c1b8-4679-8ed3-da5e11643f29/8a940ebd-8630-4247-888e-c4c611f4f0e2.jpg';

    // rest of content

    ctx.fillStyle = '#c3d200';
    ctx.font = "45px panton";
    var text = $("#the_text").text();
    ctx.fillText(text, 10, 120);

    ctx.fillStyle = '#000000';
    ctx.font = "17px panton";
    var text = $("#the_text").text();
    ctx.fillText('Lorem ipsum dolor sit amet, consectetur:', 230, 280);

    ctx.fillStyle = '#000000';
    ctx.font = " bold 31px panton";
    var text = $("#the_text").text();
    ctx.fillText('Lorem ipsum dolor sit amet, consectetur', 180, 350);

    ctx.fillStyle = '#000000';
    ctx.font = " bold 31px panton";
    var text = $("#the_text").text();
    ctx.fillText('Lorem ipsum dolor sit amet, consectetur adipiscing', 80, 400);

    // create image
    var img = document.createElement("img");
    img.src = canvas.toDataURL();
    $("#show_img_here").append(img);
    //$("body").append(canvas);
  });
};

// share icons
var a2a_config = a2a_config || {};
a2a_config.overlays = a2a_config.overlays || [];
a2a_config.overlays.push({
  services: ['twitter', 'facebook', 'linkedin', 'email'],
  size: '50',
  style: 'horizontal',
  position: 'top center'
});

CSS:

body {
  background: white;
}



button {
  background: #0084ff;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font-size: 15px;
  color: #fff;
}


.center-screen {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  min-height: 100vh;
}


我也尝试过这样做,但不起作用。
var background = new Image();
background.src = "http://cdn.playbuzz.com/cdn/503aeb8a-c1b8-4679-8ed3-da5e11643f29/8a940ebd-8630-4247-888e-c4c611f4f0e2.jpg";

background.onload = function(){
    ctx.drawImage(background,0,0);   
}

或者使用图像源绘制图像:

var img = document.getElementById("image");
    ctx.drawImage(img, 0, 0);


这一切都不起作用。

注意:在HTML上使用 标签可以解决插入图片的问题,但它将无法被识别为可以在社交网络上分享的图像。

这是演示测试链接:FIDDLE DEMO


我认为这就是你要找的:https://dev59.com/8Gw15IYBdhLWcg3wA28A 如果你需要额外的帮助或者这个解决方法无法解决你的问题,请让我知道。 - Maxwell Archer
请插入 HTML 和 CSS。 - s.kuznetsov
@AxelAldrich,我觉得我的问题没有那么复杂,我只是想在画布上插入图像源,但它不起作用。如果您可以的话,请看一下我在描述中的fiddle演示代码。 - Pedro Mendes
@sergeykuznetsov 改进了代码的格式,还添加了整个 HTML、JavaScript 和 CSS 代码,并插入了包含这些代码的 Fiddle 演示。 - Pedro Mendes
2个回答

1

加载后渲染内容

您正在将内容(文本)呈现到画布上,并在背景图像加载之前将该内容作为图像添加。

然后,背景图像加载事件触发,您在内容上绘制背景图像,但由于您已经显示了画布内容(作为图像),因此背景图像从未显示。

始终使用Image.onload事件

每当您设置Image.src属性时,请使用load事件启动与该图像相关的任何形式的渲染。

示例

示例取自您发布的代码,并被缩减以显示基本内容。背景图像是跨域的,这会使画布变脏,因此示例已将最终输出(作为图像)注释掉。它只在渲染完成时添加画布,而不是图像。

整个渲染过程在一个函数中完成,在背景图像加载时调用该函数。

我已将jQuery删除,因为它与问题和解决方案无关。

show_img_btn.addEventListener("click", function() {
    const canvas = document.createElement("canvas");
    canvas.width = 800;
    canvas.height = 500;
    const ctx = canvas.getContext('2d');

    const bgImg = new Image();
    bgImg.src = 'http://cdn.playbuzz.com/cdn/503aeb8a-c1b8-4679-8ed3-da5e11643f29/8a940ebd-8630-4247-888e-c4c611f4f0e2.jpg';
    
    bgImg.addEventListener("load", () => drawContent(ctx, bgImg), {once: true});
    ctx.fillText("Loading image...", 50, 50);
    
});
function drawContent(ctx, bgImg) {
    ctx.drawImage(bgImg, 0, 0);
    ctx.fillStyle = "rgba(200, 0, 0, 0.5)";
    ctx.fillRect(0, 0, 800, 500);

    ctx.textAlign = "center";
    ctx.fillStyle = '#c3d200';
    ctx.font = "45px panton";
    ctx.fillText(the_text.textContent, ctx.canvas.width / 2, 120);

    /* Tainted canvas can not get pixel data on cross origin image (from cdn.playbuzz.com to stackoverflow.com)
    var img = document.createElement("img");
    img.src = ctx.canvas.toDataURL();
    img.addEventListener("load", () => {
          show_img_here.appendChild(img);
    }, {once: true});
     */

    show_img_here.appendChild(ctx.canvas);

};
body {
  background: white;
}
button {
  background: #0084ff;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font-size: 15px;
  color: #fff;
}
<div id="the_text" style="display: none;width:100%;height:1000px;background-color:red;">CERTIFICATE OF ATTENDANCE</div>
<button id="show_img_btn">Load & create image</button>
<div class=" center-screen" id="show_img_here" style=""></div>


谢谢,这是一个非常好的解释,尽管文档的最终结果是画布而不是图像,但我认为如果将图像转换为base64并使用toDataURL()方法,这个问题可以解决。 - Pedro Mendes

-1
我发现将PNG或JPG文件转换为Base64可以解决我的问题:
  1. 通过转换为Base64,现在可以将画布转换为PNG或JPG;
  2. 社交网络图标插件现在识别图片作为图片。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接