terça-feira, 12 de agosto de 2014

Salvando uma imagem com background a partir de canvas

Olá galera,

Esses dias precisei salvar uma imagem a partir do canvas. Só clicando com o botão direito e pedindo para salvar como imagem funciona. Então qual o problema? O click com o botão direito já tinha um evento mapeado e o background do PNG gerado era transparente.

O problema foi solucionado com Javascript através de uma simples página HTML com um botão.

Código HTML:

    <!DOCTYPE html>
    <html lang="pt-br">
      <head>
        <title>Canvas</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
      </head>
      <body>
        <canvas id="canvas" width="200" height="200"></canvas>
        <button>Baixar</button>
        <script defer="defer" src="canvas.js"></script>
      </body>
    </html>
  

Código Javascript:

    var button = document.getElementsByTagName('button');

    button[0].addEventListener('click', function() {
      var canvas = document.getElementById("canvas");
      var w = canvas.width;
      var h = canvas.height;
      var context = canvas.getContext('2d');
      var data = context.getImageData(0, 0, w, h);
      context.fillStyle = "rgb(255,0,0)"; 
      context.fillRect(0,0,w,h);
      window.location.href = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");

      context.clearRect (0,0,w,h);
      context.putImageData(data, 0,0);
    });
  

Explicando o código do Javascript:

Linha 3 - Adicionando o evento de click ao botão.
Linha 7 - Retorna o objeto com métodos e propriedades para desenhar na tela.
Linha 8 - Retorna o objeto ImageData que copia os dados do pixel para a geometria com largura e alturas definidas.
Linha 9 - Retorna a cor usada para preencher o desenho.
Linha 10 - Desenha o retângulo "cheio".
Linha 11 - Conversão e exportação do desenho do canvas em uma URL codificada PNG de 64 bits.
Linha 13 - Limpa os pixels especificado dentro do retângulo.
Linha 14 - Coloca os dados da imagem (a partir do objeto ImageData especificado) de volta para a tela.

Fica aí a dica de hoje.

Um grande abraço a todos.

8 comentários:

  1. e se eu precisar salvar essa imagem no hd local para exibição posterior, sem intervenção do usuário? sabe se tem como?

    ResponderExcluir
    Respostas
    1. Olá Agnaldo,

      O procedimento é o mesmo. Só que você não precisará colocar o código que gera a imagem com o evento de click do botão.

      Abraço

      Excluir
  2. Minha dúvida é a mesma do amigo que comentou. Não estou conseguindo salvar a imagem no computador local. Poderia me ajudar? Obrigado

    ResponderExcluir
    Respostas
    1. Olá Cássio,
      Clicando no botão não está sendo salva uma imagem vermelha?!
      Abraço

      Excluir

    2. (tag script)
      window.onload = function () {

      var largura = 500;
      var altura = 300;

      var quadro = document.getElementById("quadro");
      quadro.setAttribute("width", largura);
      quadro.setAttribute("height", altura);

      var ctx = quadro.getContext("2d");


      var desenhando = false;

      quadro.onmousedown = function (evt) {
      ctx.moveTo(evt.clientX, evt.clientY);
      desenhando = true;
      }

      quadro.onmouseup = function () {
      desenhando = false;
      }
      quadro.onmousemove = function (evt)
      {
      if (desenhando){
      ctx.lineTo(evt.clientX, evt.clientY);
      ctx.stroke();
      }
      }

      }
      (tag fecha script)




      (tag button) SALVAR (tag fecha button)
      (tag script) defer="defer" src="canvas.js">
      (tag fecha script)

      (tag script) var button = document.getElementsByTagName('button');

      button[0].addEventListener('click', function() {
      var canvas = document.getElementById("quadro");
      window.location.href = canvas.toDataURL("images/png").replace("images/png", "images/octet-stream");


      context.clearRect (0,0,w,h);
      context.putImageData(data, 0,0);
      });

      (tag fecha script)

      Excluir
    3. alterei algumas tags porque o comentário não aceitou, mas é mais ou menos isso: quero pegar uma assinatura de uma pessoa e salvá-la no banco de dados local.

      Excluir
  3. é que na verdade eu adaptei esta parte do código com outra parte que eu utilizo o canvas pra desenhar, como se fosse uma assinatura, entende?

    ResponderExcluir
    Respostas
    1. Olá Cássio,

      o script que eu publiquei ele gera uma imagem para ser salvar em um disco local. Para persistir em um banco de dados será necessário utilizar alguma linguagem de servidor (PHP, Java, Ruby, Python, etc)

      Abraço

      Excluir