我希望能够在PHP中克隆使用imagecreatetruecolor
或其他图像创建函数创建的图像。
正如评论中所述,不,你不能简单地进行克隆操作,例如:
$copy = $original;
这是因为资源是引用类型,不能像标量值一样进行复制。
例如:
$a = imagecreatetruecolor(10,10);
$b = $a;
var_dump($a, $b);
// resource(2, gd)
// resource(2, gd)
这个小函数可以克隆一个图像资源并保留 alpha 通道(透明度)。
function _clone_img_resource($img) {
//Get width from image.
$w = imagesx($img);
//Get height from image.
$h = imagesy($img);
//Get the transparent color from a 256 palette image.
$trans = imagecolortransparent($img);
//If this is a true color image...
if (imageistruecolor($img)) {
$clone = imagecreatetruecolor($w, $h);
imagealphablending($clone, false);
imagesavealpha($clone, true);
}
//If this is a 256 color palette image...
else {
$clone = imagecreate($w, $h);
//If the image has transparency...
if($trans >= 0) {
$rgb = imagecolorsforindex($img, $trans);
imagesavealpha($clone, true);
$trans_index = imagecolorallocatealpha($clone, $rgb['red'], $rgb['green'], $rgb['blue'], $rgb['alpha']);
imagefill($clone, 0, 0, $trans_index);
}
}
//Create the Clone!!
imagecopy($clone, $img, 0, 0, 0, 0, $w, $h);
return $clone;
}
public function __clone() {
$original = $this->_img;
$copy = imagecreatetruecolor($this->_width, $this->_height);
imagecopy($copy, $original, 0, 0, 0, 0, $this->_width, $this->_height);
$this->_img = $copy;
}
function clone_img_resource($img) {
return imagecrop($img, array('x'=>0,'y'=>0,'width'=>imagesx($img),'height'=>imagesy($img)));
}
好的,所以我需要带透明度调整大小,我看到这个问题的答案和我的问题的答案相似但不完全相同,所以我将发布我的答案。
我想指出,我修改了此处的答案来回答我的个人需求和OP的问题。(这是关于保持将被复制/克隆/或调整大小的唯一图像的透明度)
此外:透明颜色将保留该资源,并将其应用于其他透明图像复制到它上面。我使用的解决方法是,我在我的示例中使用imagecopy()复制克隆文件以清除分配的透明颜色。
$im = imagecreatefromstring(file_get_contents('I/image.png')); //
$imw = imagesx($im); /*w*/ $imh = imagesy($im); /*h*/
$tmpIm = imagecreatetruecolor($imw, $imh); // This is black by default
imagealphablending($tmpIm, false); imagesavealpha($tmpIm, true); // Set these as usual
$wht = imagecolorallocatealpha($tmpIm, 255, 255, 255, 127); // white
imagecolortransparent($tmpIm, $wht); // Setting this seems to be unsettable and will make this color transparent on all images later coppied to it
imagealphablending($tmpIm, false); imagesavealpha($tmpIm, true); // Set these as usual
// That is it... As long as you set the transparency of the background before you copy it should work. That means now at least some of the other answers can work now.
imagecopyresampled($tmpIm, $im, 0, 0, 0, 0, $imw, $imh, $imw, $imh); // Copy or resize whatever floats your boat. The above process is what does the trick.
$newIm = imagecreatetruecolor($imw, $imh); // Begin Clone
imagealphablending($newIm, false); imagesavealpha($newIm, true); // Set these as usual
imagecopyresampled($newIm, $tmpIm, 0, 0, 0, 0, $imw, $imh, $imw, $imh); // Clearing the tranparent color previously set (Workaround)
imagedestroy($tmpIm);
header('Content-Type: image/png');
imagepng($newIm); // see I told you.. Or he did... Whatever, it works...
所以对于这个函数,它将会是:
function F_img_clone($im,$trgt,$id){
$imw = imagesx($im); $imh = imagesy($im); // Height and Width of Original
if(empty($trgt) === true){
$rsiw = $imw; $rsih = $imh; // if there are no H or W changes
}else{ // if there are H or W changes
if( $imw > $imh ) {
$pcntg = ( ($trgt??1920) / $imw );
}else{
$pcntg = ( ($trgt??1920) / $imh );
}
$rsiw = round($imw * $pcntg); $rsih = round($imh * $pcntg);
}
$ni = imagecreatetruecolor($rsiw, $rsih);// Begin the background
imagealphablending($ni, false); imagesavealpha($ni, true); // To keep the alpha channel
$wht = imagecolorallocatealpha($ni, 255, 255, 255, 127); // white
imagecolortransparent($ni, $wht); // Setting this seems to be unsettable and will make this color transparent on all images later coppied to it
imagealphablending($ni, false); imagesavealpha($ni, true);
imagecopyresampled($ni, $im, 0, 0, 0, 0, $rsiw, $rsih, $imw, $imh);
imagealphablending($ni, true); imagesavealpha($ni, false);
imagedestroy($im);
$imw = imagesx($ni); /*h*/ $imh = imagesy($ni); /*w*/
${$id} = imagecreatetruecolor($imw, $imh); // Begin Clone
imagealphablending(${$id}, false); imagesavealpha(${$id}, true); // Set these as usual
imagecopyresampled(${$id}, $ni, 0, 0, 0, 0, $imw, $imh, $imw, $imh); // Clearing the tranparent color previously set (Workaround)
imagedestroy($ni);
return ${$id};
}
所以使用它的方式是:
$image = imagecreatefromstring(file_get_contents('I/image.png')); //
$clone = F_img_clone($image,'','clone');
原始的$image将保持不变。
imagecreatetruecolor
返回一个resource。因此,不能只使用简单的赋值,因为$img1
和$img2
都将指向相同的资源。 - user895378imagecopy
。 - user895378