2012-10-16 37 views
9

我正在寻找一个finshed的解决方案或可能一些数学/算法创建一个大的图像拼贴出较小的产品图片? 我知道如何做一个方形的时尚,从gd/imagemagick相同大小的图片,但我想有一些内置的变化。在PHP中的图像拼贴

例如,一些图片可能会稍高,如果所有的都是相同的大小和方形 - 我可能希望其中一个占用更多的空间,只是混淆了设计。保持有趣。

我越想越想这个,它似乎用一个公式来做就越困难。为所有可能的场景预定义“模板”并不奏效,因为图片的数量可能会从1(不需要工作)变为10+。

我不是在寻找任何旋转或特殊效果,只是在网格中的图像可能有一定的间距,并且没有重叠。

任何想法如何实现这一点,是否真的没有准备好去那里?

回答

23

我建议你创建一个网格和重量的方法。

这个答案分为3种类型分为:

  1. Working with a virtual grid
  2. Randomly dispose image into that grid
  3. Implement transparency
+0

哇。可能是最广泛的答案永远。非常非常感谢你!这一定会为我节省一大笔时间来开展一些工作。 现在我的主要问题是要计算如何将图像放置在网格中..我需要尝试跟踪不同的图像大小,并动态计算最优化的布局,以便如何使用“$ imageGrid-> putImage($ blue,6,2,0,0);“ - 有任何想法吗? –

+0

很高兴看到这个答案可以帮助你。是的,您可以通过以下方式动态确定体重:1)制作所有图像宽度/高度的总和,2)使用此总和获取每个图像宽度/高度的百分比,3)创建一个100x100的网格并使用这些百分比。我现在的工作现在无法帮助你,所以让我知道如果你需要一个例子,我今晚可以写下它(gmt + 2)。 –

+0

嗨,谢谢!我不确定我是否理解这将如何动态确定定位 - 所以一个例子会很棒。也许我只需要再想一想,并重新阅读你写的所有内容。但是,在你写给我的那本小说后,我有点惭愧地问你,哈哈。不用担心,我并不着急! –

19

与虚拟网格

创建一个新的形象的工作,一个真正的宽度/高度(例如:600x800),而且网格宽度/ h八(例如:10x10)。然后,您可以为图像提供虚拟尺寸和虚拟位置。我会尽力让它一步一步地让你理解我的意思。

首先,我们需要一个环境。

class imageGrid 
{ 

    private $realWidth; 
    private $realHeight; 
    private $gridWidth; 
    private $gridHeight; 
    private $image; 

    public function __construct($realWidth, $realHeight, $gridWidth, $gridHeight) 
    { 
     $this->realWidth = $realWidth; 
     $this->realHeight = $realHeight; 
     $this->gridWidth = $gridWidth; 
     $this->gridHeight = $gridHeight; 

     // create destination image 
     $this->image = imagecreatetruecolor($realWidth, $realHeight); 

     // set image default background 
     $white = imagecolorallocate($this->image, 255, 255, 255); 
     imagefill($this->image, 0, 0, $white); 
    } 

    public function __destruct() 
    { 
     imagedestroy($this->image); 
    } 

    public function display() 
    { 
     header("Content-type: image/png"); 
     imagepng($this->image); 
    } 

} 

$imageGrid = new imageGrid(800, 600, 10, 10); 
$imageGrid->display(); 

这会给我们一个美丽的白色方形。然后,我们需要一个网格来显示图像。因为这可能很难想象,所以让我们来展示它。

public function demoGrid() 
{ 
    $black = imagecolorallocate($this->image, 0, 0, 0); 
    imagesetthickness($this->image, 3); 
    $cellWidth = ($this->realWidth - 1)/$this->gridWidth; // note: -1 to avoid writting 
    $cellHeight = ($this->realHeight - 1)/$this->gridHeight; // a pixel outside the image 
    for ($x = 0; ($x <= $this->gridWidth); $x++) 
    { 
     for ($y = 0; ($y <= $this->gridHeight); $y++) 
     { 
      imageline($this->image, ($x * $cellWidth), 0, ($x * $cellWidth), $this->realHeight, $black); 
      imageline($this->image, 0, ($y * $cellHeight), $this->realWidth, ($y * $cellHeight), $black); 
     } 
    } 
} 

通过调用:

$imageGrid = new imageGrid(800, 600, 10, 10); 
$imageGrid->demoGrid(); 
$imageGrid->display(); 

