skip to Main Content

I’m trying to crop an image that is being returned on request along with coordinations to crop the image at the specified position using ctx.drawImage() function, the drawn image is being shown on the DOM but when I try to get the dateURL of the canvas I get a base64 image back which is empty and doesn’t contain the drawn image.

this is the code of the component that returns the canvas and the img I’m trying to show from the dataURL of the canvas.

<template>
    <canvas ref="canvas" :style="{ width }"></canvas>
    <img alt="canvas image" :src="imageURL" :style="{ width }" />
</template>

<script lang="ts" setup>
import { ref, onMounted } from 'vue';

const props = withDefaults(
    defineProps<{
        imageSrc: string;
        coordinates: string;
        width: string;
    }>(),
    {
        width: '120px'
    }
);

const imageURL = ref<string>('');
const canvas = ref<HTMLCanvasElement | null>(null);

onMounted(() => {
    if (!canvas.value) return;

    const ctx = canvas.value.getContext('2d');
    const img = new Image();
    img.src = props.imageSrc;

    img.onload = function () {
        const [x1, y1, x2, y2] = props.coordinates.split(',').map(Number);
        canvas.value ? (canvas.value.width = x2 - x1) : '';
        canvas.value ? (canvas.value.height = y2 - y1) : '';
        ctx?.drawImage(img, x1, y1, x2 - x1, y2 - y1, 0, 0, x2 - x1, y2 - y1);
    };

    imageURL.value = canvas.value.toDataURL();
});
</script>

2

Answers


  1. You need to place your toDataURL() in the img.onload callback, not after. Doing img.onload = function() ... only registers the callback but the callback isn’t called yet, hence an initial empty canvas:

    img.onload = function () {
        const [x1, y1, x2, y2] = props.coordinates.split(',').map(Number);
        canvas.value ? (canvas.value.width = x2 - x1) : '';
        canvas.value ? (canvas.value.height = y2 - y1) : '';
        ctx?.drawImage(img, x1, y1, x2 - x1, y2 - y1, 0, 0, x2 - x1, y2 - y1;
        imageURL.value = canvas.value.toDataURL());
    };    
    
    Login or Signup to reply.
  2. export const createImageSrcCanvas = ({ elementId }: { elementId: string }): string => {
      const canvas = document.getElementById(elementId)
      const context = canvas.getContext('2d')
      context?.drawImage(videoElement, 0, 0, canvas.width, canvas.height)
      return canvas.toDataURL('image/png')
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search