22 febrero, 2013

Cuidado con yotube.com!

Hace unos instantes, trate de ingresar a youtube. Grande fue mi sorpresa cuando me encontré con esta página:



¡Mich! dije yo... Asi que me puedo ganar un iPad... jejejeje...

Cuando vi la barra de direcciones me di cuenta de todo. De seguro me pedían el número de la tarjeta de crédito o algo asi.

La pregunta es ¿cómo llegué ahí? . . .  simple... puse yotube.com en lugar de youtube.com

Ya me parecía extraño que Google estuviera regalando "iMac", "iPads" y "iPhones" . . . si ofrecieran un Nexus... caigo.



bytes!

09 noviembre, 2012

Seleccion de área de una imágen con Java

De vez en cuando se necesita que el usuario seleccione un área de una imágen para darle tratamiento. Por ejemplo supongamos que tenemos un programa que almacena fichas de empleados y queremos que en cada ficha se almacene la foto del empleado.

Puede darse el caso de que las imágenes vengan en distinto tamaño, por lo que es útil proporcionar una herramienta que permita la selección de una determinada área de la imágen para su almacenamiento.

El problema en si no es muy complejo. A grandes rasgos se resume en:

  • Determinar el punto de origen.
  • Determinar el área.
  • Seleccionar el área.


Para ello utilizaremos un JPanel que contendra la imágen, la cual estaŕa a su vez contenida en un BufferedImage, un MouseListener para detectar cuando el usuario presiona y suelta el boton del mouse y un MouseMotionListener para determinar cuando el usuario mueve el mouse para seleccionar el área.

Supongamos que el usuario hace clic en un punto de la imagen que llamaremos pi(xi, yi) y arrastra el mouse hasta un punto que llamaremos pf(xf, yf).

El primer paso consiste en determinar al ancho y alto del área abarcada por el arrastre del mouse.

      ancho = Math.abs(xi - xf);
    alto = Math.abs(yi - yf);


Luego obtenemos una imagen con el área seleccionada. Para ello utilizaremos el metodo getSubimage() de BufferedImage.

     BufferedImage seleccion = imagen.getSubimage(x, y, ancho, alto);

Para crear el efecto de opacidad de fondo y seleccion más clara, dibujaremos primero la imagen aplicando un filtro que reduce en un 50% el color. Para ello usaremos RescaleOp.

BufferedImageOp op = new RescaleOp(new float[]{0.5f, 0.5f, 0.5f}, new float[]{0f, 0f, 0f}, null);

Finalmente sobrecargamos el metodo paintComponent() del JPane para que se dibuje la imagen y el área seleccionada.

@Override
public void paintComponent(Graphics gr) {
   Graphics2D g = (Graphics2D) gr;
   super.paintComponent(g);
   if (imagen == null) {
       return;
   }
   if (puntoInicial != null && puntoFinal != null) {
       g.drawImage(imagen, op, 0, 0);
       g.drawImage(getImagenSeleccionada(), x, y, this);
       g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,         RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
       g.setColor(Color.WHITE);
       g.drawRect(x, y, ancho, alto);
       g.drawString("Área: " + ancho + "x" + alto, 10, 20);
   } else {
       g.drawImage(imagen, 0, 0, this);
   }
}


La verdad, es que el tema quiza sea un poco más complejo, porque debemos cuidarnos de que los puntos esten dentro de la imágen. También podríamos forzar a seleccionar un área siempre cuadrada o bien un rectángulo libre.

El código es largo y la verdad me da flojera escribirlo todo aca, por eso los ejemplos resumidos.

Por lo mismo, en este enlace se puede descargar el código fuente del Selector de Área de Imágen y un Jframe con el ejemplo de uso para que puedas incluirlo en tu programa. Cualquier comentario, observación y correción del código es bienvenida.