我们可以看到:

enter image description here

现在,我们想知道如何编写3×4的矩形,并粘贴到(2 ,5)在我们的虚拟测量中。我们需要搜索如何获得矩形的真实大小和位置。

public function demoPutSquare($sizeW, $sizeH, $posX, $posY) 
{ 
    // Cell width 
    $cellWidth = $this->realWidth/$this->gridWidth; 
    $cellHeight = $this->realHeight/$this->gridHeight; 

    // Conversion of our virtual sizes/positions to real ones 
    $realSizeW = ($cellWidth * $sizeW); 
    $realSizeH = ($cellHeight * $sizeH); 
    $realPosX = ($cellWidth * $posX); 
    $realPosY = ($cellHeight * $posY); 

    // Getting top left and bottom right of our rectangle 
    $topLeftX = $realPosX; 
    $topLeftY = $realPosY; 
    $bottomRightX = $realPosX + $realSizeW; 
    $bottomRightY = $realPosY + $realSizeH; 

    // Displaying rectangle 
    $red = imagecolorallocate($this->image, 100, 0, 0); 
    imagefilledrectangle($this->image, $topLeftX, $topLeftY, $bottomRightX, $bottomRightY, $red); 
} 

通过调用:

$imageGrid = new imageGrid(800, 600, 10, 10); 
$imageGrid->demoGrid(); 
$imageGrid->demoPutSquare(3, 4, 2, 5); 
$imageGrid->display(); 

我们在电网得到3×4在(2,5)positionned方:

enter image description here

现在让我们更seriousely,我们有很好的措施,以便我们可以粘贴图像。

public function putImage($img, $sizeW, $sizeH, $posX, $posY) 
{ 
    // Cell width 
    $cellWidth = $this->realWidth/$this->gridWidth; 
    $cellHeight = $this->realHeight/$this->gridHeight; 

    // Conversion of our virtual sizes/positions to real ones 
    $realSizeW = ceil($cellWidth * $sizeW); 
    $realSizeH = ceil($cellHeight * $sizeH); 
    $realPosX = ($cellWidth * $posX); 
    $realPosY = ($cellHeight * $posY); 

    // Copying the image 
    imagecopyresampled($this->image, $img, $realPosX, $realPosY, 0, 0, $realSizeW, $realSizeH, imagesx($img), imagesy($img)); 
} 

通过调用:

$imageGrid = new imageGrid(800, 600, 10, 10); 
$imageGrid->demoGrid(); 
$img = imagecreatefromjpeg("ninsuo.jpg"); 
$imageGrid->putImage($img, 3, 4, 2, 5); 
$imageGrid->display(); 

我们得到:

enter image description here

这样,我们在好地方的图片,但我们失去的纵横比。让我们添加一个方法来正确调整我们的图像。

public function resizePreservingAspectRatio($img, $targetWidth, $targetHeight) 
{ 
    $srcWidth = imagesx($img); 
    $srcHeight = imagesy($img); 

    $srcRatio = $srcWidth/$srcHeight; 
    $targetRatio = $targetWidth/$targetHeight; 
    if (($srcWidth <= $targetWidth) && ($srcHeight <= $targetHeight)) 
    { 
     $imgTargetWidth = $srcWidth; 
     $imgTargetHeight = $srcHeight; 
    } 
    else if ($targetRatio > $srcRatio) 
    { 
     $imgTargetWidth = (int) ($targetHeight * $srcRatio); 
     $imgTargetHeight = $targetHeight; 
    } 
    else 
    { 
     $imgTargetWidth = $targetWidth; 
     $imgTargetHeight = (int) ($targetWidth/$srcRatio); 
    } 

    $targetImg = imagecreatetruecolor($targetWidth, $targetHeight); 

    imagecopyresampled(
     $targetImg, 
     $img, 
     ($targetWidth - $imgTargetWidth)/2, // centered 
     ($targetHeight - $imgTargetHeight)/2, // centered 
     0, 
     0, 
     $imgTargetWidth, 
     $imgTargetHeight, 
     $srcWidth, 
     $srcHeight 
    ); 

    return $targetImg; 
} 

而就在:

imagecopyresampled($this->image, $img, $realPosX, $realPosY, 0, 0, $realSizeW, $realSizeH, imagesx($img), imagesy($img)); 

我们把:

