2012-10-16 12 views
9

मैं छोटे उत्पाद चित्रों से एक बड़ी छवि कोलाज बनाने के लिए एक फिनशड समाधान या संभवतः कुछ गणित/एल्गोरिदम ढूंढ रहा हूं? मुझे पता है कि इसे एक स्क्वायर फ़ैशन में कैसे किया जाए, जीडी/इमेजमैजिक के साथ एक ही आकार के चित्रों से, लेकिन मैं कुछ बदलाव करना चाहता हूं।PHP में छवि कोलाज

उदाहरण के लिए, कुछ चित्र थोड़ा लंबा हो सकते हैं, और यदि सभी एक ही आकार और वर्ग हैं - मैं चाहता हूं कि उनमें से एक डिजाइन को मिश्रण करने के लिए, अधिक जगह ले ले। इसे दिलचस्प रखते हुए।

जितना अधिक मैं सोचता हूं उतना कठिन यह सूत्र के साथ ऐसा लगता है। सभी संभावित परिदृश्यों के लिए पूर्वनिर्धारित "टेम्पलेट्स" होने के कारण काम नहीं किया जा रहा है क्योंकि चित्रों की मात्रा केवल 1 (कोई काम आवश्यक नहीं) से 10+ तक भिन्न हो सकती है।

मैं किसी भी घूर्णन या विशेष प्रभाव की तलाश नहीं कर रहा हूं, केवल ग्रिड में छवियों के साथ कुछ अंतर और बिना ओवरलैपिंग के चित्र।

कोई विचार यह कैसे पूरा करने के लिए है, और क्या वहां वास्तव में बाहर जाने के लिए तैयार नहीं है?

उत्तर

23

मैं आपको एक ग्रिड और वजन दृष्टिकोण बनाने का सुझाव देता हूं।

इस उत्तर 3 भागों में बांटा गया है:

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

वाह। शायद सबसे व्यापक उत्तर कभी। आपका बहुत बहुत धन्यवाद! यह निश्चित रूप से मुझे कुछ शुरू करने में जमीन के काम के लिए समय का एक गुच्छा बचाएगा! मेरी मुख्य समस्या अब यह गणना करने के लिए होगी कि छवियों को ग्रिड में कैसे रखा जाएगा .. मुझे विभिन्न छवि आकारों का ट्रैक रखने और ट्रैक करने की आवश्यकता है और उन्हें "$ imageGrid-> के साथ रखने के लिए गतिशील रूप से सबसे अनुकूलित लेआउट की गणना करने की आवश्यकता है। putImage ($ नीला, 6, 2, 0, 0); " - कोई विचार? –

+0

इस उत्तर को देखने में खुशी है आपकी मदद करता है।हां आप इस तरह से वजन को गतिशील रूप से निर्धारित कर सकते हैं: 1) अपनी सभी छवियों की चौड़ाई/ऊंचाई का योग बनाएं, 2) इस योग का उपयोग करके प्रत्येक छवि चौड़ाई/ऊंचाई का प्रतिशत प्राप्त करें, 3) 100x100 का ग्रिड बनाएं और उन प्रतिशत का उपयोग करें। मैं काम पर हूं, अभी आपको और अधिक मदद नहीं कर सकता है इसलिए मुझे बताएं कि आपको उदाहरण की आवश्यकता है, तो मैं इसे आज रात लिखने में सक्षम हूं (gmt + 2)। –

+0

हाय, और धन्यवाद! मुझे यकीन नहीं है कि मैं समझता हूं कि यह स्थिति को गतिशील रूप से निर्धारित करने में कैसे मदद करेगा - इसलिए एक उदाहरण बहुत अच्छा होगा। हो सकता है कि मुझे इसके बारे में कुछ और सोचने की ज़रूरत है, और आपने जो भी लिखा है उसे दोबारा पढ़ लें। लेकिन मैं उस उपन्यास के बाद आपसे अधिक पूछने के लिए शर्मिंदा हूं, आपने मुझे अभी लिखा है, हाहा। कोई चिंता नहीं, मैं जल्दबाजी में नहीं हूँ! –

19

एक आभासी ग्रिड

एक नई छवि बनाने के साथ काम करते हुए एक असली के साथ चौड़ाई/ऊंचाई (पूर्व: 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(); 

हम देख सकते हैं:

enter image description here

अब, हम जानना चाहते हैं कि 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(); 

हम अपने ग्रिड में (2,5) में positionned 3x4 के एक वर्ग मिलती है:

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

धन्यवाद! अलग नाम के साथ कोलाज छवि को डीआईआर में सहेजने का कोई तरीका है? @ एलेन टिम्बोलो –

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% होगा, और 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(); 
} 

शाबाशी, आप सभी चरणों यहां की है। परिणाम के बारे में क्या?

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

संबंधित मुद्दे