coge la información y corre

Matrices para desenfocar

20 de septiembre del 2007 Escrito por Alex Barros

tallo.jpgEfectivamente. Desarrollando la versión 2.0 estable del plugin Imaset, y en busca de filtros para imágenes, me he encontrado un tipo de retoque fotográfico muy utilizado por editores gráficos, llamado “matriz de convolución

Consiste en el tratamiento de una matriz por otra llamada “kernel“. La matriz original es la propia imagen en este caso (un conjunto de píxeles bidimensional), y la matriz denominada kernel varía dependiendo del efecto deseado.

El proceso del algoritmo es algo complejo. Consiste en recorrer la imágen píxel a píxel, obtener los valores de los 8 píxeles más cercanos, y aplicar la matriz kernel. El valor resultante se adjudica al píxel, y continúa haciendo lo mismo con el resto.

Lo que deducimos de esto es que la matriz de convolución readjudica el color a cada fragmento (píxel), en función de sus píxeles vecinos, dada una norma de actuación mediante el kernel, que suele consistir en una matriz de 3×3 (aúnque las hay más grandes)

Llegados hasta aquí, un filtro interesante es el de desenfoque (el típico blur). Pues bien, la matriz necesaria, es una matriz compuesta enteramente por unos. Esto quiere decir que va a mezclar literalmente el color de todos los píxeles adyacentes por igual, y el resultado será un desenfoque general.

También hay infinidad de otras opciones, puede obtenerse más contraste, detectar bordes (hay varios tipos de bordes, y son útiles para distinguir siluetas, imprescindible para robots por ejemplo), resaltar, repujado….. cada matriz ofrece un resultado distinto.

Matriz cualquiera Matriz para bordes

Esto en la práctica, teniendo PHP y la biblioteca GD (para tratamiento de imágenes) podemos efectuarlo con la función imageconvolution().
Los parámetros necesarios son un resource de imágen (creado con imagetruecolor, imagecreatefromjpeg, etc), la matriz de convolución (de tres por tres), un divisor para los elementos de la matriz, y un compensador (offset).

Un ejemplo de script en PHP:

  1. $im = imagecreatefromjpeg(‘fotografia.jpg’);
  2. $matrix = array(
  3. array( 2, 2, 2 ),  
  4. array( 2, 2, 2 ),  
  5. array( 2, 2, 2)
  6. );
  7. imageconvolution($im, $matrix, 16, 0);
  8. imagejpeg($im,‘fotografia_blur.jpg’);
  9. imagedestroy($im);

Para aquellos que no dispongan de esta función en su biblioteca GD, por ser un poco atrasada, o por cualquier otra razón, aquí hay un código para generarla:

  1. //include this file whenever you have to use imageconvolution…
  2. //you can use in your project, but keep the comment below :)
  3. //great for any image manipulation library
  4. //Made by Chao Xu(Mgccl) 2/28/07
  5. //www.webdevlogs.com
  6. //V 1.0
  7. if(!function_exists(‘imageconvolution’)){
  8. function imageconvolution($src, $filter, $filter_div, $offset){
  9.     if ($src==NULL) {
  10.         return 0;
  11.     }
  12.    
  13.     $sx = imagesx($src);
  14.     $sy = imagesy($src);
  15.     $srcback = ImageCreateTrueColor ($sx, $sy);
  16.     ImageCopy($srcback, $src,0,0,0,0,$sx,$sy);
  17.    
  18.     if($srcback==NULL){
  19.         return 0;
  20.     }
  21.        
  22.     for ($y=0; $y<$sy; ++$y){
  23.         for($x=0; $x<$sx; ++$x){
  24.             $new_r = $new_g = $new_b = 0;
  25.             $alpha = imagecolorat($srcback, $pxl[0], $pxl[1]);
  26.             $new_a = $alpha >> 24;
  27.            
  28.             for ($j=0; $j<3; ++$j) {
  29.                 $yv = min(max($y1 + $j, 0), $sy1);
  30.                 for ($i=0; $i<3; ++$i) {
  31.                         $pxl = array(min(max($x1 + $i, 0), $sx1), $yv);
  32.                     $rgb = imagecolorat($srcback, $pxl[0], $pxl[1]);
  33.                     $new_r += (($rgb >> 16) & 0xFF) * $filter[$j][$i];
  34.                     $new_g += (($rgb >> 8) & 0xFF) * $filter[$j][$i];
  35.                     $new_b += ($rgb & 0xFF) * $filter[$j][$i];
  36.                 }
  37.             }
  38.  
  39.             $new_r = ($new_r/$filter_div)+$offset;
  40.             $new_g = ($new_g/$filter_div)+$offset;
  41.             $new_b = ($new_b/$filter_div)+$offset;
  42.  
  43.             $new_r = ($new_r > 255)? 255 : (($new_r < 0)? 0:$new_r);
  44.             $new_g = ($new_g > 255)? 255 : (($new_g < 0)? 0:$new_g);
  45.             $new_b = ($new_b > 255)? 255 : (($new_b < 0)? 0:$new_b);
  46.  
  47.             $new_pxl = ImageColorAllocateAlpha($src, (int)$new_r, (int)$new_g, (int)$new_b, $new_a);
  48.             if ($new_pxl == -1) {
  49.                 $new_pxl = ImageColorClosestAlpha($src, (int)$new_r, (int)$new_g, (int)$new_b, $new_a);
  50.             }
  51.             if (($y >= 0) && ($y < $sy)) {
  52.                 imagesetpixel($src, $x, $y, $new_pxl);
  53.             }
  54.         }
  55.     }
  56.     imagedestroy($srcback);
  57.     return 1;
  58. }
  59. }
  60.  

