【问题标题】:Duplicated thumbnail images inside php image spritephp图像精灵中的重复缩略图图像
【发布时间】:2016-12-31 20:26:35
【问题描述】:

我正在使用 style.css 和 index.php 开发 linux、xampp 和 wordpress 测试主题。

我使用创建图像精灵GD库创建了php脚本。它可以有条件地从给定的文件夹(glob)或url(数组)创建精灵。它还可以动态缩放所有缩略图以适应给定的边界框(不是我的功能)。

我的问题是所有缩略图都在下一个缩略图中重复。比如:第一个图像在 2、2 在 3、3 在 4(...)中重复。然而,正确的图像总是在重复的图像之上。

我认为我的循环或合并缩略图有问题,但我不确定。

这是我的代码(默认从数组创建精灵):

<?php

//////// PART 1 - DEFINE GLOBAL VARIABLES ////////

//// SPRITE IMAGES SOURCE ////
// 0 = Create sprite from memory - array()
// 1 = Create sprite from folder - glob()
$sprite_images_source = 0;

//// Use array as sprite images source ////
if($sprite_images_source == 0){
  $images=array(
    //// Example .PNGs ////
    // Orientation: Horizontal, smaller than bounding box
    'https://dummyimage.com/128x72/444/f2f2f2.png&text=128x72.png',
    // Orientation: Horizontal, bigger than bounding box
    'https://dummyimage.com/1280x720/444/f2f2f2.png&text=1280x720.png',
    // Orientation: Vertical, smaller than bounding box
    'https://dummyimage.com/72x128/444/f2f2f2.png&text=72x128.png',
    // Orientation: Vertical, bigger than bounding box
    'https://dummyimage.com/720x1280/444/f2f2f2.png&text=720x1280.png',
    // Square, smaller than bounding box
    'https://dummyimage.com/200x200/444/f2f2f2.png&text=400x400.png',

    //// Example .JPEGs ////
    // Orientation: Horizontal, smaller than bounding box
    'https://dummyimage.com/128x72/666/f2f2f2.jpg&text=128x72.jpg',
    // Orientation: Horizontal, bigger than bounding box
    'https://dummyimage.com/1280x720/666/f2f2f2.jpg&text=1280x720.jpg',
    // Orientation: Vertical, smaller than bounding box
    'https://dummyimage.com/72x128/666/f2f2f2.jpg&text=72x128.jpg',
    // Orientation: Vertical, bigger than bounding box
    'https://dummyimage.com/720x1280/666/f2f2f2.jpg&text=720x1280.jpg',
    // Square
    'https://dummyimage.com/200x200/666/f2f2f2.jpg&text=200x200.jpg',

    //// Example .GIFs ////
    // Orientation: Horizontal, smaller than bounding box
    'https://dummyimage.com/128x72/888/f2f2f2.gif&text=128x72.gif',
    // Orientation: Horizontal, bigger than bounding box
    'https://dummyimage.com/1280x720/888/f2f2f2.gif&text=1280x720.gif',
    // Orientation: Vertical, smaller than bounding box
    'https://dummyimage.com/72x128/888/f2f2f2.gif&text=72x128.gif',
    // Try to have 1/3/5/7 images to see empty space on sprite,
    // and test colorize sprite background method with this

  );

//// Use folder as sprite images source ////
} else if($sprite_images_source == 1){
 // $images = glob('sprite/images/*');
}


//// SINGLE THUMBNAIL = BOUNDING BOX DIMENSIONS ////
$thumbnail_width = 300;
$thumbnail_height = 300;
$thumbnail = imagecreatetruecolor($thumbnail_width, $thumbnail_height);


//// SPRITE DIMENSIONS ////
$sprite_columns = 5;
$sprite_rows = ceil(count($images) / $sprite_columns);
$sprite_width = $thumbnail_width * $sprite_columns;
$sprite_height = $thumbnail_height * $sprite_rows;
$sprite = imagecreatetruecolor($sprite_width, $sprite_height);