$img = $this->resizePreservingAspectRatio($img, $realSizeW, $realSizeH); 

这是这样的:

enter image description here

我们现在有一个完整的functionnalÇ做你的工作。

class imageGrid 
{ 

    private $realWidth; 
    private $realHeight; 
    private $gridWidth; 
    private $gridHeight; 
    private $image; 

    public function __construct($realWidth, $realHeight, $gridWidth, $gridHeight) 
    { 
     $this->realWidth = $realWidth; 
     $this->realHeight = $realHeight; 
     $this->gridWidth = $gridWidth; 
     $this->gridHeight = $gridHeight; 

     // create destination image 
     $this->image = imagecreatetruecolor($realWidth, $realHeight); 
     $black = imagecolorallocate($this->image, 0, 0, 0); 
     imagecolortransparent($this->image, $black); 
    } 

    public function __destruct() 
    { 
     imagedestroy($this->image); 
    } 

    public function display() 
    { 
     header("Content-type: image/png"); 
     imagepng($this->image); 
    } 

    public function putImage($img, $sizeW, $sizeH, $posX, $posY) 
    { 
     // Cell width 
     $cellWidth = $this->realWidth/$this->gridWidth; 
     $cellHeight = $this->realHeight/$this->gridHeight; 

     // Conversion of our virtual sizes/positions to real ones 
     $realSizeW = ceil($cellWidth * $sizeW); 
     $realSizeH = ceil($cellHeight * $sizeH); 
     $realPosX = ($cellWidth * $posX); 
     $realPosY = ($cellHeight * $posY); 

     $img = $this->resizePreservingAspectRatio($img, $realSizeW, $realSizeH); 

     // Copying the image 
     imagecopyresampled($this->image, $img, $realPosX, $realPosY, 0, 0, $realSizeW, $realSizeH, imagesx($img), imagesy($img)); 
    } 

    public function resizePreservingAspectRatio($img, $targetWidth, $targetHeight) 
    { 
     $srcWidth = imagesx($img); 
     $srcHeight = imagesy($img); 

     $srcRatio = $srcWidth/$srcHeight; 
     $targetRatio = $targetWidth/$targetHeight; 
     if (($srcWidth <= $targetWidth) && ($srcHeight <= $targetHeight)) 
     { 
      $imgTargetWidth = $srcWidth; 
      $imgTargetHeight = $srcHeight; 
     } 
     else if ($targetRatio > $srcRatio) 
     { 
      $imgTargetWidth = (int) ($targetHeight * $srcRatio); 
      $imgTargetHeight = $targetHeight; 
     } 
     else 
     { 
      $imgTargetWidth = $targetWidth; 
      $imgTargetHeight = (int) ($targetWidth/$srcRatio); 
     } 

     $targetImg = imagecreatetruecolor($targetWidth, $targetHeight); 

     imagecopyresampled(
      $targetImg, 
      $img, 
      ($targetWidth - $imgTargetWidth)/2, // centered 
      ($targetHeight - $imgTargetHeight)/2, // centered 
      0, 
      0, 
      $imgTargetWidth, 
      $imgTargetHeight, 
      $srcWidth, 
      $srcHeight 
     ); 

     return $targetImg; 
    } 

} 

现在,我们可以用它玩,看看它的工作原理:

$imageGrid = new imageGrid(800, 400, 12, 2); 

$blue = imagecreatefrompng("cheers_blue.png"); 
$imageGrid->putImage($blue, 6, 2, 0, 0); 
imagedestroy($blue); 

$green = imagecreatefrompng("cheers_green.png"); 
$imageGrid->putImage($green, 2, 1, 6, 0); 
imagedestroy($green); 

$red = imagecreatefrompng("cheers_red.png"); 
$imageGrid->putImage($red, 2, 1, 8, 0); 
imagedestroy($red); 

$yellow = imagecreatefrompng("cheers_yellow.png"); 
$imageGrid->putImage($yellow, 2, 1, 10, 0); 
imagedestroy($yellow); 

$purple = imagecreatefrompng("cheers_purple.png"); 
$imageGrid->putImage($purple, 3, 1, 6, 1); 
imagedestroy($purple); 

$cyan = imagecreatefrompng("cheers_cyan.png"); 
$imageGrid->putImage($cyan, 3, 1, 9, 1); 
imagedestroy($cyan); 

$imageGrid->display(); 

enter image description here

