Matrices para desenfocar
Escrito por Alex Barros
Efectivamente. 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.

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:
-
$im = imagecreatefromjpeg(‘fotografia.jpg’);
-
);
-
imageconvolution($im, $matrix, 16, 0);
-
imagejpeg($im,‘fotografia_blur.jpg’);
-
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:
-
//include this file whenever you have to use imageconvolution…
-
//you can use in your project, but keep the comment below
-
//great for any image manipulation library
-
//Made by Chao Xu(Mgccl) 2/28/07
-
//www.webdevlogs.com
-
//V 1.0
-
function imageconvolution($src, $filter, $filter_div, $offset){
-
if ($src==NULL) {
-
return 0;
-
}
-
-
$sx = imagesx($src);
-
$sy = imagesy($src);
-
$srcback = ImageCreateTrueColor ($sx, $sy);
-
ImageCopy($srcback, $src,0,0,0,0,$sx,$sy);
-
-
if($srcback==NULL){
-
return 0;
-
}
-
-
for ($y=0; $y<$sy; ++$y){
-
for($x=0; $x<$sx; ++$x){
-
$new_r = $new_g = $new_b = 0;
-
$alpha = imagecolorat($srcback, $pxl[0], $pxl[1]);
-
$new_a = $alpha >> 24;
-
-
for ($j=0; $j<3; ++$j) {
-
for ($i=0; $i<3; ++$i) {
-
$rgb = imagecolorat($srcback, $pxl[0], $pxl[1]);
-
$new_r += (($rgb >> 16) & 0xFF) * $filter[$j][$i];
-
$new_g += (($rgb >> 8) & 0xFF) * $filter[$j][$i];
-
$new_b += ($rgb & 0xFF) * $filter[$j][$i];
-
}
-
}
-
-
$new_r = ($new_r/$filter_div)+$offset;
-
$new_g = ($new_g/$filter_div)+$offset;
-
$new_b = ($new_b/$filter_div)+$offset;
-
-
$new_r = ($new_r > 255)? 255 : (($new_r < 0)? 0:$new_r);
-
$new_g = ($new_g > 255)? 255 : (($new_g < 0)? 0:$new_g);
-
$new_b = ($new_b > 255)? 255 : (($new_b < 0)? 0:$new_b);
-
-
$new_pxl = ImageColorAllocateAlpha($src, (int)$new_r, (int)$new_g, (int)$new_b, $new_a);
-
if ($new_pxl == -1) {
-
$new_pxl = ImageColorClosestAlpha($src, (int)$new_r, (int)$new_g, (int)$new_b, $new_a);
-
}
-
if (($y >= 0) && ($y < $sy)) {
-
imagesetpixel($src, $x, $y, $new_pxl);
-
}
-
}
-
}
-
imagedestroy($srcback);
-
return 1;
-
}
-
}
-
Muy pronto os presentaré la versión definitiva de Imaset 2.0, qué nervios!
Categorias: Aplicaciones, Código, HOWTO/CóMO, PHP |



Respeta el copyleft