Coisas que eu quero fazer
Isso exibe um arquivo de imagem local em um canvas HTML.
Encontrei várias sugestões na minha pesquisa, mas quando as experimentei, não funcionaram.
(Nenhum erro foi exibido e nada apareceu na tela.)
Ambiente
Chrome: 131.0.6778.86
Código que tentei
HTML
<input type="file" id="file" accept="image/png, image/jpeg"></div>
<canvas id="canvas"></canvas>JavaScript
document.getElementById("file").onchange = (event) => {
const file = event.target.files[0];
if(!file.type.match(/^image\/(png|jpeg)$/)) return ;
const reader = new FileReader();
reader.onload = (event) => {
const img = new Image();
img.src = reader.result;
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0);
}
reader.readAsDataURL(file);
}
Quando um arquivo é selecionado, uma imagem é criada e a imagem selecionada é inserida no atributo src.
A imagem criada está sendo desenhada no Canvas usando `drawImage`. Parece correta, mas não funcionou no meu ambiente.
contramedida
Funcionou após modificar o código JavaScript da seguinte forma.
O código que manipula a imagem após definir o atributo `src` da imagem é executado após a chamada de `setTimeout`, que coloca a aplicação em estado ocioso.
document.getElementById("file").onchange = (event) => {
const file = event.target.files[0];
if(!file.type.match(/^image\/(png|jpeg|gif)$/)) return ;
const reader = new FileReader();
reader.onload = (event) => {
const img = new Image();
img.src = reader.result;
setTimeout( ()=> {
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0);
});
}
reader.readAsDataURL(file);
}
Nota lateral
No meu ambiente, o valor de `img.width` era 0 quando `canvas.width = img.width;` era chamado antes da correção. Portanto, presumi que o objeto `img` não estava no estado correto e adicionei uma chamada `setTimeout`.
Nota lateral 2
O código estava funcionando em um site executado em um ambiente de teste (sandbox) com praticamente o mesmo código de antes da correção.
Pode haver algum outro fator em jogo. (Será um problema no meu código ou uma questão de sincronização?)
Resultado
Consegui exibir um arquivo de imagem local na tela.


コメント