Tutorial de Canvas – Parte 3 – Usando imagens – Kleber's Blog
Anuncio Google	Tutorial de Canvas – Parte 3 – Usando imagens	Este é o terceiro artigo de uma série que irá apresentar os recursos disponibilizados pela nova tag <canvas> do HTML5. Nesse artigo, veremos como usar manipular imagens com o Canvas. Você pode acessar uma lista de todos os artigos da série nesse link.
Obtendo imagens para serem desenhadas
Usando imagens da mesma página
Usando imagens de outros domínios
Usando outros elementos canvas
Criando uma imagem do zero
Embutindo uma imagem através de data:URL
Usando quadros de um vídeo
Exemplo: Um gráfico de linha simples
Exemplo: Imagem lado a lado
Exemplo: Enquadrando uma imagem
Exemplo de uma galeria de imagens
Controlando o comportamento do escalonamento da imagem
Um dos recursos mais excitantes do <canvas> é a habilidade de usar imagens. Estas podem ser usadas para composição dinâmica de uma foto ou como fundos de gráficos, objetos de jogos, e assim em diante. Imagens externas podem ser usadas em qualquer formato suportado pelo navegador, como PNG, GIF, ou JPEG. Você pode até mesmo usar a imagem produzida por outros elementos canvas da mesma página como fonte!
A importação de imagens para o canvas é basicamente um processo em dois passos:
Obter uma referência para um objeto HTMLImageElement ou para algum outro elemento canvas que será usado com fonte. Não é possível usar imagens apenas pelo fornecimento de uma URL ou caminho para ela.
Desenhar a imagem no canvas através da função drawImage().
Vamos dar uma olhada em como isso é feito.
A API do canvas é capaz de usar qualquer um dos seguintes tipos de dados como fonte de uma imagem:
São imagens criadas usando o construtor Image() , de forma idêntica a qualquer elementos <img>.
Ao usar o elemento <video> do HTML com fonte de sua imagem, será capturado o quadro atual de um vídeo, que será usado como imagem.
Você pode usar outro elemento <canvas> como fonte da imagem.
Este é um bitmap de alta performance que pode ser renderizado com baixa latência; ele pode ser criado tanto de qualquer uma das fontes acima quanto de muitas outras.
Essas fontes são referenciadas coletivamente pelo tipo CanvasImageSource.
Existem diversas maneiras para obter imagens para uso em um canvas.
Podemos obter uma referência para imagens na mesma página onde está o canvas através de um das opções a seguir:
A coleção document.images
O método document.getElementsByTagName()
Se você souver o ID da imagem especifica que quer usar, pode usar o método document.getElementById() para recuperar a imagem específica
Usando imagens de outro domínios
Usando o atributo crossOrigin de um HTMLImageElement, você pode requisitar permissão para carregar uma imagem de um outro domínio para uso em sua chamada à drawImage(). Se o domínio hospedeiro permitir acesso entre domínio à imagem, ela poderá ser usada em seu canvas sem contamina-lo; caso contrário, usar a imagem irá contaminar o canvas.
O que é um canvas "contaminado"?
Apesar de você poder usar imagens sem aprovação de acesso em seu canvas, fazendo isso você contamina o canvas. Uma vez que o canvas seja contaminado, você não será capaz de puxar dados dele. Por exemplo, não poderá usar os métodos toBlob(), toDataURL(), ougetImageData(); fazer isso irá disparar um erro de segurança.
Isso protege os usuários de ter dados privativos expostos pelo uso de imagens para puxar informações de sites remotos sem permissão.
Usando outros elementos do canvas
De forma análoga ao uso de imagens normais, podemos acessar outros elementos canvas apenas pelo uso dos métodos document.getElementsByTagName() ou document.getElementById(). Certifique-se de ter desenhado algo no canvas antes de usa-lo no destino.
Um dos usos mais práticos desse método seria usar um segundo elemento canvas como miniatura de outros canvas maiores.
Uma outra opção é criar um novo objeto HTMLImageElement em nosso script. Para fazer isso, você pode usar o conveniente construtor Image():
Quando o script é executado, a imagem começa a ser carregada.
Se você tentar chamar drawImage() antes da imagem ter terminado seu carregamento, nada irá acontecer (ou, em navegadores antigos, um erro pode ser disparado). Dessa forma, certifique-se de usar o evento load de forma que você não tente usar esse método antes do término do carregamento da imagem:
Se você estiver usando apenas uma imagem externa, essa é uma boa abordagem, mas uma vez que tenha que rastrear mais de uma, precisaremos recorrer a um recurso mais esperto. Isso vai além do escopo desse artigo, mas você pode dar uma olhada em JavaScript Image Preloader para uma solução mais completa.
Uma outra forma possível para incluir imagens é através de data: url. Data URLs permitem que você defina complemente uma imagem como uma String Base64 diretamente em seu código.
Uma vantagem de Data URLs é que a imagem resultante estará disponível imediatamente sem necessidade de um novo acesso ao servidor. Uma outra vantagem em potencial é que é possível encapsular todos os seus códigos CSS, JavaScript, HTML, e imagens, tornando a página mais portátil.
Algumas desvantagens desse método são que sua imagem não será salva em cache, e para imagens grandes a URL codificada será bem longa.
Você pode usar quadros de um vídeo que está sendo apresentado por um elemento <video> (mesmo que o vídeo não esteja visível). Por exemplo, se você possuir um elemento <video> com o ID "myvideo", pode fazer isso:
Isso irá retornar o objeto HTMLVideoElement para o vídeo, que, como mencionado anteriormente, pode ser usado como um CanvasImageSource.
Uma vez que você tenha uma referência para sua fonte de imagem, podemos usar o método drawImage() para renderiza-la no canvas. Como veremos mais tarde o método drawImage() é sobrecarregado e tem diversas variações. Em sua forma mais básica, ele se parece com o seguinte:
Desenha o CanvasImageSource especificado pelo parâmetro image nas coordenadas (x, y).
No exemplo a seguir, usaremos uma imagem externa como backdrop para um pequeno gráfico de linha. O uso de backdrops pode tornar o seu script consideravelmente menor porque evita a necessidade de código para gerar o fundo. Nesse exemplo, usamos apenas uma imagem, assim foi usado o manipulador de imagem load do objeto image para executar as sentenças de desenho. O método drawImage() posiciona os backdrops na coordenada (0, 0), que é o canto superior esquerdo do canvas.
O gráfico resultante deve se parecer com isso:
A segunda variação do método drawImage() adiciona dois novos parâmetros e permite que posicionemos imagens escalonadas no canvas.
Essa variação acrescenta os parâmetros width e height, que indicam o tamanho que a imagem terá ao ser desenhada no canvas.
Nesse exemplo, usaremos uma imagem como papel de parede e repetiremos ela diversas vezes no canvas. Isso é feito simplesmente pelo posicionamento em loop da imagem em diversas posições. No código abaixo, o primeiro loop for itera as linhas. O segundo for itera as colunas. A imagem é escalonada para 1/3 de seu tamanho original, que é 50×38 pixels.
Nota: Imagens podem ficar borradas quando escalonada para um tamanho maior do que o original ou granuladas se escalonadas para tamanhos menores. Escalonamento provavelmente não é a melhor solução se você tiver algum texto que precisa ficar legível.
O canvas resultante ficará assim:
A terceira e última variação do método drawImage() possui oito parâmetros. Essa variação recorta uma seção da imagem, escalona essa seção e a desenha no canvas.
Dada uma image, essa função obtém a área da imagem especifica pelo retângulo cujo canto superior esquerdo é (sx, sy) e cuja largura e altura são sWidth e sHeight e desenha essa imagem no canvas, posicionando ela em (dx, dy) e escalonando-a para o tamanho especificado por dWidth e dHeight.
Para realmente entender o que esse método faz, pode ajudar dar uma olhada na imagem à direita. Os primeiros quatro parâmetros definem a localização e o tamanho da fatia da imagem fonte. Os últimos quatro definem o retângulo no qual será desenhado a imagem no canvas destino.
O fatiamento pode ser útil quando se quer fazer composições. Você pode ter todos os elementos em um único arquivo de imagem e usar esse método para compor um desenho completo. Por exemplo, se quiser criar um mapa pode ter uma imagem PNG que contenha todo o texto necessário em um único arquivo e dependendo de seus dados poderia alterar a escala de seu mapa de forma bem fácil. Uma outra vantagem é que você não precisa carregar cada imagem individualmente, o que pode melhorar a performance do carregamento.
Nesse exemplo, usaremos a mesma foto usada no exemplo anterior, mas recortaremos sua cabeça e colocaremos ela em um quadro. A imagem do quadro é um PNG de 24 bits que inclui uma sombra. Como um PNG de 24 bits inclui um canal alfa de 8 bits, ele pode ser posicionado em qualquer fundo sem ter que se preocupar com um cor fosca.
&lt;img id="source" src="http://www.klebermota.eti.br/wp-content/rhino.jpg" width="300" height="227"&gt;
&lt;img id="frame" src="http://www.klebermota.eti.br/wp-content/Canvas_picture_frame.png" width="132" height="150"&gt;
Usamos uma abordagem diferente para carregar a imagem dessa vez. Ao invés de carrega-las pela criação de um novo objeto HTMLImageElement, incluímos ela com uma tag <img> diretamente em nosso HTML e recuperamos as imagens a partir dela. As imagens ficam ocultas na saída pela configuração da propriedade display do CSS para none para essas imagens.
O script em si é bastante simples. Para cada <img> é associado um atributo ID, que torna fácil seleciona-las usando document.getElementById(). Em seguida, simplesmente usamos drawImage() para fatiar a imagem do rinoceronte e escalona-la no canvas, e em seguida desenhar a moldura sobre ela usando uma segunda chamada àdrawImage().
No exemplo final desse artigo, construiremos uma pequena galeria de imagens. Quando a página é carregada, um elemento <canvas> é inserido para cada imagem e uma moldura é desenhada em torno delas.
Nesse caso, cada imagem possui uma largura e altura fixas, assim como a moldura desenhadas em torno delas. Você poderia aperfeiçoar o script de forma que ele usasse a largura e altura da imagem para fazer com que ela coubesse perfeitamente na moldura.
O código abaixo deve ser auto-explicativo. Percorremos em loop um conêiner document.images e adicionamos novos elementos canvas de acordo. Provavelmente a única coisa digna de nota, para aqueles que não estejam familiarizados com o DOM, é o uso do métodoNode.insertBefore. insertBefore() é um método do nó pai (uma célula da tabela) do elemento (a imagem) antes que nós inserimos nosso novo nó (o elemento canvas).
E a seguir algum código CSS para tornar as coisas melhores:
Agora segue o código JavaScript que põe tudo junto para desenhar as imagens emolduradas:
Como mencionado anteriormente, escalonar imagens pode resultar em artefatos difusos ou quadriculados, devido ao processo de escalonamento. Você pode usar a propriedade imageSmoothingEnabled do contexto de desenho para controlar o uso dos algoritmos de suavização da imagem quando escalonar imagens em seu contexto. Por padrão, isso é true, o que significa que as imagens serão suavizadas quando escalonadas. Você pode desativar esse recurso dessa forma:
Publicado em 26 de outubro de 201313 de junho de 2017Autor Kleber MotaCategorias Canvas, HTML5, JavaScriptTags Canvas, gráficos, html, html5, tutorial	Iran Nunes
Olá kleber, excelente post, tenho uma dúvida: consigo gerar o data:URL, copio e através de um gerenciador de mysql gravo em um campo blob e consigo recuperar a imagem, no entanto se pegar mesmo dado com. jquery ex. var foto = $('#base64').text(); obs o id base64 é um input textarea, e através do POST do ajax envio para o php gravar o mesmo campo blob, não. recupero a imagem aparece apenas o fundo sem imagem, seria o caso de imagem contaminada. Guest
Olá kleber, excelente post, tenho uma dúvida: consigo gerar o data:URL, copio e através de um gerenciador de mysql gravo em um campo blob e consigo recuperar a imagem, no entanto se pegar mesmo dado com. jquery ex. var foto = $('#base64').text(); obs o id base64 é um input textarea, e através do POST do ajax envio para o php gravar o mesmo campo blob, não. recupero a imagem aparece apenas o fundo sem imagem, seria o caso de imagem contaminada. Navegação de Post
Anterior Post anterior: Tutorial de Canvas – Parte 2 – Desenhando formasSeguinte Próximo post: Tutorial de Canvas – Parte 4 – Aplicando estilos e cores