Muy pronto os presentaré la versión definitiva de Imaset 2.0, qué nervios!

Categorias: Aplicaciones, Código, HOWTO/CóMO, PHP | No hay comentarios »

HOWTO/CÓMO instalar el plugin Adobe Flash Player 9 de 32bits en Mozilla Firefox DE 64bits sobre Ubuntu Feisty 64bits usando nspluginwrapper

10 de agosto del 2007 Escrito por José Cabo

flash-logo.jpgHace unos días escribí una entrada sobre porque Ubuntu Feisty de 64bits no estaba preparada para el usuario común sino más bien para el más “experto”. Una de las razones que puse fue que no podía tener el reproductor de Adobe Flash Player 9 corriendo en mi Firefox de 64bits por culpa de los gilipollas de Adobe.

Resulta que un cariñoso usuario me ayudó bastante comentándome que usando una especie de “hack” se podía rular sin problemas el plugin DE 32bits en Firefox DE 64bits. No se exactamente como funciona, el caso es que lo hace y bastante bien.

Y ahora HOWTO/CÓMO instalar el plugin de Adobe Flash Player 9 (para Linux de 32bits) en Mozilla Firefox de 64bits con nspluginwrapper [en mi caso usando Ubuntu Feisty, pero no creo que haya problemas con otras distribuciones].

Sigue leyendo esta entrada »

Categorias: GNU/Linux, HOWTO/CóMO, Web | No hay comentarios »

INNER JOIN para unir Tablas

15 de marzo del 2006 Escrito por Alex Barros

Ver también: Explicación visual de los SQL Join
Ver también: Hacer Múltiples Join en una sola Sentencia

Muy bien, aprendices del Sql, hoy hablaremos de la instrucción INNER JOIN. Muy útil para casos concretos.

Primero de todo vamos a crear una situación hipotética:

Imaginemos que tenemos que hacer una web que contiene unos artículos en referencia a comentarios de novelas, y que son doce escritores de prestigio los que van introduciendo esas críticas.

Lo normal y más básico para un programador sería pensar en base de datos y lenguaje dinámico. Una buena elección podría ser trabajar con PHP y MySql (aunque para lo que voy a decir basta con una base de datos de tipo Sql).

Lo primero que nos viene a la mente es: haré una tabla, llamémosla criticas. En ella almacenaríamos cada artículo. Los campos básicos serían ID, Libro, Escritor (del libro, nunca confundir con el autor de la crítica), Editorial, año … y Autor de la crítica.

Pero y si quisiéramos, como es normal, poner en la misma crítica una referencia al autor de la critica, aúnque sólo sea un pequeño texto biográfico? Tendríamos que repetir un mismo texto repetidas veces en la base (la biografia de doce autores en, pongamos 150 registros) y si quisieramos modificarlo y hubiera 70 entradas con ese autor… eso sería un desastre.

http://modulos.zumbe.net/imagenes/inner_join_criticas.gif

Entonces queda claro que hay que hacer una referencia a otra tabla que contenga a los autores, con sus respectivos datos. La tabla autores. Cada autor tendría su ID, su nombre y su biografía, además de otros datos como webpage, e-mail, bibliografía…

Algunos dirían: pues fácil, haces dos querys a la base. en uno le dices

  1. SELECT * FROM criticas WHERE ID =’37′

y en otra

  1. SELECT * FROM autores WHERE

where qué? tendrías que sacar una variable de sql a php, otra vez a sql…
Nada! Si alguien sugiere eso desconfiad de él y de su familia (es broma ;D) existe un método sencillo y eficaz: el INNER JOIN

Tan sencilla es la sentencia como:

  1. SELECT * FROM criticas INNER JOIN autores ON criticas.autor = autores.id WHERE criticas.id=’7′

De esta forma estamos uniendo las dos tablas, cada vez que en criticas el autor sea n, en autores se unirá su correspondiente fila, con id=n.

Traduciendo al español la sentencia dice exactamente:

SELECCIONA TODOS LOS CAMPOS UNIENDO criticas CON autores DONDE el campo autor de la tabla criticas SEA IGUAL A el campo id de la tabla autores EN EL REGISTRO EN QUE el id de criticas sea 7

En definitiva, el inner join une dos tablas, donde encajan un campo de una con el mismo de la otra.

A partir de ahora las tablas se hacen más manejables y flexibles.

Y recordad!:

  • Para seleccionar campos de cada tabla : tabla.campo universal en sql, dato importante.
  • Estructura del inner join: SELECT campos FROM tabla1 INNER JOIN tabla2 ON tabla1.campo = tabla2.campo
  • Antes de hacer barbaridades con vuestras bases de datos documentaos un poco, lo digo por experiencia ;)

Categorias: Código, HOWTO/CóMO, MySQL | 30 comentarios »

Siguientes entradas »

del.icio.us meneame.net RSS

Search:

Bicivalencia Localiza las estaciones de Valenbisi, servicio público de bicicletas en Valencia, España. Ver más Gpsia Descubre y comparte rutas por todo el mundo, tomadas con GPS. Ver más Imaset Edita tus imágenes de Wordpress con este sencillo plugin. Ver más

¡Mi música es tuya!

Digo yo que...

Mis fotos de Flickr

Entradas recientes

Meta:

Respeta el copyleft

,