Personnally,我更喜欢一个不保留长宽比:-)

enter image description here

干杯! (!嗯,享受我会说)

+0

谢谢!好的代码;) –

+0

谢谢!有没有办法将拼贴图像保存为不同名称的dir? @Alain Tiemblo –

5

随机配置的图像成网格

的方法是:我们会动摇我们的所有图像,以得到一个随机排列,并随机处置他们行:1至4张图片每行(您可以更改此值),并使用每行较高的图像来确定每行的高度。因此,如果图片比另一张图片高出50%,如果图片不在同一行中,则会保留比例。

这有点困难,所以我决定在本部分的开发过程中不要使用图形。这就是为什么有很多步骤和调试的原因,但是这对于最终结果一步一步地帮助很大。

我们得到了我们所有的图像的高度和它们的总和:

$images = array(); 
$totalHeight = 0; 
foreach (glob("images/*.jpg") as $jpg) 
{ 
    $img = imagecreatefromjpeg($jpg); 
    $images[$jpg] = imagesy($img); 
    $totalHeight += $images[$jpg]; 
    imagedestroy($img); 
} 

echo "image list with heights:\n"; 
var_dump($images); 
echo "total heights: {$totalHeight}\n"; 

给我们:

image list with heights: 
array(12) { 
    ["images/image1.jpg"]=> 
    int(392) 
    ["images/image10.jpg"]=> 
    int(640) 
    ["images/image11.jpg"]=> 
    int(364) 
    ["images/image12.jpg"]=> 
    int(324) 
    ["images/image2.jpg"]=> 
    int(533) 
    ["images/image3.jpg"]=> 
    int(360) 
    ["images/image4.jpg"]=> 
    int(768) 
    ["images/image5.jpg"]=> 
    int(330) 
    ["images/image6.jpg"]=> 
    int(360) 
    ["images/image7.jpg"]=> 
    int(338) 
    ["images/image8.jpg"]=> 
    int(600) 
    ["images/image9.jpg"]=> 
    int(391) 
} 
total heights: 5400 

然后我们shfuffle图像阵列来获得图像的随机配置。我们需要保存密钥,并且密码没有,所以我们需要一点小技巧。

// Shuffle image array of files preserving keys to get random image disposition 
$keys = array_keys($images); 
shuffle($keys); 
$images = array_merge(array_flip($keys), $images); 

// Separate image names and heights, will simplify our future work 
$heights = array_values($images); 
$images = array_keys($images); 

echo "image list:\n"; 
var_dump($images); 

echo "image heights:\n"; 
var_dump($heights); 

给我们:

image list: 
array(12) { 
    [0]=> 
    string(17) "images/image6.jpg" 
    [1]=> 
    string(17) "images/image5.jpg" 
    [2]=> 
    string(18) "images/image10.jpg" 
    [3]=> 
    string(17) "images/image2.jpg" 
    [4]=> 
    string(18) "images/image12.jpg" 
    [5]=> 
    string(17) "images/image3.jpg" 
    [6]=> 
    string(17) "images/image4.jpg" 
    [7]=> 
    string(17) "images/image1.jpg" 
    [8]=> 
    string(17) "images/image8.jpg" 
    [9]=> 
    string(17) "images/image9.jpg" 
    [10]=> 
    string(18) "images/image11.jpg" 
    [11]=> 
    string(17) "images/image7.jpg" 
} 
image heights: 
array(12) { 
    [0]=> 
    int(360) 
    [1]=> 
    int(330) 
    [2]=> 
    int(640) 
    [3]=> 
    int(533) 
    [4]=> 
    int(324) 
    [5]=> 
    int(360) 
    [6]=> 
    int(768) 
    [7]=> 
    int(392) 
    [8]=> 
    int(600) 
    [9]=> 
    int(391) 
    [10]=> 
    int(364) 
    [11]=> 
    int(338) 
} 

最重要的这里就是要检查,如果我们保留了图像/高度关联。

现在,我们需要将图像高度转换为百分比:所以如果您有2张图像,其中一张比第二张高50%,因此您的第一张图像总高度的66% %为第二个。这个虚拟高度将被用作我们网格的高度。

$count = count($heights); 
for ($i = 0; ($i < $count); $i++) 
{ 
    $heights[$i] = ($heights[$i] * 100)/$totalHeight 
} 

echo "image heights in percents\n"; 
var_dump($heights); 
echo "check : " . array_sum($heights) . " = 100\n"; 