//// SPRITE BACKGROUND COLOR ////
$sprite_bg = imagecolortransparent($sprite, imagecolorallocatealpha($sprite, 0,0,0,0));
imagefill($sprite,0,0,$sprite_bg);


//////// PART 2 - GENERATE SPRITE ////////

//// Assign each source from array to single image
foreach ($images as $i => $image) {
  $images[$i] = array(
    'src' => $image,
    'title' => 'Product ' . ($i + 1),
    'price' => '$' . ($i * 100)
  );
}


//// SINGLE THUMBNAIL MANIPULATION ////
// Start Generate Thumbnail from first file in array/folder
$i = 0;

for ($y = 0; $y < $sprite_height; $y += $thumbnail_height) {
  for ($x = 0; $x < $sprite_width; $x += $thumbnail_width) {
    // What is this for ???
    if ($i >= count($images)) {
      break 2;
    }

    // Assosiate correct image for thumbnail from array
    $image = $images[$i];
    $src = imagecreatefromstring(file_get_contents($image['src']));

    // Scale Image to Bounding Box
    scale_image($src, $thumbnail, 'fit');


    //// PRINT IMAGE INTO SINGLE THUMBNAIL ////
    imagecopy($sprite, $thumbnail, $x, $y, 0, 0, $thumbnail_width, $thumbnail_height);
    imagedestroy($src);
    $i++;
  }
  // END | for ($y = 0; $y < $sprite_height; $y += $thumbnail_height)
}
// END | for ($y = 0; $y < $sprite_height; $y += $thumbnail_height)


//////// PART 3 - OUTPUT SPRITE ////////

// Output Sprite to Browser as PNG
header('Content-Type: image/png');
imagepng($sprite);

// Clean up, and free memory
imagedestroy($thumbnail);
imagedestroy($sprite);


// FUNCTION - SCALE IMAGE
function scale_image($src_image, $dst_image, $op = 'fit') {
  $src_width = imagesx($src_image);
  $src_height = imagesy($src_image);

  $dst_width = imagesx($dst_image);
  $dst_height = imagesy($dst_image);

  // Try to match destination image by width
  $new_width = $dst_width;
  $new_height = round($new_width*($src_height/$src_width));
  $new_x = 0;
  $new_y = round(($dst_height-$new_height)/2);

  // FILL and FIT mode are mutually exclusive
  if ($op =='fill')
    $next = $new_height < $dst_height;
  else
    $next = $new_height > $dst_height;

  // If match by width failed and destination image does not fit, try by height
  if ($next) {
    $new_height = $dst_height;
    $new_width = round($new_height*($src_width/$src_height));
    $new_x = round(($dst_width - $new_width)/2);
    $new_y = 0;
  }

  // Copy image on right place
  imagecopyresampled($dst_image, $src_image , $new_x, $new_y, 0, 0, $new_width, $new_height, $src_width, $src_height);
}

