todos - Recortar espacios en blanco desde la imagen en PHP
quitar espacios en texto php (6)
¿Es posible eliminar los espacios en blanco que rodean una imagen en PHP?
NOTA: para aclarar, me refiero a algo parecido a la función de ajuste photoshops.
Gracias.
La biblioteca gd de PHP tiene la función imagecropauto
:
<?php
$img=imagecreatefrompng("tux.png"); // Load and instantiate the image
if($img) {
$cropped=imagecropauto($img,IMG_CROP_DEFAULT); // Auto-crop the image
imagedestroy($img); // Clean up as $img is no longer needed
header("Content-type: image/png"); // Set the appropriate header so the browser
// knows how to present it
imagepng($cropped); // Return the newly cropped image
}
De forma predeterminada, imagecropauto
intentará recortar usando transparencia, y luego volverá a utilizar las 4 esquinas de la imagen para intentar detectar el fondo para recortar; También he tenido éxito con las siguientes constantes en lugar de IMG_CROP_AUTO
en el ejemplo anterior:
-
IMG_CROP_BLACK
- Útil para imágenes con fondo negro -
IMG_CROP_WHITE
- Útil para imágenes con fondo blanco -
IMG_CROP_THRESHOLD
: le permite establecer un color y un umbral para usar al cortar
El imagecropauto
se ha incluido en php desde la versión 5.5, para obtener más información, consulte la documentación de PHP para imagecropauto
aquí .
La secuencia de comandos de Gnud llama redundantemente imágenes e imágenes. También itera cada píxel en cada lado, incluso cuando las esquinas se superponen. Esta versión mejorada elimina las llamadas a funciones redundantes y comprueba cada píxel solo una vez, lo que garantiza un aumento significativo de la velocidad. La función devuelve un estado ($ result [''#'']) igual a 2 si cada píxel es recortado.
example();
function example(){
$img = imagecreatefromjpeg("http://ecx.images-amazon.com/images/I/413XvF0yukL._SL500_AA280_.jpg");
// find the trimmed image border
$box = imageTrimBox($img);
// copy cropped portion
$img2 = imagecreate($box[''w''], $box[''h'']);
imagecopy($img2, $img, 0, 0, $box[''l''], $box[''t''], $box[''w''], $box[''h'']);
// output cropped image to the browser
header(''Content-Type: image/png'');
imagepng($img2);
imagedestroy($img);
imagedestroy($img2);
}
function imageTrimBox($img, $hex=null){
if (!ctype_xdigit($hex)) $hex = imagecolorat($img, 0,0);
$b_top = $b_lft = 0;
$b_rt = $w1 = $w2 = imagesx($img);
$b_btm = $h1 = $h2 = imagesy($img);
do {
//top
for(; $b_top < $h1; ++$b_top) {
for($x = 0; $x < $w1; ++$x) {
if(imagecolorat($img, $x, $b_top) != $hex) {
break 2;
}
}
}
// stop if all pixels are trimmed
if ($b_top == $b_btm) {
$b_top = 0;
$code = 2;
break 1;
}
// bottom
for(; $b_btm >= 0; --$b_btm) {
for($x = 0; $x < $w1; ++$x) {
if(imagecolorat($img, $x, $b_btm-1) != $hex) {
break 2;
}
}
}
// left
for(; $b_lft < $w1; ++$b_lft) {
for($y = $b_top; $y <= $b_btm; ++$y) {
if(imagecolorat($img, $b_lft, $y) != $hex) {
break 2;
}
}
}
// right
for(; $b_rt >= 0; --$b_rt) {
for($y = $b_top; $y <= $b_btm; ++$y) {
if(imagecolorat($img, $b_rt-1, $y) != $hex) {
break 2;
}
}
}
$w2 = $b_rt - $b_lft;
$h2 = $b_btm - $b_top;
$code = ($w2 < $w1 || $h2 < $h1) ? 1 : 0;
} while (0);
// result codes:
// 0 = Trim Zero Pixels
// 1 = Trim Some Pixels
// 2 = Trim All Pixels
return array(
''#'' => $code, // result code
''l'' => $b_lft, // left
''t'' => $b_top, // top
''r'' => $b_rt, // right
''b'' => $b_btm, // bottom
''w'' => $w2, // new width
''h'' => $h2, // new height
''w1'' => $w1, // original width
''h1'' => $h1, // original height
);
}
Me doy cuenta de que esto es bastante antiguo, pero tengo una idea ligeramente diferente sobre el recorte de una imagen a través de GD. En lugar de hacer solo un lado a la vez, haga los cuatro. Es más rápido y menos costoso para la CPU en algunos aspectos. Sin embargo, si detiene los bucles FOR en el momento en que encuentre los lados superior-inferior-izquierdo-derecho, eso es más rápido que esto.
Entonces primero hay:
#
# Do all four sides at once
#
echo "Finding the top-left-bottom-right edges of the image...please wait./n";
$top = 99999;
$bot = -99999;
$left = 99999;
$right = -99999;
for( $x=$offset; $x<($w-$offset); $x++ ){
for( $y=$offset; $y<($h-$offset); $y++ ){
$rgb = imagecolorat( $gd, $x, $y );
if( $color != $rgb ){
$left = ($x < $left) ? $x : $left;
$right = ($x > $right) ? $x : $right;
$top = ($y < $top) ? $y : $top;
$bot = ($y > $bot) ? $y : $bot;
}
}
}
y luego está:
#
# Top
#
echo "Finding the top of the image/n";
$top = null;
for( $y=$offset; $y<($h-$offset); $y++ ){
for( $x=$offset; $x<($w-$offset); $x++ ){
$rgb = imagecolorat( $gd, $x, $y );
if( $color != $rgb ){ $top = $y; break; }
}
if( !is_null($top) ){ break; }
}
#
# Bottom
#
echo "Finding the bottom of the image/n";
$bot = null;
for( $y=($h-$offset); $y>$offset; $y-- ){
for( $x=$offset; $x<($w-$offset); $x++ ){
$rgb = imagecolorat( $gd, $x, $y );
if( $color != $rgb ){ $bot = $y; break; }
}
if( !is_null($bot) ){ break; }
}
#
# Left
#
echo "Finding the left of the image/n";
$left = null;
for( $x=$offset; $x<($w-$offset); $x++ ){
for( $y=$offset; $y<($h-$offset); $y++ ){
$rgb = imagecolorat( $gd, $x, $y );
if( $color != $rgb ){ $left = $x; break; }
}
if( !is_null($left) ){ break; }
}
#
# right
#
echo "Finding the right of the image/n";
$right = null;
for( $x=($w-$offset); $x>$offset; $x-- ){
for( $y=$offset; $y<($h-$offset); $y++ ){
$rgb = imagecolorat( $gd, $x, $y );
if( $color != $rgb ){ $right = $x; break; }
}
if( !is_null($right) ){ break; }
}
En ambos casos, la variable $ color contiene el primer punto de color en la imagen:
$color = imagecolorat( $gd, 0, 0 );
Esto se debe a que en las imágenes GIF, el primer punto es el 99% del tiempo el color transparente (o de fondo). Además, el $ offset es (para mí) una manera de decir que sé que la imagen solo será tan amplia y tan alta. Así que si dibujo algo que es solo un máximo de 256 por 256, pero lo pongo en un fondo de 1024 x 1024, puedo borrar parte de ese fondo y hacer un desplazamiento de 255 haciendo que los bucles FOR solo vayan de 255 a (1024 -255) o 769.
Ok, antes de que alguien pregunte, ¿POR QUÉ haría eso? Porque algunas fuentes (como Bastarda) no tienen la información de fuente correcta en ellas y una salida de 256 pt de la letra "z" produce una imagen en la parte inferior de la " z "va más allá de 256 (hasta algo así como 512) por lo que para obtener la imagen completa tienes que comenzar (o terminar) más abajo de lo que crees que sería la fuente. Así que dividí la diferencia y eliminé 255 píxeles de cada extremo. Esto fue después de ver realmente que Bastarda hace esto.
Algunas notas adicionales:
1. Imágenes PNG que PUEDE configurarse para que sean como imágenes GIF, pero normalmente tendrá que especificar cuál será el color de fondo.
2. Las imágenes JPEG NO se descomprimen de la misma manera cada vez. Así que incluso comparar la misma imagen que cargó dos veces puede no funcionar igual y puede dar diferentes tamaños.
3. Estas rutinas funcionan mejor en imágenes simples en blanco y negro (o en dos colores). Los colores múltiples pueden arrojar estas rutinas. Especialmente si decides usar tolerancias.
4. Para usar tolerancias para determinar si ha encontrado el borde de una imagen, todo lo que tiene que hacer es calcular previamente tanto la tolerancia alta como la baja (es decir: si tiene una tolerancia de cinco (5) en el componente rojo) , entonces puede calcular la tolerancia como X-5-a-x + 5 O x-2.5-a-x + 2.5 dependiendo de si desea que la tolerancia sea el rango ENTERO o solo el rango +/-). Puede tolerar las partes ROJA, VERDE, AZUL y ALFA del color o del color completo. De modo que hay varias tolerancias diferentes que puede calcular si lo desea y todas ellas son la forma correcta de hacerlo, según sus necesidades.
Mira la biblioteca de ImageMagick en PHP. Tiene buenos métodos para trabajar y manipular imágenes (incluido el crop ).
Tendrás que averiguar dónde está el "espacio en blanco" alrededor de la imagen. Podría ser un desafío, ya que el "espacio en blanco" podría ser el color blanco, algún otro color, transparencia, etc.
Para recortar todos los espacios en blanco, como usted lo llama, rodeando la parte interesante de la imagen, primero descubrimos dónde se detiene el "espacio en blanco" y luego copiamos todo dentro de esos bordes.
//load the image
$img = imagecreatefromjpeg("http://ecx.images-amazon.com/images/I/413XvF0yukL._SL500_AA280_.jpg");
//find the size of the borders
$b_top = 0;
$b_btm = 0;
$b_lft = 0;
$b_rt = 0;
//top
for(; $b_top < imagesy($img); ++$b_top) {
for($x = 0; $x < imagesx($img); ++$x) {
if(imagecolorat($img, $x, $b_top) != 0xFFFFFF) {
break 2; //out of the ''top'' loop
}
}
}
//bottom
for(; $b_btm < imagesy($img); ++$b_btm) {
for($x = 0; $x < imagesx($img); ++$x) {
if(imagecolorat($img, $x, imagesy($img) - $b_btm-1) != 0xFFFFFF) {
break 2; //out of the ''bottom'' loop
}
}
}
//left
for(; $b_lft < imagesx($img); ++$b_lft) {
for($y = 0; $y < imagesy($img); ++$y) {
if(imagecolorat($img, $b_lft, $y) != 0xFFFFFF) {
break 2; //out of the ''left'' loop
}
}
}
//right
for(; $b_rt < imagesx($img); ++$b_rt) {
for($y = 0; $y < imagesy($img); ++$y) {
if(imagecolorat($img, imagesx($img) - $b_rt-1, $y) != 0xFFFFFF) {
break 2; //out of the ''right'' loop
}
}
}
//copy the contents, excluding the border
$newimg = imagecreatetruecolor(
imagesx($img)-($b_lft+$b_rt), imagesy($img)-($b_top+$b_btm));
imagecopy($newimg, $img, 0, 0, $b_lft, $b_top, imagesx($newimg), imagesy($newimg));
//finally, output the image
header("Content-Type: image/jpeg");
imagejpeg($newimg);
Mi viejo ejemplo, que asume un "borde" idéntico en todos los lados de la imagen, solo para aclarar los comentarios :)
//load the image
$img = imagecreatefromjpeg("img.jpg");
//find the size of the border.
$border = 0;
while(imagecolorat($img, $border, $border) == 0xFFFFFF) {
$border++;
}
//copy the contents, excluding the border
//This code assumes that the border is the same size on all sides of the image.
$newimg = imagecreatetruecolor(imagesx($img)-($border*2), imagesy($img)-($border*2));
imagecopy($newimg, $img, 0, 0, $border, $border, imagesx($newimg), imagesy($newimg));
//finally, if you want, overwrite the original image
imagejpeg($newimg, "img.jpg");
Sé que esto es bastante antiguo, pero si tiene habilitado ImageMagick, puede usar este método