导致:

Image heights in percents 
array(12) { 
    [0]=> 
    float(6.6666666666667) 
    [1]=> 
    float(6.1111111111111) 
    [2]=> 
    float(11.851851851852) 
    [3]=> 
    float(9.8703703703704) 
    [4]=> 
    int(6) 
    [5]=> 
    float(6.6666666666667) 
    [6]=> 
    float(14.222222222222) 
    [7]=> 
    float(7.2592592592593) 
    [8]=> 
    float(11.111111111111) 
    [9]=> 
    float(7.2407407407407) 
    [10]=> 
    float(6.7407407407407) 
    [11]=> 
    float(6.2592592592593) 
} 
check : 100 = 100 

我们现在产生线的阵列,就看我们有多少图像每行放。对于这个例子,我们希望每行有1到4个图像。在这里更改rand() % 4 + 1您想获得的每行数量尽可能多的图像。例如:rand() % 3 + 2会给你2到5张图像。

$lines = array(); 
while ($count > 0) 
{ 
    $nbImages = rand() % 4 + 1; 
    if (($count - $nbImages) < 0) 
    { 
     $nbImages = $count; 
    } 

    $lines[] = $nbImages; 
    $count -= $nbImages; 
} 

echo "Number of lines : " . count($lines) . "\n"; 
echo "images per line disposition :\n"; 
var_dump($lines); 

导致:

Number of lines : 5 
images per line disposition : 
array(5) { 
    [0]=> 
    int(3) 
    [1]=> 
    int(1) 
    [2]=> 
    int(1) 
    [3]=> 
    int(4) 
    [4]=> 
    int(3) 
} 

我们需要的图像与行相关联,并与线的位置。这将帮助我们获取图像在我们网格中的位置。

$imageLines = array(); 
foreach ($lines as $key => $numberImg) 
{ 
    while ($numberImg--) 
    { 
     $imageLines[] = $key; 
    } 
} 

echo "image/line association:\n"; 
var_dump($imageLines); 

$imagePositions = array(); 
foreach ($lines as $numberImg) 
{ 
    for ($i = 0; ($i < $numberImg); $i++) 
    { 
     $imagePositions[] = $i; 
    } 
} 

echo "image/position in a line association:\n"; 
var_dump($imagePositions); 

导致:

image/line association: 
array(12) { 
    [0]=> 
    int(0) 
    [1]=> 
    int(0) 
    [2]=> 
    int(0) 
    [3]=> 
    int(1) 
    [4]=> 
    int(2) 
    [5]=> 
    int(3) 
    [6]=> 
    int(3) 
    [7]=> 
    int(3) 
    [8]=> 
    int(3) 
    [9]=> 
    int(4) 
    [10]=> 
    int(4) 
    [11]=> 
    int(4) 
} 
image/position in a line association: 
array(12) { 
    [0]=> 
    int(0) 
    [1]=> 
    int(1) 
    [2]=> 
    int(2) 
    [3]=> 
    int(0) 
    [4]=> 
    int(0) 
    [5]=> 
    int(0) 
    [6]=> 
    int(1) 
    [7]=> 
    int(2) 
    [8]=> 
    int(3) 
    [9]=> 
    int(0) 
    [10]=> 
    int(1) 
    [11]=> 
    int(2) 
} 

现在,我们需要让我们的图像的总宽度。我们有1到4张图像,所以为了得到每幅图像的整数大小,不管每行图像的数量是多少,我们将4(最大值)乘以4到1的所有值。在这种情况下:4 * 3 * 2 * 1 = 24,所以如果我们有1个图像/线,它的宽度将是24,2图像/线:24/2 = 12,3图像/线:24/3 = 8,4图像/线:24/4 = 6。所有的都是有效的整数。

$i = 4; 
$virtualWidth = 1; 
while ($i) 
{ 
    $virtualWidth *= $i--; 
} 

echo "virtual width: {$virtualWidth}\n"; 

不在话下这里,这导致:

virtual width: 24 

我们现在需要确定每行的高度,按照每行最高的图像。在这个计算中我们也可以推导出我们的网格高度。

// Determine the virtual height needed for each line and for the whole grid 
$imageHeights = array(); 
$index = 0; 
foreach ($lines as $key => $numberImages) 
{ 
    $slice = array_slice($heights, $index, $numberImages); 

    echo "at line {$key}, images heights are:\n"; 
    var_dump($slice); 

    $imageHeights[] = max($slice); 
    $index += $numberImages; 
} 
$virtualHeight = array_sum($imageHeights); 

