2

外部フィードからの画像をキャッシュし、サイトで画像が表示されたときにサーバーのディレクトリに保存するスクリプトがあります。

現時点では、元の画像をサーバーに保存し、幅が 300px と 150px にサイズ変更された 2 つの追加のサムネイルを作成しています。

これを少し変更して、次のことが発生するようにしたいと思います。

  1. フル/元の画像はサーバーに保存されます(通常どおり)
  2. 正方形の300x300px と 150x150pxの両方の.jpg サムネイルが作成されます

ただし、画像の幅/高さのサイズが変更されると、追加のキャンバスの幅/高さが追加されて完全に正方形になる可能性はありますか? ここでの問題の1つは、最初に画像が「ポートレート」か「ランドスケープ」かを判断することだと思いますか?

また、現在、透明な PNG 画像で黒の背景を取得しています。これを克服し、代わりに背景を白で塗りつぶす方法はありますか?

助けてくれてありがとうございました!! :)

サイズ変更を行うコード (imageCache.php) は次のとおりです。

<?php
  function cacheFetch($url,$size,$age)
  {
// directory in which to store cached files, must be writable by PHP
$cacheDir = "cache/";
// cache filename constructed from MD5 hash of URL
$filename = $cacheDir.md5($url);
// append size to filename if not 0
if ($size) $filename .= "_".$size;
// default to fetch the file
$fetch = true;
// but if the file exists, don't fetch if it is recent enough
if (file_exists($filename))
{
  $fetch = (filemtime($filename) < (time()-$age));
}
// fetch the file if required
if ($fetch)
{
  if (substr($url,0,4)=="http")
  {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
    $data = curl_exec($ch);
    curl_close($ch);
    if (strlen($data))
    {
      $fp = fopen($filename,"w");
      fwrite($fp,$data);
      fclose($fp);
      $error = false;
    }
    else
    {
      $error = true;
    }
  }
  else
  {
    copy($url,$filename);
    $error = false;
  }
}
// return the filename only if wget did not fail
if (!$error)
{
  if ($size)
  {
    $src = file_get_contents($filename);
    $oldImage = imagecreatefromstring($src);
    $oldX = imagesx($oldImage);
    $oldY = imagesy($oldImage);
    if ($oldX && $oldY)
    {
      $newX = $size;
      $xFactor = ($newX / $oldX);
      $newY = intval($oldY * $xFactor);
      $newImage = imagecreatetruecolor($newX,$newY);
      imagecopyresized($newImage, $oldImage, 0,0,0,0, $newX, $newY, $oldX, $oldY);
      imagejpeg($newImage,$filename);
    }
  }
  return $filename;
}
else
{
  // as an error occured, delete the empty file so it is retried next time
  unlink($filename);
  // return false
  return false;
}
}
require("includes/common.php");

$id = $_GET["id"];

$size = $_GET["size"];

$sql = "SELECT image_url FROM `".$config_databaseTablePrefix."products` WHERE id='".database_safe($id)."'";
if (database_querySelect($sql,$rows))
{
$src = $rows[0]["image_url"];

$src = cacheFetch($src,$size,604800);

$img = file_get_contents($src);

header("Content-Type: image");

print $img;
  }
?>

そして、サイズの .htaccess ビットは次のとおりです。

RewriteRule ^fullimage/(.*).jpg$ imageCache.php?id=$1&size=0 [L]
RewriteRule ^smallimage/(.*).jpg$ imageCache.php?id=$1&size=150 [L]
RewriteRule ^mediumimage/(.*).jpg$ imageCache.php?id=$1&size=300 [L]

編集:再加工されたコード:

if ($size)
{
    $src = file_get_contents($filename);
    $oldImage = imagecreatefromstring($src);
    $oldX = imagesx($oldImage);
    $oldY = imagesy($oldImage);
    if ($oldX && $oldY)
    {
      $color = imagecolorallocate($newImage, 255,255,255);  //The three parameters are R,G,B
  imagefilledrectangle ($newImage, 0, 0, $newX,  $newY,$color);
      $size = max($newX,$newY);
      $newImage = imagecreatetruecolor($newX,$newY);
      imagecopyresized($newImage, $oldImage, ($size-$newX)/2,($size-$newY)/2,0,0, $newX, $newY, $oldX, $oldY);  //Just the coordinates was changed
      imagejpeg($newImage,$filename);
4

1 に答える 1

2

申し訳ありませんが、コードが複雑すぎるため、コードに私の提案を追加しません。ヒントだけです。

1. リサイズした画像を正方形にするには?

明らかに、元の画像のより大きな次元のサイズの正方形を作成する必要があります。ここでは、画像のサイズが既に変更されていると仮定します。

$resized = /*We hae resized image downloaded from the site [note1]*/;
$size = max(imagesx($resized), imagesy($resized)); //Make the square so the thumbnail fits in it
$thumbNail = imagecreate($size, $size);  //Square.
imagecopy($thumbNail, 
          ($size-imagesx($resized))/2,   //Put the image in the middle of the square
          ($size-imagesy($resized))/2, 
          0,
          0,
          imagesx($resized),
          imagesy($resized)  
);

[note1]または、寸法を計算して $size を作成し、正方形に画像をコピーすることもできます。これは高速ですが、疑似コードを作成するのはより複雑です。

2. 新しい画像の背景を変更する方法

これは本当のミステリーではありません。画像全体に長方形を描くだけです。

$color = imagecolorallocate($thumbNail, 255,255,255);
imagefilledrectangle ($thumbNail, 0, 0, imagesx($thumbNail),  imagesy($thumbNail),$color);

背景を透明にすることもできます。

$color = imagecolorallocatealpha($thumbNail, 255,255,255,127);
imagealphablending($thumbNail, false);  //[note2]
imagefilledrectangle ($thumbNail, 0, 0, imagesx($thumbNail),  imagesy($thumbNail),$color);
imagealphablending($thumbNail, true);  //If you use it

[注 2]再びtransparent+ black=になるため、ブレンディングをオフにしますblack

3.回答に関連するコード

まずはリサイズ、コピー。元のコードでは、計算された新しい高さと幅がと に$newXあり$newYます。これらを新しい画像サイズとして使用します。

$size = max($newX,$newY);
$newImage = imagecreatetruecolor($size, $size);
imagecopyresized($newImage, $oldImage, ($size-$newX)/2,($size-$newY)/2,0,0, $newX, $newY, $oldX, $oldY);  //Just the coordinates was changed

それから彼は背景。明らかに、最初に背景を設定してから、画像をコピーする必要があります。ただし、どの関数が何を行うかを確認できるように、これらの手順を分けています。

 $newImage = imagecreatetruecolor($newX,$newY);
 $color = imagecolorallocate($newImage, 255,255,255);  //The three parameters are R,G,B
 imagefilledrectangle ($newImage, 0, 0, $newX,  $newY,$color);
于 2013-02-10T15:48:16.093 に答える