2

我有一个脚本,它缓存来自外部提要的图像,并在现场查看图像时将它们存储在我服务器上的目录中。

目前它工作得很好 - 将原始图像存储在我的服务器上并创建两个额外的缩略图,它们的宽度重新调整为 300 像素和 150 像素。

我想稍微改变一下,以便发生以下情况:

  1. 完整/原始图像存储在服务器上(正常)
  2. 创建了一个300x300px 和 150x150px 的正方形 .jpg缩略图

但是,是否有可能,一旦图像宽度/高度调整大小,然后添加额外的画布宽度/高度以使其完全正方形?我想这里的问题之一是首先确定图像是“肖像”还是“风景”?

此外,目前我正在获得带有透明 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 和 copyresize 图像。这会更快,但为它制作伪代码更复杂。

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

[note2]关闭混合,因为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 回答