Home > other >  Convert a Canvas element into Image element
Convert a Canvas element into Image element

Time:05-16

I have a website where I need to generate dynamic images specific to the user. The approach I found was using canvas. I have text information and image file which need to be copied to the canvas and then, later on, can be converted to the image file which the user can download.

function generateImage() {
    let event_date = '11-02-2022'
    let event_name = 'Prom Night'

    let canvas = document.getElementById("your-canvas")
    let ctx = canvas.getContext("2d")

    ctx.font = "26px Arial";
    ctx.textAlign = 'center'

    // For Heading
    ctx.fillText(event_date   ' - '   event_name, 400, 50)

    var img = new Image();
    img.onload = function () {
        ctx.drawImage(img, 100, 100);
    }
    img.src = 'https://cdn.sstatic.net/stackexchange/img/logos/so/so-icon.png'
    return canvas.toDataURL('image/jpg')
}

// generateImage()
let image_gen = generateImage()
$('#gen-image').attr('src', image_gen)
<script src="https://code.jquery.com/jquery-3.6.0.js"
        integrity="sha256-H K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>

<center>
  <h1>CANVAS ELEMENT</h1>
</center>
<br>
<canvas id="your-canvas" width="1000" height="400"></canvas>
<center>
  <h1>IMAGE ELEMENT</h1>
</center>
<br>
<img src="" id="gen-image" alt="" style="border: 0.1em solid black;">

As you can see in the snippet that the image is visible and copied successfully into the canvas but not visible when the canvas is converted into img with toDataURL()

CodePudding user response:

Loading an Image can take some time. In your code, toDataURL is returned before image is loaded and painted on canvas.

To resolve this, you can use Promise to wait until the image is loaded and then get the URL of the canvas.

function generateImage() {
  const promise = new Promise((resolve, reject) => {
    let event_date = "11-02-2022";
    let event_name = "Prom Night";

    let canvas = document.getElementById("your-canvas");
    let ctx = canvas.getContext("2d");

    ctx.font = "26px Arial";
    ctx.textAlign = "center";

    // For Heading
    ctx.fillText(event_date   " - "   event_name, 400, 50);

    var img = new Image();
    img.setAttribute("crossorigin", "anonymous");
    img.src = "https://picsum.photos/200/300";
    img.onload = () => {
      ctx.drawImage(img, 100, 100);
      resolve(canvas.toDataURL("image/jpg"));
    };
  });
  return promise;
}

generateImage().then((value) => {
  $("#gen-image").attr("src", value);
});
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>

<center>
  <h1>CANVAS ELEMENT</h1>
</center>
<br>
<canvas id="your-canvas" width="1000" height="400"></canvas>
<center>
  <h1>IMAGE ELEMENT</h1>
</center>
<br>
<img src="" id="gen-image" alt="" style="border: 0.1em solid black;">

  • Related