【问题讨论】:

    标签: php sprite gd bounding-box


    【解决方案1】:

    移动这行代码

    $thumbnail = imagecreatetruecolor($thumbnail_width, $thumbnail_height);
    

    在这几行之后

        for ($y = 0; $y < $sprite_height; $y += $thumbnail_height) {
          for ($x = 0; $x < $sprite_width; $x += $thumbnail_width) {
            // What is this for ???
            if ($i >= count($images)) {
              break 2;
            }
    ################## MOVE THAT LINE HERE ##################
    

    别忘了使用

    imagedestroy($thumbnail);
    

    循环结束之前。

    希望这有助于删除重叠的图像。

    更新 您的代码正在运行,问题是缩略图句柄重复。这是与我之前的答案相比的结果快照。

    【讨论】:

      【解决方案2】:

      加布里埃尔,我的英语比你差。让我帮你让你自己帮你吧……

      实际上问题在于您的 $thumbnail 处理被保存在 $dst_image 中的 scale_image 函数中,这就是它重复的原因......

      我尝试写 (imagepng($thumbnail,'images/image_xyzzz_i.png');) $thumbnail 并销毁它。创建了重叠的图像。当我尝试在 scale_image 函数中破坏 $dst_image 时,它也破坏了 $thumbnail。摆脱这种关系。

      更新....

      可以清楚地看到,精灵只受$thumbnail的影响。

      更新 - 2

      这是您修改后的代码...只需两次复制和粘贴...

      <?php
      
      //////// PART 1 - DEFINE GLOBAL VARIABLES ////////
      
      //// SPRITE IMAGES SOURCE ////
      // 0 = Create sprite from memory - array()
      // 1 = Create sprite from folder - glob()
      $sprite_images_source = 0;
      
      //// Use array as sprite images source ////
      if($sprite_images_source == 0){
        $images=array(
          //// Example .PNGs ////
          // Orientation: Horizontal, smaller than bounding box
          'https://dummyimage.com/128x72/444/f2f2f2.png&text=128x72.png',
          // Orientation: Horizontal, bigger than bounding box
          'https://dummyimage.com/1280x720/444/f2f2f2.png&text=1280x720.png',
          // Orientation: Vertical, smaller than bounding box
          'https://dummyimage.com/72x128/444/f2f2f2.png&text=72x128.png',
          // Orientation: Vertical, bigger than bounding box
          'https://dummyimage.com/720x1280/444/f2f2f2.png&text=720x1280.png',
          // Square, smaller than bounding box
          'https://dummyimage.com/200x200/444/f2f2f2.png&text=400x400.png',
      
          //// Example .JPEGs ////
          // Orientation: Horizontal, smaller than bounding box
          'https://dummyimage.com/128x72/666/f2f2f2.jpg&text=128x72.jpg',
          // Orientation: Horizontal, bigger than bounding box
          'https://dummyimage.com/1280x720/666/f2f2f2.jpg&text=1280x720.jpg',
          // Orientation: Vertical, smaller than bounding box
          'https://dummyimage.com/72x128/666/f2f2f2.jpg&text=72x128.jpg',
          // Orientation: Vertical, bigger than bounding box
          'https://dummyimage.com/720x1280/666/f2f2f2.jpg&text=720x1280.jpg',
          // Square
          'https://dummyimage.com/200x200/666/f2f2f2.jpg&text=200x200.jpg',
      
          //// Example .GIFs ////
          // Orientation: Horizontal, smaller than bounding box
          'https://dummyimage.com/128x72/888/f2f2f2.gif&text=128x72.gif',
          // Orientation: Horizontal, bigger than bounding box
          'https://dummyimage.com/1280x720/888/f2f2f2.gif&text=1280x720.gif',
          // Orientation: Vertical, smaller than bounding box
          'https://dummyimage.com/72x128/888/f2f2f2.gif&text=72x128.gif',
          // Try to have 1/3/5/7 images to see empty space on sprite,
          // and test colorize sprite background method with this
      
        );
      
      //// Use folder as sprite images source ////
      } else if($sprite_images_source == 1){
       // $images = glob('sprite/images/*');
      }
      
      
      //// SINGLE THUMBNAIL = BOUNDING BOX DIMENSIONS ////
      $thumbnail_width = 300;
      $thumbnail_height = 300;
      ################# CUT LINE 1 FROM HERE ########################
      
      
      //// SPRITE DIMENSIONS ////
      $sprite_columns = 5;
      $sprite_rows = ceil(count($images) / $sprite_columns);
      $sprite_width = $thumbnail_width * $sprite_columns;
      $sprite_height = $thumbnail_height * $sprite_rows;
      $sprite = imagecreatetruecolor($sprite_width, $sprite_height);
      
      
      //// SPRITE BACKGROUND COLOR ////
      $sprite_bg = imagecolortransparent($sprite, imagecolorallocatealpha($sprite, 0,0,0,0));
      imagefill($sprite,0,0,$sprite_bg);
      
      
      //////// PART 2 - GENERATE SPRITE ////////
      
      //// Assign each source from array to single image
      foreach ($images as $i => $image) {
        $images[$i] = array(
          'src' => $image,
          'title' => 'Product ' . ($i + 1),
          'price' => '$' . ($i * 100)
        );
      }
      
      
      //// SINGLE THUMBNAIL MANIPULATION ////
      // Start Generate Thumbnail from first file in array/folder
      $i = 0;
      
      for ($y = 0; $y < $sprite_height; $y += $thumbnail_height) {
        for ($x = 0; $x < $sprite_width; $x += $thumbnail_width) {
          // What is this for ???
          if ($i >= count($images)) {
            break 2;
          }
      
      
      ############################# PASTED LINE 1 HERE ######################
      $thumbnail = imagecreatetruecolor($thumbnail_width, $thumbnail_height);
      #######################################################################
      
          // Assosiate correct image for thumbnail from array
          $image = $images[$i];
          $src = imagecreatefromstring(file_get_contents($image['src']));
      
          // Scale Image to Bounding Box
          scale_image($src, $thumbnail, 'fit');
      
      
          //// PRINT IMAGE INTO SINGLE THUMBNAIL ////
          imagecopy($sprite, $thumbnail, $x, $y, 0, 0, $thumbnail_width, $thumbnail_height);
          imagedestroy($src);
          $i++;
      
      ######################## PASTED LINE 2 HERE ###########################
      imagedestroy($thumbnail);
      #######################################################################
      
        }
        // END | for ($y = 0; $y < $sprite_height; $y += $thumbnail_height)
      }
      // END | for ($y = 0; $y < $sprite_height; $y += $thumbnail_height)
      
      
      //////// PART 3 - OUTPUT SPRITE ////////
      
      // Output Sprite to Browser as PNG
      header('Content-Type: image/png');
      imagepng($sprite);
      
      // Clean up, and free memory
      ######################## CUT LINE 2 HERE ###########################
      imagedestroy($sprite);
      
      
      // FUNCTION - SCALE IMAGE
      function scale_image($src_image, $dst_image, $op = 'fit') {
        $src_width = imagesx($src_image);
        $src_height = imagesy($src_image);
      
        $dst_width = imagesx($dst_image);
        $dst_height = imagesy($dst_image);
      
        // Try to match destination image by width
        $new_width = $dst_width;
        $new_height = round($new_width*($src_height/$src_width));
        $new_x = 0;
        $new_y = round(($dst_height-$new_height)/2);
      
        // FILL and FIT mode are mutually exclusive
        if ($op =='fill')
          $next = $new_height < $dst_height;
        else
          $next = $new_height > $dst_height;
      
        // If match by width failed and destination image does not fit, try by height
        if ($next) {
          $new_height = $dst_height;
          $new_width = round($new_height*($src_width/$src_height));
          $new_x = round(($dst_width - $new_width)/2);
          $new_y = 0;
        }
      
        // Copy image on right place
        imagecopyresampled($dst_image, $src_image , $new_x, $new_y, 0, 0, $new_width, $new_height, $src_width, $src_height);
      }
      

      【讨论】:

      • 感谢您的回答@Vishal 我需要尝试几次,但它现在可以正常工作,我需要在循环内添加缩略图宽度和高度,以使这项工作正常工作您的意思是:摆脱这种关系我应该删除/更改函数 scale_image 内的 $dst_image 吗?有 3 个循环,foreach、for($y 和 for($x 我应该只放一次 destroy($thumbnail) 吗??我不熟悉清理内存 - 我如何检查它是否已清理?!百万谢谢你再次为你的帮助,我现在非常高兴:))
      • 嗨,Gab,我已经添加了带有注释的代码。希望你现在清楚了。看我刚刚在 for 循环中移动了两行。
      • 要查看精灵的输出,请在创建图像文件夹后评论 header('Content-Type: image/png'); 并将 imagedestroy($sprite); 更改为 imagedestroy($sprite,"images/sprite.png");
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-26
      • 1970-01-01
      • 2011-01-26
      • 2013-09-10
      • 2010-11-13
      • 2010-10-15
      • 1970-01-01
      相关资源
      最近更新 更多