echo "heights for each line:\n"; 
var_dump($imageHeights); 
echo "total height = {$virtualHeight}\n"; 

这导致:

at line 0, images heights are: 
array(3) { 
    [0]=> 
    float(6.6666666666667) 
    [1]=> 
    float(6.1111111111111) 
    [2]=> 
    float(11.851851851852) 
} 
at line 1, images heights are: 
array(1) { 
    [0]=> 
    float(9.8703703703704) 
} 
at line 2, images heights are: 
array(1) { 
    [0]=> 
    int(6) 
} 
at line 3, images heights are: 
array(4) { 
    [0]=> 
    float(6.6666666666667) 
    [1]=> 
    float(14.222222222222) 
    [2]=> 
    float(7.2592592592593) 
    [3]=> 
    float(11.111111111111) 
} 
at line 4, images heights are: 
array(3) { 
    [0]=> 
    float(7.2407407407407) 
    [1]=> 
    float(6.7407407407407) 
    [2]=> 
    float(6.2592592592593) 
} 
heights for each line: 
array(5) { 
    [0]=> 
    float(11.851851851852) 
    [1]=> 
    float(9.8703703703704) 
    [2]=> 
    int(6) 
    [3]=> 
    float(14.222222222222) 
    [4]=> 
    float(7.2407407407407) 
} 
total height = 49.185185185185 

我们检查这个结果,如果我们有每行的最高值,而如果和是有效的。

我们终于获得了所有需要显示随机定位图像网格的信息。

$imageGrid = new imageGrid(800, 800, $virtualWidth, $virtualHeight); 
foreach (glob("images/*.jpg") as $jpg) 
{ 
    $img = imagecreatefromjpeg($jpg); 

    $index = array_search($jpg, $images); 
    echo "image {$index}:\n"; 

    $line = $imageLines[$index]; 
    echo "image is at line {$line}\n"; 

    $sizeW = ($virtualWidth/$lines[$line]); 
    echo "width = {$virtualWidth}/{$lines[$line]} = {$sizeW}\n"; 

    $sizeH = $imageHeights[$line]; 
    echo "height = {$imageHeights[$line]}\n"; 

    $posX = $imagePositions[$index] * ($virtualWidth/$lines[$line]); 
    echo "pos X = {$imagePositions[$index]} * ({$virtualWidth}/{$lines[$line]}) = {$posX}\n"; 

    $slice = array_slice($imageHeights, 0, $line); 
    echo "Slice to calc Y:\n"; 
    var_dump($slice); 

    $posY = array_sum($slice); 
    echo "pos Y = {$posY}\n"; 

    echo "\n"; 

    $imageGrid->putImage($img, $sizeW, $sizeH, $posX, $posY); 
    imagedestroy($img); 
} 

这导致:

image 7: 
image is at line 3 
width = 24/4 = 6 
height = 14.222222222222 
pos X = 2 * (24/4) = 12 
Slice to calc Y: 
array(3) { 
    [0]=> 
    float(11.851851851852) 
    [1]=> 
    float(9.8703703703704) 
    [2]=> 
    int(6) 
} 
pos Y = 27.722222222222 

image 2: 
image is at line 0 
width = 24/3 = 8 
height = 11.851851851852 
pos X = 2 * (24/3) = 16 
Slice to calc Y: 
array(0) { 
} 
pos Y = 0 

image 10: 
image is at line 4 
width = 24/3 = 8 
height = 7.2407407407407 
pos X = 1 * (24/3) = 8 
Slice to calc Y: 
array(4) { 
    [0]=> 
    float(11.851851851852) 
    [1]=> 
    float(9.8703703703704) 
    [2]=> 
    int(6) 
    [3]=> 
    float(14.222222222222) 
} 
pos Y = 41.944444444444 

image 4: 
image is at line 2 
width = 24/1 = 24 
height = 6 
pos X = 0 * (24/1) = 0 
Slice to calc Y: 
array(2) { 
    [0]=> 
    float(11.851851851852) 
    [1]=> 
    float(9.8703703703704) 
} 
pos Y = 21.722222222222 

