PHP의 GDlib imagecopyresampled를 사용할 때 PNG 이미지 투명도를 유지할 수 있습니까?
다음 PHP 코드 스 니펫은 GD를 사용하여 브라우저에 업로드 된 PNG의 크기를 128x128로 조정합니다. 제 경우에는 원본 이미지의 투명 영역이 단색 검정으로 대체된다는 점을 제외하면 훌륭하게 작동합니다.
imagesavealpha
설정되어 있지만 뭔가 잘못되었습니다.
리샘플링 된 이미지에서 투명도를 유지하는 가장 좋은 방법은 무엇입니까?
$uploadTempFile = $myField[ 'tmp_name' ]
list( $uploadWidth, $uploadHeight, $uploadType )
= getimagesize( $uploadTempFile );
$srcImage = imagecreatefrompng( $uploadTempFile );
imagesavealpha( $targetImage, true );
$targetImage = imagecreatetruecolor( 128, 128 );
imagecopyresampled( $targetImage, $srcImage,
0, 0,
0, 0,
128, 128,
$uploadWidth, $uploadHeight );
imagepng( $targetImage, 'out.png', 9 );
imagealphablending( $targetImage, false );
imagesavealpha( $targetImage, true );
나를 위해 해냈어. 감사합니다 ceejayoz.
대상 이미지에는 소스 이미지가 아닌 알파 설정이 필요합니다.
편집 : 전체 대체 코드. 아래 답변과 의견도 참조하십시오. 이것은 어떤 식 으로든 완벽하다고 보장되지는 않지만 당시 내 요구를 충족 시켰습니다.
$uploadTempFile = $myField[ 'tmp_name' ]
list( $uploadWidth, $uploadHeight, $uploadType )
= getimagesize( $uploadTempFile );
$srcImage = imagecreatefrompng( $uploadTempFile );
$targetImage = imagecreatetruecolor( 128, 128 );
imagealphablending( $targetImage, false );
imagesavealpha( $targetImage, true );
imagecopyresampled( $targetImage, $srcImage,
0, 0,
0, 0,
128, 128,
$uploadWidth, $uploadHeight );
imagepng( $targetImage, 'out.png', 9 );
왜 그렇게 복잡하게 만드나요? 다음은 내가 사용하는 것이며 지금까지 나를 위해 일했습니다.
$im = ImageCreateFromPNG($source);
$new_im = imagecreatetruecolor($new_size[0],$new_size[1]);
imagecolortransparent($new_im, imagecolorallocate($new_im, 0, 0, 0));
imagecopyresampled($new_im,$im,0,0,0,0,$new_size[0],$new_size[1],$size[0],$size[1]);
나는 이것이 트릭을해야한다고 믿는다.
$srcImage = imagecreatefrompng($uploadTempFile);
imagealphablending($srcImage, false);
imagesavealpha($srcImage, true);
edit: Someone in the PHP docs claims imagealphablending
should be true, not false. YMMV.
An addition that might help some people:
It is possible to toggle imagealphablending while building the image. I the specific case that I needed this, I wanted to combine some semi-transparent PNG's on a transparent background.
First you set imagealphablending to false and fill the newly created true color image with a transparent color. If imagealphablending were true, nothing would happen because the transparent fill would merge with the black default background and result in black.
Then you toggle imagealphablending to true and add some PNG images to the canvas, leaving some of the background visible (ie. not filling up the entire image).
The result is an image with a transparent background and several combined PNG images.
I have made a function for resizing image like JPEG/GIF/PNG with copyimageresample
and PNG images still keep there transparency:
$myfile=$_FILES["youimage"];
function ismyimage($myfile) {
if((($myfile["type"] == "image/gif") || ($myfile["type"] == "image/jpg") || ($myfile["type"] == "image/jpeg") || ($myfile["type"] == "image/png")) && ($myfile["size"] <= 2097152 /*2mb*/) ) return true;
else return false;
}
function upload_file($myfile) {
if(ismyimage($myfile)) {
$information=getimagesize($myfile["tmp_name"]);
$mywidth=$information[0];
$myheight=$information[1];
$newwidth=$mywidth;
$newheight=$myheight;
while(($newwidth > 600) || ($newheight > 400 )) {
$newwidth = $newwidth-ceil($newwidth/100);
$newheight = $newheight-ceil($newheight/100);
}
$files=$myfile["name"];
if($myfile["type"] == "image/gif") {
$tmp=imagecreatetruecolor($newwidth,$newheight);
$src=imagecreatefromgif($myfile["tmp_name"]);
imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newwidth, $newheight, $mywidth, $myheight);
$con=imagegif($tmp, $files);
imagedestroy($tmp);
imagedestroy($src);
if($con){
return true;
} else {
return false;
}
} else if(($myfile["type"] == "image/jpg") || ($myfile["type"] == "image/jpeg") ) {
$tmp=imagecreatetruecolor($newwidth,$newheight);
$src=imagecreatefromjpeg($myfile["tmp_name"]);
imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newwidth, $newheight, $mywidth, $myheight);
$con=imagejpeg($tmp, $files);
imagedestroy($tmp);
imagedestroy($src);
if($con) {
return true;
} else {
return false;
}
} else if($myfile["type"] == "image/png") {
$tmp=imagecreatetruecolor($newwidth,$newheight);
$src=imagecreatefrompng($myfile["tmp_name"]);
imagealphablending($tmp, false);
imagesavealpha($tmp,true);
$transparent = imagecolorallocatealpha($tmp, 255, 255, 255, 127);
imagefilledrectangle($tmp, 0, 0, $newwidth, $newheight, $transparent);
imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newwidth, $newheight, $mywidth, $myheight);
$con=imagepng($tmp, $files);
imagedestroy($tmp);
imagedestroy($src);
if($con) {
return true;
} else {
return false;
}
}
} else
return false;
}
I suppose that this might do the trick:
$uploadTempFile = $myField[ 'tmp_name' ]
list( $uploadWidth, $uploadHeight, $uploadType )
= getimagesize( $uploadTempFile );
$srcImage = imagecreatefrompng( $uploadTempFile );
$targetImage = imagecreatetruecolor( 128, 128 );
$transparent = imagecolorallocate($targetImage,0,255,0);
imagecolortransparent($targetImage,$transparent);
imagefilledrectangle($targetImage,0,0,127,127,$transparent);
imagecopyresampled( $targetImage, $srcImage,
0, 0,
0, 0,
128, 128,
$uploadWidth, $uploadHeight );
imagepng( $targetImage, 'out.png', 9 );
The downside is that the image will be stripped of every 100% green pixels. Anyhow, hope it helps :)
Regrading the preserve transparency, then yes like stated in other posts imagesavealpha() have to be set to true, to use the alpha flag imagealphablending() must be set to false else it doesn't work.
Also I spotted two minor things in your code:
- You don't need to call
getimagesize()
to get the width/height forimagecopyresmapled()
- The
$uploadWidth
and$uploadHeight
should be-1
the value, since the cordinates starts at0
and not1
, so it would copy them into an empty pixel. Replacing it with:imagesx($targetImage) - 1
andimagesy($targetImage) - 1
, relativily should do :)
Here is my total test code. It works for me
$imageFileType = pathinfo($_FILES["image"]["name"], PATHINFO_EXTENSION);
$filename = 'test.' . $imageFileType;
move_uploaded_file($_FILES["image"]["tmp_name"], $filename);
$source_image = imagecreatefromjpeg($filename);
$source_imagex = imagesx($source_image);
$source_imagey = imagesy($source_image);
$dest_imagex = 400;
$dest_imagey = 600;
$dest_image = imagecreatetruecolor($dest_imagex, $dest_imagey);
imagecopyresampled($dest_image, $source_image, 0, 0, 0, 0, $dest_imagex, $dest_imagey, $source_imagex, $source_imagey);
imagesavealpha($dest_image, true);
$trans_colour = imagecolorallocatealpha($dest_image, 0, 0, 0, 127);
imagefill($dest_image, 0, 0, $trans_colour);
imagepng($dest_image,"test1.png",1);
Pay attention to the source image's width
and height
values which are passed to imagecopyresampled
function. If they are bigger than actual source image size, the rest of image area will be filled with black color.
I combined the answers from ceejayoz and Cheekysoft, which gave the best result for me. Without imagealphablending() and imagesavealpha() the image is not clear:
$img3 = imagecreatetruecolor(128, 128);
imagecolortransparent($img3, imagecolorallocate($img3, 0, 0, 0));
imagealphablending( $img3, false );
imagesavealpha( $img3, true );
imagecopyresampled($img3, $srcImage, 0, 0, 0, 0, 128, 128, $uploadWidth, $uploadHeight);
imagepng($img3, 'filename.png', 9);
'Programing' 카테고리의 다른 글
문자열에 10 자 중 하나가 포함되어 있는지 확인 (0) | 2020.08.23 |
---|---|
압축을 풀지 않고 Unix .tar.gz 파일이 유효한 파일인지 확인하는 방법은 무엇입니까? (0) | 2020.08.23 |
Python에서 소스 파일 이름 및 줄 번호를 기록하는 방법 (0) | 2020.08.23 |
SELF JOIN이란 무엇이며 언제 사용합니까? (0) | 2020.08.23 |
Ipython 노트북 / Jupyter에서 Pandas는 내가 플롯하려는 그래프를 표시하지 않습니다. (0) | 2020.08.23 |