Cómo crear una imagen PNG con Java y cómo usar el Canvas de

Anuncio
Licenciatura en Ciencias de la Computación, Facultad de Ciencias, UNAM. Riesgo tecnológico. Profesor: Karla Ramirez Pulido. Dibujar con HTML5 y JavaIO y PostrgreSQL JDBC Despliegue de imágenes en páginas web dinámicas y acceso a BD. Manuel Ignacio Castillo López, ayudante de laboratorio. Canvas HTML5 Considere una página web vacía. Note que el respectivo HTML, tiene un body con un hijo llamado “canvas” (entre otros): <!DOCTYPE HTML> <html> <head> <title>Ejemplo Canvas HTML5</title> <meta http­equiv="content­type" content="text/html; charset=utf­8" /> <meta charset="UTF­8" /> <meta name="author" content="Manuel Nachintoch Castillo" /> </head> <body > <canvas id=”cavas” width=”1000” height=”500” > Canvas HTML5 no soportado </canvas> <script type="text/javascript" > // aquí pondremos el código de dibujado de nuestro Canvas </script> <noscript >Javascript está desactivado, o su navegador no lo sopota</noscript> </body> </html> Canvas es un espacio en una página web, donde podemos dibujar al vuelo. El texto dentro de la etiqueta es mostrado cuando el navegador del cliente no puede interpretar el elemento <canvas> Las etiquetas width y height, como su nombre sugiere, indican el ancho y alto (respectivamente) del canvas en la página web. Luego aparece una etiqueta <script> En esta etiqueta usualmente se incluye código Javascript para incluir cierta funcionalidad dinámica en la página web. Para manipular en canvas, ​
necesitamos de Javascript, ya que es la única manera de hacerlo. Algunos frameworks y entornos nos permiten dibujar en un Canvas HTML5 sin usar Javascript, pero lo que hacen en realidad es transformar todo en Javascript que puede interpretar un navegador web. Finalmente, la etiqueta <noscript> Contiene un texto que se mostrará al usuario cuando su navegador no ejecute o interprete el Javascript. Si el navegador cliente puede interpretar el Javascript y hacer los dibujos indicados en el canvas, no se mostrará el contenido de la etiqueta <noscript> Veamos algunas instrucciones que nos permiten hacer dibujo en nuestro canvas: Lo primero que necesitamos, es una referencia al canvas en sí mismo. Para ello, vamos a usar la instrucción ​
document.getElementById​
y le daremos el ID del canvas: var canvas = document.getElementById("canvas"); Note que estamos almacenando dicha referencia en una variable llamada canvas, aunque podría llamarse de cualquier forma que desee. Ahora, el dibujo lo hacemos por medio del contexto del canvas, por lo que necesitamos obtenerlo: var ctx = canvas.getContext("2d"); El contexto solicitado, es sólo para dibujo en 2D. Es posible obtener un contexto para hacer dibujo en 3D con ‘webgl’, pero para fines didácticos, usemos el 2D. Para usar WebGL es recomendado (sino indispensable) tener frescos conocimientos en Álgebra Lineal. Comencemos a hacer dibujos en el plano. Lo primero que queremos hacer es iniciar un camino para dibujar líneas en el plano: ctx.beginPath(); Para dibujar una línea, primero debemos indicar el punto inicial de la misma: ctx.moveTo(50, 450); Luego, indicamos el punto final de la línea: ctx.lineTo(50, 50); Ahora, pintemos un texto. Lo primero que nos gustaría hacer es indicar el tamaño del mismo y la fuente con la que queremos que aparezca: ctx.font = “25px Arial”; Ahora, pintemos una cadena: ctx.fillText(“Hola”, 380, 480); La instrucción anterior dibuja una cadena, cuya línea base será paralela a la horizontal; pero ¿y si queremos pintar una cadena en otro ángulo? Por ejemplo, paralela a la vertical? Probablemente queramos “guardar” el estado actual del contexto, ya que no necesariamente vamos a querer pintar otras cosas con ese ángulo. Para guardar el estado del contexto usamos: ctx.save(); Ahora, vamos a trasladar el origen de nuestro plano de dibujo a una posición. Preferentemente, podemos escoger aquella donde nos gustaría donde quedará el texto (o lo que sea) rotado: ctx.translate(0, 280); ctx.rotate(­Math.PI /2); Lo anterior es una rotación de 90° en el sentido contrario a las agujas del reloj. Combinado con lo siguiente; ctx.fillText(“vertical”, 0, 25); Obtenemos un texto paralelo a la vertical que se lee de abajo hacia arriba. Para restaurar el estado inicial del contexto y eliminar la rotación y traslación que hemos hecho a nuestro plano de dibujo: ctx.restore(); Si queremos pintar el perímetro de un rectángulo, usamos la siguiente instrucción: ctx.rect(790, 100, 200, 100); El primer parámetro es la coordenada x de la esquina superior izquierda del rectángulo. El segundo, es la coordenada y de la esquina superior. El tercero es el ancho del rectángulo a dibujar y el último es la altura. Para dibujar el área de un rectángulo, puede interesarnos primero asignar un color para pintar por ejemplo un rectángulo rojo en lugar de uno negro (color por defecto). Para construir un color, usamos una cadena de 6 hexadecimales como esta: “#0156AB”. Debe empezar con el símbolo ‘#’. Los primeros dos dígitos son el valor que le daremos al rojo, los siguientes dos al verde y los últimos dos al azul: #000000 es negro y #FFFFFF es blanco: ctx.fillStyle = “#FF0000”; Con la siguiente instrucción pintamos el rectángulo usando el color dado: ctx.fillRect(810, 110, 20, 20); Java ImageIO Podemos crear imágenes al vuelo usando las clases ​
java.awt.image.BufferedImage y javax.imageio.ImageIO​
. Para ello, podemos hacer algo como lo siguiente. Por simplicidad, vamos a ejemplificar el dibujado con solo usar el main. Note que el main tira una excepción del tipo java.io.IOException, por lo que debemos importar dicha excepción también. public static void main(String[] args) throws IOException { BufferedImage img = new BufferedImage(1000, 500, BufferedImage.TYPE_4BYTE_ABGR); Lo anterior crea un BufferedImage ​
img​
, que consiste en un “lienzo” de 1000 pixels de ancho, 500 de alto y 4 bytes de capa de color: transparencia (alpha), azúl, verde y rojo; los colores básicos en la teoría emisora de la luz con los que podemos formar cualquier otro color. File png = Paths.get(“imagen.png”).toFile(); La instrucción anterior, nos devuelve un archivo que en principio representa una imagen, cuya ruta absoluta se sitúa en el directorio donde se esté ejecutando la aplicación. Debemos importar a File de java.io.File y Paths de java.nio.Paths. Graphics2D g = img.createGraphics(); La última instrucción nos devuelve un objeto que nos permite dibujar sobre un lienzo en el plano. Así como en HTML5, podemos pedir gráficos de 3D, pero estos pueden depender de la plataforma en tiempo de ejecución (por ejemplo, OpenGL v2) y también requieren de un conocimiento moderado en Álgebra Lineal. Pero para ejemplificar el dibujo, nos basta con usar un lienzo plano. Graphics2D vive en el paquete java.awt. g.setColor(Color.black); Por defecto, los gráficos tienen color blanco. La instrucción anterior le dice explicitamente a nuestros gráficos que queremos usar color negro. Deberemos importar color de java.awt. g.drawLine(50, 450, 50, 50); A diferencia de HTML5, con los gráficos de Java no vamos a seguir un camino, si no que podemos trazar libremente sobre el ​
BufferedImage (nuestro lienzo). La instrucción anterior, le dice a los gŕaficos que queremos una línea recta con un extremo en el punto (50, 450) y el otro en la coordenada (50, 50). g.setFont(new Font(“Arial”, Font.PLAIN, 25)); Con lo anterior, le indicamos a los gráficos que para la próxima cadena que queramos pintar, queremos que use la fuente Arial, sin cursivas ni negritas, sino sólo plano y de tamaño 25. Font deberá importarse del paquete java.awt. g.drawString(“Cadena”, 380, 480); La instrucción anterior pinta una cadena que dice Cadena con base superior derecha en el punto (380, 480) de nuestro lienzo (BufferedImage). AffineTransform original = g.getTransform(); Para realizar ciertas acciones, es posible que nos interese aplicar transformaciones al plano. Por ejemplo, podríamos querer escribir un texto que quede paralelo a la vertical y que se lea de abajo a arriba. Pero posiblemente, después de pintar dicho texto, queramos eliminar las transformaciones hechas para trabajar con el plano “original”. Para esto usamos getTransform(), que nos devuelve el estado actual (respecto a las transformaciones) que sufre el lienzo. AffineTransform pertenece al paquete java.awt.geom g.translate(0, 280); Con la instrucción anterior aplicamos una transformación al plano y lo trasladamos a un nuevo origen. g.rotate(­Math.PI /2); Y con esta, rotamos el plano en sentido anti­horario 90°. g.setTransform(original); Finalmente, restablecemos el estado original del plano. g.drawRect(790, 100, 200, 100); La instrucción anterior dibuja el perímetro de un rectángulo anclado desde la esquina superior izquierda en el punto (790, 100) de nuestro lienzo y de ancho 200 y alto 100. g.fillRect(810, 110, 20, 20); Y con esta dibujamos el área de un rectángulo anclado en la esquina superior izquierda en la coordenada (810, 110) y de ancho 20 y alto 20 (es decir, es un cuadrado). g.dispose(); Cuando terminamos de dibujar, usamos esa instrucción para indicarle a la JVM que ya no necesitamos los gráficos y puede liberar los recursos. ImageIO.write(img, “PNG”, png); } Finalmente, escribimos nuestro lienzo (ya con todos sus dibujos encima) en un archivo de tipo PNG usando el archivo de Java (File) png. PostgreSQL JDBC Suponiendo que tenemos un usuario “test” con permiso para usar una base de datos existente “testDB”, que a su vez tiene una table “testTable”, constituida por un valor entre “ID” y una cadena “valor”; podemos hacer lo siguiente: Creamos una clase “ObjetoBD” que represente una entrada de la base de datos: public class ObjetoBD { private int id; private String valor; public ObjetoBD(int id, String val) { this.id = id; this.valor = val; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getValor() { return valor; } public void setValor(String valor) { this.valor = valor; } } Creamos una clase que será un Bean para usar con nuestra página web: @ApplicationScoped public class Consultor { public ObjetoBD[] consultar() throws SQLException, ClassNotFoundException { Class.forName("org.postgresql.Driver"); Connection con = DriverManager.getConnection( "jdbc:postgresql://localhost:5432/testDB", "test", "insecure"); Statement stmt = con.createStatement(); String query = "SELECT * FROM testTable;"; ResultSet resultados = stmt.executeQuery(query); LinkedList<ObjetoBD> salida = new LinkedList<>(); while(resultados.next()) { salida.add(new ObjetoBD(resultados.getInt("id"), resultados.getString("value"))); } return salida.toArray(new ObjetoBD[0]); } }//Consultor Usamos una tabla en una página XHTML para mostrar el conteido de la base de datos: <p>La base de datos contiene:</p> <table > <tr > <th >ID</th> <th >Valor</th> </tr> <ui:repeat value="#{consultor.consultar()}" var="resultado" > <tr > <td >#{resultado.id}</td> <td >#{resultado.valor}</td> </tr> </ui:repeat> </table> Es importante recordar, que debemos incluir la biblioteca org.postgresql.Driver en *­war/web/WEB­INF/lib y desde ese mismo directorio, incluirlo explícitamente en Netbeans. 
Descargar