image 3: 
image is at line 1 
width = 24/1 = 24 
height = 9.8703703703704 
pos X = 0 * (24/1) = 0 
Slice to calc Y: 
array(1) { 
    [0]=> 
    float(11.851851851852) 
} 
pos Y = 11.851851851852 

image 5: 
image is at line 3 
width = 24/4 = 6 
height = 14.222222222222 
pos X = 0 * (24/4) = 0 
Slice to calc Y: 
array(3) { 
    [0]=> 
    float(11.851851851852) 
    [1]=> 
    float(9.8703703703704) 
    [2]=> 
    int(6) 
} 
pos Y = 27.722222222222 

image 6: 
image is at line 3 
width = 24/4 = 6 
height = 14.222222222222 
pos X = 1 * (24/4) = 6 
Slice to calc Y: 
array(3) { 
    [0]=> 
    float(11.851851851852) 
    [1]=> 
    float(9.8703703703704) 
    [2]=> 
    int(6) 
} 
pos Y = 27.722222222222 

image 1: 
image is at line 0 
width = 24/3 = 8 
height = 11.851851851852 
pos X = 1 * (24/3) = 8 
Slice to calc Y: 
array(0) { 
} 
pos Y = 0 

image 0: 
image is at line 0 
width = 24/3 = 8 
height = 11.851851851852 
pos X = 0 * (24/3) = 0 
Slice to calc Y: 
array(0) { 
} 
pos Y = 0 

image 11: 
image is at line 4 
width = 24/3 = 8 
height = 7.2407407407407 
pos X = 2 * (24/3) = 16 
Slice to calc Y: 
array(4) { 
    [0]=> 
    float(11.851851851852) 
    [1]=> 
    float(9.8703703703704) 
    [2]=> 
    int(6) 
    [3]=> 
    float(14.222222222222) 
} 
pos Y = 41.944444444444 

image 8: 
image is at line 3 
width = 24/4 = 6 
height = 14.222222222222 
pos X = 3 * (24/4) = 18 
Slice to calc Y: 
array(3) { 
    [0]=> 
    float(11.851851851852) 
    [1]=> 
    float(9.8703703703704) 
    [2]=> 
    int(6) 
} 
pos Y = 27.722222222222 

image 9: 
image is at line 4 
width = 24/3 = 8 
height = 7.2407407407407 
pos X = 0 * (24/3) = 0 
Slice to calc Y: 
array(4) { 
    [0]=> 
    float(11.851851851852) 
    [1]=> 
    float(9.8703703703704) 
    [2]=> 
    int(6) 
    [3]=> 
    float(14.222222222222) 
} 
pos Y = 41.944444444444 

要调试我们的代码,我们与结束吧:

$debug = true; 
if ($debug) 
{ 
    echo ob_get_clean(); 
} 
else 
{ 
    ob_clean(); 
    $imageGrid->display(); 
} 

欧凯,你在这里的所有步骤。结果呢?

enter image description here

F5 ......

enter image description here

F5 ......

enter image description here

最终代码:

ob_start(); 

echo '<pre>'; 

// Get height of all images 
$images = array(); 
$totalHeight = 0; 
foreach (glob("images/*.jpg") as $jpg) 
{ 
    $img = imagecreatefromjpeg($jpg); 
    $images[$jpg] = imagesy($img); 
    $totalHeight += $images[$jpg]; 
    imagedestroy($img); 
} 

echo "image list with heights:\n"; 
var_dump($images); 

// Shuffle image array of files preserving keys to get random image disposition 
$keys = array_keys($images); 
shuffle($keys); 
$images = array_merge(array_flip($keys), $images); 

// Separate image names and heights, will simplify our future work 
$heights = array_values($images); 
$images = array_keys($images); 

echo "image list:\n"; 
var_dump($images); 

echo "total heights: {$totalHeight}\n"; 

echo "image heights:\n"; 
var_dump($heights); 

// Get percentage of image height compared to the total height 
$count = count($heights); 
for ($i = 0; ($i < $count); $i++) 
{ 
    $heights[$i] = ($heights[$i] * 100)/$totalHeight; // becomes virtual height in a x100 grid 
} 

echo "image heights in percents\n"; 
var_dump($heights); 
echo "check : " . array_sum($heights) . " = 100\n"; 

// Get random number of images per line and number of lines 
// Between 1 to 4 images/line until there is no more image. 
$lines = array(); 
while ($count > 0) 
{ 
    $nbImages = rand() % 4 + 1; 
    if (($count - $nbImages) < 0) 
    { 
     $nbImages = $count; 
    } 

    $lines[] = $nbImages; 
    $count -= $nbImages; 
} 

