我一直在研究(并尝试)使用PHP 5.6从PNG图像中裁剪或修剪空白的不同方法:
Crop whitespace from image in PHP
https://gist.github.com/ericpedia/3583170
http://php.net/manual/en/function.imagecropauto.php
https://deano.me/2015/01/trim-an-image-using-php-gd/
我也读过Imagick,但是下载包含许多源文件,我担心在本地和服务器上安装和运行可能很麻烦。无论如何,我都不希望像这样的笨重的库比我需要的库多100倍,我只想修剪空白就可以了。
这是我尝试过的:
function CropPNG($img){
//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
}
}
}
$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));
imagepng($newimg);
return $newimg;
}
function imagetrim($im, $bgcol, $pad=null){
// Calculate padding for each side.
if (isset($pad)){
$pada = explode(' ', $pad);
if (isset($pada[3])){
$p = array((int) $pada[0], (int) $pada[1], (int) $pada[2], (int) $pada[3]);
}else if (isset($pada[2])){
$p = array((int) $pada[0], (int) $pada[1], (int) $pada[2], (int) $pada[1]);
}else if (isset($pada[1])){
$p = array((int) $pada[0], (int) $pada[1], (int) $pada[0], (int) $pada[1]);
}else{
$p = array_fill(0, 4, (int) $pada[0]);
}
}else{
$p = array_fill(0, 4, 0);
}
// Get the width and height of the image.
$imw = imagesx($im);
$imh = imagesy($im);
// Set the X variables.
$xmin = $imw;
$xmax = 0;
// find the endges.
for ($iy=0; $iy<$imh; $iy++) {
$first = true;
for ($ix=0; $ix<$imw; $ix++) {
$ndx = imagecolorat($im, $ix, $iy);
if ($ndx != $bgcol) {
if ($xmin > $ix) { $xmin = $ix; }
if ($xmax < $ix) { $xmax = $ix; }
if (!isset($ymin)) { $ymin = $iy; }
$ymax = $iy;
if ($first) { $ix = $xmax; $first = false; }
}
}
}
// The new width and height of the image. (not including padding)
$imw = 1+$xmax-$xmin; // Image width in pixels
$imh = 1+$ymax-$ymin; // Image height in pixels
// Make another image to place the trimmed version in.
$im2 = imagecreatetruecolor($imw+$p[1]+$p[3], $imh+$p[0]+$p[2]);
// Make the background of the new image the same as the background of the old one.
$bgcol2 = imagecolorallocate($im2, ($bgcol >> 16) & 0xFF, ($bgcol >> 8) & 0xFF, $bgcol & 0xFF);
imagefill($im2, 0, 0, $bgcol2);
// Copy it over to the new image.
imagecopy($im2, $im, $p[3], $p[0], $xmin, $ymin, $imw, $imh);
// To finish up, return the new image.
return $im2;
}
function ConvertBase64ImageDataToPNG($imgData, $path){
$image_parts = explode(";base64,", $imgData);
$image_type_aux = explode("image/", $image_parts[0]);
$image_type = $image_type_aux[1];
$img = base64_decode($image_parts[1]);
//$img = CropPNG($img);
//$img = imagecropauto($img, IMG_CROP_DEFAULT);
//$img = imagetrim($img, imagecolorallocate($img, 0xFF, 0xFF, 0xFF), 1);
file_put_contents($path, $img);
}
请注意我的最终功能ConvertBase64ImageDataToPNG()
-效果很好,只是没有修剪/修剪。这3条注释掉的行是我尝试裁剪的行,没有任何工作。我将PNG文件写入磁盘,但该文件已损坏并且无法显示。对于我得到from here的CropPNG()
,我认为我的最后两行是错误的。我进行了修改,因为它说使用header()
,仅当将png流式传输到我认为的浏览器时才需要,而我不是,我只是想将其写入磁盘。
我不需要花哨的东西,奇特的东西或灵活的东西-我只想要一种简单的方法来从PNG签名文件(手写内容)中裁剪空白,然后将其上传到我的PHP Webapp中。这些PNG签名文件很多时候都需要在签名周围包含很多空白,我需要对其进行裁剪。
在此先感谢您的帮助。