我正在寻找一个精简的解决方案,或者可能是一些数学/算法,用于从较小的产品图片中创建大图像拼贴? 我知道如何以方形方式进行,从gd / imagemagick相同大小的图片,但我想内置一些变化。
例如,有些图片可能会稍微高一点,如果所有图片的尺寸和方形相同 - 我可能会想要其中一张占用更多空间,只是为了混淆设计。保持有趣。
我越想到这一点,它似乎越难以配方。为所有可能的场景预定义“模板”是行不通的,因为图片数量可能从1(不需要工作)到10 +不等。
我不是在寻找任何旋转或特殊效果,只是网格中的图像,中间可能有一些间距,没有重叠。
任何想法如何实现这一点,是否真的没有准备好去那里?
答案 0 :(得分:24)
我建议你创建一个网格和权重方法。
这个答案分为三部分:
答案 1 :(得分:21)
创建一个新图像,具有实际宽度/高度(例如:600x800),但也是网格宽度/高度(例如: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();
我们可以看到:
现在,我们想知道如何编写一个3x4的矩形,并将其粘贴到我们的虚拟测量中的(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();
我们在网格中得到一个3x4的正方形(2,5):
现在让我们更加严格,我们有很好的措施,所以我们可以粘贴图像。
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();
我们得到:
这样我们就能在合适的地方拍照,但是我们失去了宽高比。让我们添加一个方法来正确调整图像大小。
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);
这看起来像这样:
我们现在有一个完整的功能类来完成你的工作。
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();
个人而言,我更喜欢没有保留宽高比的那个: - )
干杯! (呃,我会说!)
答案 2 :(得分: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则不需要,所以我们需要稍微欺骗一下。
// 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%,33%对于第二个。此虚拟高度将用作网格上的高度。
$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();
}
哦,你有这里的所有步骤。结果怎么样?
... F5
... F5
最终代码:
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();
}
我的方法可能不是最好的方法,但至少,它可以让您随意将图像定位到网格中,从而保留图像的重量。这个主题很难处理,所以我希望这对你的案子来说已经足够了。
答案 3 :(得分: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);
我们走了。