调整图像并将图像裁剪成正方形,白色背景 - 使用GD

时间:2013-02-10 15:31:08

标签: php caching thumbnails gdlib

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

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

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

  1. 完整/原始图像存储在服务器上(正常)
  2. 300x300px&创建了150x150px .jpg缩略图
  3. 然而,是否有可能,一旦图像宽度/高度调整大小,然后添加额外的画布宽度/高度使其完全正方形?我想这里的一个问题是确定图像首先是“肖像”还是“风景”?

    此外,目前我正在获得带有透明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);
    

1 个答案:

答案 0 :(得分:1)

抱歉,我不会在代码中添加我的sugestions,因为它太复杂了。所以只是提示。

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。如何更改新图像的背景

这不是真正的谜 - 你只是draw rectangle整个图像:

$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中计算出新的高度和宽度。我将使用theese作为新图像尺寸。

$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);