Php gd未将白色背景添加到透明PNG
我有个小问题。我的脚本通过基于url查询的目录。执行此操作时,它会为这些图像创建缩略图。现在的问题是,它创建PNG缩略图,但不是透明的或至少是白色的背景,而是标准的黑色 这是代码,有人能指出我在代码中的问题吗,或者我可能遗漏了什么Php gd未将白色背景添加到透明PNG,php,image-processing,gd,Php,Image Processing,Gd,我有个小问题。我的脚本通过基于url查询的目录。执行此操作时,它会为这些图像创建缩略图。现在的问题是,它创建PNG缩略图,但不是透明的或至少是白色的背景,而是标准的黑色 这是代码,有人能指出我在代码中的问题吗,或者我可能遗漏了什么 <?php $folder = $_GET['folder']; //POST if from form, GET if from URL $thisdir = getcwd(); if(!file_exists($thisdir ."/"."$folder/
<?php
$folder = $_GET['folder']; //POST if from form, GET if from URL
$thisdir = getcwd();
if(!file_exists($thisdir ."/"."$folder/thumbs")) {
mkdir($thisdir ."/"."$folder/thumbs" , 0777);
}
function returnimages($dirname="") {
$pattern="(\.jpg$)|(\.png$)|(\.jpeg$)|(\.gif$)"; //valid image extensions
$handle = opendir($dirname);
while(false !== ($filename = readdir($handle))) {
if(eregi($pattern, $filename)){ //if this file is a valid image
$files[] = $filename;
}
}
if (count($files)<>0) {
sort($files);
}
$curimage=0;
while($curimage !== count($files)){
$cropfile=$dirname.'/'.$files[$curimage];echo '<br>'.$cropfile;
if(preg_match('/[.](jpg)|(jpeg)$/', $cropfile)) {
$source_img = imagecreatefromjpeg($cropfile);
} elseif(preg_match('/[.](png)$/', $cropfile)) {
imagealphablending($source_img, false);
imagesavealpha($source_img, true);
$source_img = imagecreatefrompng($cropfile);
} elseif(preg_match('/[.](gif)$/', $cropfile)) {
$source_img = imagecreatefromgif($cropfile);
} else {
echo "Code 43: Unable to read file type.";
exit(0);
}
if (!$source_img) {
echo "could not create image handle";
exit(0);
}
$new_w = 480;
$new_h = 480;
$orig_w = imagesx($source_img);
$orig_h = imagesy($source_img);
$w_ratio = ($new_w / $orig_w);
$h_ratio = ($new_h / $orig_h);
if ($orig_w > $orig_h ) {//landscape from here new
$crop_w = round($orig_w * $h_ratio);
$crop_h = $new_h;
$src_x = ceil( ( $orig_w - $orig_h ) / 2 );
$src_y = 0;
} elseif ($orig_w < $orig_h ) {//portrait
$crop_h = round($orig_h * $w_ratio);
$crop_w = $new_w;
$src_x = 0;
$src_y = ceil( ( $orig_h - $orig_w ) / 2 );
} else {//square
$crop_w = $new_w;
$crop_h = $new_h;
$src_x = 0;
$src_y = 0;
}
$dest_img = imagecreatetruecolor($new_w,$new_h);
imagecopyresampled($dest_img, $source_img, 0 , 0 , $src_x, $src_y, $crop_w, $crop_h, $orig_w, $orig_h); //till here
if(imagejpeg($dest_img, $dirname."/thumbs/".$files[$curimage], 80)) {
imagedestroy($dest_img);
imagedestroy($source_img);
} else {
echo "could not make thumbnail image";
exit(0);
}
$curimage++;
}
}
returnimages($name=$folder);
?>
这是因为您正在使用
imagejpeg
作为每种可能的图像类型的输出函数。我在循环中更改了您的代码以使其正常工作:
// Add these defines somewhere at the top
define('TYPE_JPEG', 0);
define('TYPE_PNG', 1);
define('TYPE_GIF', 2);
// ... skipping some code. Here goes while loop iterating over every image
while($curimage !== count($files)){
$cropfile=$dirname.'/'.$files[$curimage];echo '<br>'.$cropfile;
// Determine type of the image
if(preg_match('/[.](jpg)|(jpeg)$/', $cropfile)) {
$source_img = imagecreatefromjpeg($cropfile);
$type = TYPE_JPEG;
} elseif(preg_match('/[.](png)$/', $cropfile)) {
$source_img = imagecreatefrompng($cropfile);
$type = TYPE_PNG;
} elseif(preg_match('/[.](gif)$/', $cropfile)) {
$source_img = imagecreatefromgif($cropfile);
$type = TYPE_GIF;
} else {
echo "Code 43: Unable to read file type.";
exit(0);
}
if (!$source_img) {
echo "could not create image handle";
exit(0);
}
$new_w = 480;
$new_h = 480;
$orig_w = imagesx($source_img);
$orig_h = imagesy($source_img);
$w_ratio = ($new_w / $orig_w);
$h_ratio = ($new_h / $orig_h);
if ($orig_w > $orig_h ) {//landscape from here new
$crop_w = round($orig_w * $h_ratio);
$crop_h = $new_h;
$src_x = ceil( ( $orig_w - $orig_h ) / 2 );
$src_y = 0;
} elseif ($orig_w < $orig_h ) {//portrait
$crop_h = round($orig_h * $w_ratio);
$crop_w = $new_w;
$src_x = 0;
$src_y = ceil( ( $orig_h - $orig_w ) / 2 );
} else {//square
$crop_w = $new_w;
$crop_h = $new_h;
$src_x = 0;
$src_y = 0;
}
$dest_img = imagecreatetruecolor($new_w,$new_h);
$dest_path = $dirname."/thumbs/".$files[$curimage];
switch ($type) {
case TYPE_JPEG:
imagecopyresampled($dest_img, $source_img, 0 , 0 , $src_x, $src_y, $crop_w, $crop_h, $orig_w, $orig_h);
$success = imagejpeg($dest_img, $dest_path, 80);
break;
case TYPE_PNG:
// Preserve alpha
imagesavealpha($dest_img, true);
// Create transparent color
$color = imagecolorallocatealpha($dest_img, 0, 0, 0, 127);
// Fill in background
imagefill($dest_img, 0, 0, $color);
// Copy from source
imagecopyresampled($dest_img, $source_img, 0 , 0 , $src_x, $src_y, $crop_w, $crop_h, $orig_w, $orig_h);
$success = imagepng($dest_img, $dest_path);
break;
default:
$black = imagecolorallocate($dest_img, 0, 0, 0);
// This will make the background transparent
imagecolortransparent($dest_img, $black);
// Copy from source
imagecopyresampled($dest_img, $source_img, 0 , 0 , $src_x, $src_y, $crop_w, $crop_h, $orig_w, $orig_h);
$success = imagegif($dest_img, $dest_path);
break;
}
if($success) {
imagedestroy($dest_img);
imagedestroy($source_img);
} else {
echo "could not make thumbnail image";
exit(0);
}
$curimage++;
}
//在顶部某处添加这些定义
定义('TYPE_JPEG',0);
定义('TYPE_PNG',1);
定义('TYPE_GIF',2);
// ... 跳过一些代码。下面是循环遍历每个图像时的情况
而($curimage!==计数($files)){
$cropfile=$dirname.'/'.$files[$curimage];echo'
'.$cropfile;
//确定图像的类型
if(preg_match('/[.(jpg)|(jpeg)$/',$cropfile)){
$source\u img=imagecreatefromjpeg($cropfile);
$type=type\U JPEG;
}elseif(预匹配('/[.](png)$/',$cropfile)){
$source\u img=imagecreatefrompng($cropfile);
$type=type\u PNG;
}elseif(preg_match('/[.](gif)$/',$cropfile)){
$source\u img=imagecreatefromformgif($cropfile);
$type=type\u GIF;
}否则{
echo“代码43:无法读取文件类型。”;
出口(0);
}
如果(!$source\u img){
echo“无法创建图像句柄”;
出口(0);
}
$new_w=480;
$new_h=480;
$orig_w=imagesx($source_img);
$orig\U h=imagesy($source\U img);
$w_比率=($new_w/$orig_w);
$h_比率=($new_h/$orig_h);
如果($orig_w>$orig_h){//从这里开始新的风景
$crop\U w=圆形($orig\U w*$h\U比率);
$crop_h=$new_h;
$src_x=ceil($orig_w-$orig_h)/2);
$src_y=0;
}elseif($orig_w<$orig_h){//肖像
$crop_h=圆形($orig_h*$w_比率);
$crop_w=$new_w;
$src_x=0;
$src_y=ceil($orig_h-$orig_w)/2);
}else{//square
$crop_w=$new_w;
$crop_h=$new_h;
$src_x=0;
$src_y=0;
}
$dest_img=ImageCreateTureColor($new_w,$new_h);
$dest_path=$dirname./thumbs/“$files[$curimage];
交换机($类型){
案例类型\u JPEG:
imagecopyresampled($dest\u img,$source\u img,0,0,$src\u x,$src\u y,$crop\u w,$crop\u h,$orig\u w,$orig\u h);
$success=imagejpeg($dest\u img,$dest\u path,80);
打破
案例类型\u PNG:
//保留阿尔法
imagesavealpha($dest_img,true);
//创建透明颜色
$color=imagecolorallocatealpha($dest_img,0,0,0127);
//填写背景
图像填充($dest_img,0,0,$color);
//从源代码复制
imagecopyresampled($dest\u img,$source\u img,0,0,$src\u x,$src\u y,$crop\u w,$crop\u h,$orig\u w,$orig\u h);
$success=imagepng($dest\u img,$dest\u path);
打破
违约:
$black=imagecolorallocate($dest\u img,0,0,0);
//这将使背景透明
imagecolortransparent($dest\u img,$black);
//从源代码复制
imagecopyresampled($dest\u img,$source\u img,0,0,$src\u x,$src\u y,$crop\u w,$crop\u h,$orig\u w,$orig\u h);
$success=imagegif($dest\u img,$dest\u path);
打破
}
如果($成功){
图像销毁($dest\u img);
图像销毁($source\u img);
}否则{
echo“无法生成缩略图”;
出口(0);
}
$curimage++;
}
如您所见,根据文件类型,我们使用不同的输出函数:、和。PNG和GIF文件需要一些额外的操作以保持透明度。我已经在Windows下的PHP5.2.13上使用JPEG、GIF和PNG(透明和常规)文件对它进行了测试,看起来一切正常。您可以调整其他参数,例如采用可选的$quality
和$filters
参数
此外,关于守则:
- 最重要的规则:不要相信用户输入。您正在根据
$\u GET
的值创建目录,这可能是不安全的,因为用户可以传递类似'/../../../../../../etc'的内容
- 清理一下不会有什么坏处。使用
foreach
代替while
循环计数器。我想我可以检索文件列表。和returnimages($name=$folder)代码>呼叫对我来说没有意义。你真的需要分配和呼叫一条线路吗