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
You need to place your
toDataURL()
in theimg.onload
callback, not after. Doingimg.onload = function() ...
only registers the callback but the callback isn’t called yet, hence an initial empty canvas: