9

imagecreatetruecolorまたは他の画像作成関数で作成されたPHPで画像のクローンを作成したいと思っています。

コメントで言われたように、あなたは次のような単純な愛情をすることはできません:

$copy = $original;

これは、リソースが参照であり、スカラー値のようにコピーできなかったためです。

例 :

$a = imagecreatetruecolor(10,10);
$b = $a;

var_dump($a, $b);

// resource(2, gd)

// resource(2, gd)
4

4 に答える 4

7

この小さな関数は、アルファチャネル(透明度)を保持しながら画像リソースのクローンを作成します。

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;
}
于 2013-02-04T16:05:03.600 に答える
6

したがって、見つかった解決策はコメントにあり、これは画像管理クラスでの実装です。

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;
}
于 2012-09-26T16:53:01.767 に答える
1

はるかに単純なコード、1行で、透過性を処理します。

function clone_img_resource($img) {
    return imagecrop($img, array('x'=>0,'y'=>0,'width'=>imagesx($img),'height'=>imagesy($img)));
}
于 2018-03-11T20:50:36.487 に答える
0

わかりました。透明度を使用してサイズを変更する必要がありました。この質問の回答と質問の回答は似ていますが、まったく同じではないので、回答を投稿します。

私の個人的なニーズと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はそのまま残ります。

于 2020-06-18T04:54:30.540 に答える