echo "Number of lines : " . count($lines) . "\n"; 
echo "images per line disposition :\n"; 
var_dump($lines); 

// Associate an image with a line 
$imageLines = array(); 
foreach ($lines as $key => $numberImg) 
{ 
    while ($numberImg--) 
    { 
     $imageLines[] = $key; 
    } 
} 

echo "image/line association:\n"; 
var_dump($imageLines); 

// Associate an image with a position in a line 
$imagePositions = array(); 
foreach ($lines as $numberImg) 
{ 
    for ($i = 0; ($i < $numberImg); $i++) 
    { 
     $imagePositions[] = $i; 
    } 
} 

echo "image/position in a line association:\n"; 
var_dump($imagePositions); 

// We have from 1 to 4 images/line so we create a grid with a virtual width of 1*2*3*4. 
// In this case, 1 image/line = 24, 2/line =24/2=12, 3/line=24/3=8, all are valid integers. 
$i = 4; 
$virtualWidth = 1; 
while ($i) 
{ 
    $virtualWidth *= $i--; 
} 

echo "virtual width: {$virtualWidth}\n"; 

// Determine the virtual height needed for each line and for the whole grid 
$imageHeights = array(); 
$index = 0; 
foreach ($lines as $key => $numberImages) 
{ 
    $slice = array_slice($heights, $index, $numberImages); 

    echo "at line {$key}, images heights are:\n"; 
    var_dump($slice); 

    $imageHeights[] = max($slice); 
    $index += $numberImages; 
} 
$virtualHeight = array_sum($imageHeights); 

echo "heights for each line:\n"; 
var_dump($imageHeights); 
echo "total height = {$virtualHeight}\n"; 


// Create a grid and place logically all images in the virtual area 
$imageGrid = new imageGrid(800, 800, $virtualWidth, $virtualHeight); 
foreach (glob("images/*.jpg") as $jpg) 
{ 
    $img = imagecreatefromjpeg($jpg); 

    // Determine position 
    $index = array_search($jpg, $images); 
    echo "image {$index}:\n"; 

    $line = $imageLines[$index]; 
    echo "image is at line {$line}\n"; 

    $sizeW = ($virtualWidth/$lines[$line]); 
    echo "width = {$virtualWidth}/{$lines[$line]} = {$sizeW}\n"; 

    $sizeH = $imageHeights[$line]; 
    echo "height = {$imageHeights[$line]}\n"; 

    $posX = $imagePositions[$index] * ($virtualWidth/$lines[$line]); 
    echo "pos X = {$imagePositions[$index]} * ({$virtualWidth}/{$lines[$line]}) = {$posX}\n"; 

    $slice = array_slice($imageHeights, 0, $line); 
    echo "Slice to calc Y:\n"; 
    var_dump($slice); 

    $posY = array_sum($slice); 
    echo "pos Y = {$posY}\n"; 

    echo "\n"; 

    $imageGrid->putImage($img, $sizeW, $sizeH, $posX, $posY); 
    imagedestroy($img); 
} 

$debug = false; 
if ($debug) 
{ 
    echo ob_get_clean(); 
} 
else 
{ 
    ob_clean(); 
    $imageGrid->display(); 
} 

我的方法可能不是最好的方法,但至少它可以让您将图像随机定位到保留图像重量的网格中。这个问题很难处理,所以我希望这对你的情况足够了。

+0

这比我所希望的还要多,简直太棒了!谢谢。 –

5

实现透明度

首先对__construct方法,替换:

$white = imagecolorallocate($this->image, 255, 255, 255); 
    imagefill($this->image, 0, 0, $white); 

通过:

$transparent = imagecolorallocate($this->image, 255, 0, 255); 
    imagefill($this->image, 0, 0, $transparent); 
    imagecolortransparent($this->image, $transparent); 

然后,在resizePreservingAspectRatio方法,添加刚过:

$targetImg = imagecreatetruecolor($targetWidth, $targetHeight); 

以下行:

$targetTransparent = imagecolorallocate($targetImg, 255, 0, 255); 
    imagefill($targetImg, 0, 0, $targetTransparent); 
    imagecolortransparent($targetImg, $targetTransparent); 

然后我们开始吧。

enter image description here