function graphicNovel($imagex, $imagey=null, $imgLoc=".", $PictureData, $frameSpacing=6, $penWidth=2, $col=null, $ti=null, $colWeight=75) { // Currently, the template will just keep trying to use as many images as it requires from PictureData. Please provide at least as many images as the biggest template requires. // Setting up the variables and arrays: // - imagex - width of resulting image // - imagey (optional) - height of resulting image. Default is 1.4142 times the value of imagex (ISO standard for paper size ratio) // - imgLoc (optional) = location of image files. Defaults to current directory. Since the new image handler code arrived, this is the root of user directories. // - PictureData - two dimensional array - index 1 stores each picture array. Each picture array contains ["P"] (picture) ["T"] (title) ["D"] (description) ["O"] (owner) // - frameSpacing (optional) - number of pixels wide for the white lines, exluding black outline. Default is 6 pixels. // - penWidth (optional)- the thickness of the line/bubble outlining. Default is 2 pixels. // - col (optional) - RGB values of the end colourise effect (form is as array with indexes ["R"], ["G"] and ["B"]. Probably obvious how to configure this.) // - ti (optional) - Template number. If left null, this will be picked at random from what's available. // - colWeight (optional) - how opaque the colour-covering is. A higher number reduces the comic's visibility. Default is 75 (%), but not used if $col is null. //putenv('GDFONTPATH=' . realpath('.')); // This works if the font is in the directory of the calling php... this should be explicitly set if the function will be used elsewhere. putenv('GDFONTPATH=/home/sites/llamalan.co.uk/public_html/fonts'); if($imagey == null) $imagey = $imagex; $templateCount = 7; // I've done this so that the script doesn't load templates unnecessarily. Must remember to update this though. // if($imagey == null) $imagey = $imagex * 1.4142; // 1.4142 : 1 is the aspect ratio of the ISO paper size standard. $percent = 1.0; // Dunno why I called this 'percent'. It's actually the multiplier of the image dimensions // used to create the first image in order to resample it down to the required dimensions. $imagexL = $imagex * $percent; // See? $imageyL = $imagey * $percent; $frameSpacing *= $percent; $penWidth *= $percent; // If the picture data doesn't work (if array is empty or one of the pictures don't exist) then we can't let the poor thing break if(!is_array($PictureData) || count($PictureData) == 0) { return itDead($imagex, $imagey, "No pictures."); } $im = imagecreatetruecolor($imagexL, $imageyL); //Why work on an image larger than the required size? To achieve antialiasing on all edges. $black = imagecolorallocate($im, 0, 0, 0); $white = imagecolorallocate($im, 255, 255, 255); if($ti == null || $ti < $templateCount) { $ti = rand(0, $templateCount); // Chosen template } if(count($PictureData) < 3) { $ti = -1; } // The PM function (polygon mark) - parameter one is the percentage wanted of parameter two. // the function returns a coordinate. // CONFIGURING TEMPLATES // // Setting up the comic template. // // Each template number contains image locations and sizes and lines. It may do masking as well to perform more interesting effects later... // // first index (e.g. templates[0]): This is the template no. // // second index (e.g. templates[0]["lines"): "lines" = lines that cannot be drawn using rectangles, "img" = image size, pos and text flag, "squares" = rectangles // // third index (e.g. templates[0]["lines"][0]: Config array for lines, rectangles, imgs. // $ti=4; switch($ti) { case 0: // TEMPLATE NUMERO UNO // Dominating image down entire left side, three small ones up top, four below. $templates["lines"][0] = array ( pm(30, $imagexL), pm(0, $imageyL), // Point 1 (x, y) pm(30, $imagexL), pm(100, $imageyL), // Point 2 (x, y) ); $templates["lines"][1] = array ( pm(30, $imagexL), pm(20, $imageyL), // width and height of image pm(100, $imagexL), pm(20, $imageyL), // coordinates ); $templates["lines"][2] = array ( pm(54.5, $imagexL), pm(0, $imageyL), // width and height of image pm(55.5, $imagexL), pm(20, $imageyL), // coordinates ); $templates["lines"][3] = array ( pm(80.5, $imagexL), pm(0, $imageyL), // width and height of image pm(79.5, $imagexL), pm(20, $imageyL), // coordinates ); $templates["lines"][4] = array ( pm(30, $imagexL), pm(60, $imageyL), // width and height of image pm(100, $imagexL), pm(60, $imageyL), // coordinates ); $templates["lines"][5] = array ( pm(63, $imagexL), pm(20, $imageyL), // width and height of image pm(63, $imagexL), pm(60, $imageyL), // coordinates ); $templates["lines"][6] = array ( pm(67, $imagexL), pm(60, $imageyL), // width and height of image pm(67, $imagexL), pm(100, $imageyL), // coordinates ); // Images $templates["img"][0] = array ( "imgW"=>pm(30, $imagexL), "imgH"=>pm(100, $imageyL), // width and height of image "imgX"=>pm(0, $imagexL), "imgY"=>pm(0, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][1] = array ( "imgW"=>pm(25, $imagexL), "imgH"=>pm(20, $imageyL), // width and height of image "imgX"=>pm(30, $imagexL), "imgY"=>pm(0, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][2] = array ( "imgW"=>pm(25, $imagexL), "imgH"=>pm(20, $imageyL), // width and height of image "imgX"=>pm(55, $imagexL), "imgY"=>pm(0, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][3] = array ( "imgW"=>pm(25, $imagexL), "imgH"=>pm(20, $imageyL), // width and height of image "imgX"=>pm(80, $imagexL), "imgY"=>pm(0, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][4] = array ( "imgW"=>pm(33, $imagexL), "imgH"=>pm(40, $imageyL), // width and height of image "imgX"=>pm(30, $imagexL), "imgY"=>pm(20, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][5] = array ( "imgW"=>pm(37, $imagexL), "imgH"=>pm(40, $imageyL), // width and height of image "imgX"=>pm(63, $imagexL), "imgY"=>pm(20, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][6] = array ( "imgW"=>pm(37, $imagexL), "imgH"=>pm(40, $imageyL), // width and height of image "imgX"=>pm(30, $imagexL), "imgY"=>pm(60, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][7] = array ( "imgW"=>pm(33, $imagexL), "imgH"=>pm(40, $imageyL), // width and height of image "imgX"=>pm(67, $imagexL), "imgY"=>pm(60, $imageyL), // coordinates "text" => 1, // show text or not? ); break; case 1: // TEMPLATE TWO // A central image, surrounded by three others with a 100% wide one at its lower half. Three smaller ones line the bottom of the page. $templates["lines"][1] = array ( pm(50, $imagexL), pm(0, $imageyL), // Point 1 (x, y) pm(50, $imagexL), pm(5, $imageyL), // Point 2 (x, y) ); $templates["lines"][2] = array ( pm(0, $imagexL), pm(40, $imageyL), // Point 1 (x, y) pm(25, $imagexL), pm(40, $imageyL), // Point 2 (x, y) ); $templates["lines"][3] = array ( pm(75, $imagexL), pm(40, $imageyL), // Point 1 (x, y) pm(100, $imagexL), pm(40, $imageyL), // Point 2 (x, y) ); $templates["lines"][4] = array ( pm(0, $imagexL), pm(80, $imageyL), // Point 1 (x, y) pm(100, $imagexL), pm(80, $imageyL), // Point 2 (x, y) ); $templates["squares"][1] = array ( pm(25, $imagexL), pm(5, $imageyL), // Point 1 (x, y) pm(75, $imagexL), pm(75, $imageyL), // Point 2 (x, y) ); $templates["squares"][2] = array ( pm(33, $imagexL), pm(80, $imageyL), // Point 1 (x, y) pm(66, $imagexL), pm(110, $imageyL), // Point 2 (x, y) ); $templates["img"][0] = array ( "imgW"=>pm(50, $imagexL), "imgH"=>pm(40, $imageyL), // width and height of image "imgX"=>pm(0, $imagexL), "imgY"=>pm(0, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][1] = array ( "imgW"=>pm(50, $imagexL), "imgH"=>pm(40, $imageyL), // width and height of image "imgX"=>pm(50, $imagexL), "imgY"=>pm(0, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][2] = array ( "imgW"=>pm(100, $imagexL), "imgH"=>pm(40, $imageyL), // width and height of image "imgX"=>pm(0, $imagexL), "imgY"=>pm(40, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][3] = array ( "imgW"=>pm(50, $imagexL), "imgH"=>pm(70, $imageyL), // width and height of image "imgX"=>pm(25, $imagexL), "imgY"=>pm(5, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][4] = array ( "imgW"=>pm(33, $imagexL), "imgH"=>pm(20, $imageyL), // width and height of image "imgX"=>pm(0, $imagexL), "imgY"=>pm(80, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][5] = array ( "imgW"=>pm(33, $imagexL), "imgH"=>pm(20, $imageyL), // width and height of image "imgX"=>pm(33, $imagexL), "imgY"=>pm(80, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][6] = array ( "imgW"=>pm(33, $imagexL), "imgH"=>pm(20, $imageyL), // width and height of image "imgX"=>pm(66, $imagexL), "imgY"=>pm(80, $imageyL), // coordinates "text" => 0, // show text or not? ); break; case 2: // TEMPLATE THREE // Going for drama and less dialogue! Two thin pics either side, with five short but very wide ones vertically. $templates["squares"][0] = array ( pm(0, $imagexL), pm(5, $imageyL), // Point 1 (x, y) pm(20, $imagexL), pm(85, $imageyL), // Point 2 (x, y) ); $templates["squares"][1] = array ( pm(80, $imagexL), pm(15, $imageyL), // Point 1 (x, y) pm(100, $imagexL), pm(95, $imageyL), // Point 2 (x, y) ); $templates["squares"][2] = array ( pm(20, $imagexL), pm(20, $imageyL), // Point 1 (x, y) pm(80, $imagexL), pm(40, $imageyL), // Point 2 (x, y) ); $templates["squares"][3] = array ( pm(20, $imagexL), pm(60, $imageyL), // Point 1 (x, y) pm(80, $imagexL), pm(80, $imageyL), // Point 2 (x, y) ); $templates["img"][0] = array ( "imgW"=>pm(100, $imagexL), "imgH"=>pm(20, $imageyL), // width and height of image "imgX"=>pm(0, $imagexL), "imgY"=>pm(0, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][1] = array ( "imgW"=>pm(80, $imagexL), "imgH"=>pm(20, $imageyL), // width and height of image "imgX"=>pm(10, $imagexL), "imgY"=>pm(20, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][2] = array ( "imgW"=>pm(80, $imagexL), "imgH"=>pm(20, $imageyL), // width and height of image "imgX"=>pm(10, $imagexL), "imgY"=>pm(40, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][3] = array ( "imgW"=>pm(80, $imagexL), "imgH"=>pm(20, $imageyL), // width and height of image "imgX"=>pm(10, $imagexL), "imgY"=>pm(60, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][4] = array ( "imgW"=>pm(100, $imagexL), "imgH"=>pm(20, $imageyL), // width and height of image "imgX"=>pm(0, $imagexL), "imgY"=>pm(80, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][5] = array ( "imgW"=>pm(20, $imagexL), "imgH"=>pm(80, $imageyL), // width and height of image "imgX"=>pm(0, $imagexL), "imgY"=>pm(5, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][6] = array ( "imgW"=>pm(20, $imagexL), "imgH"=>pm(80, $imageyL), // width and height of image "imgX"=>pm(80, $imagexL), "imgY"=>pm(15, $imageyL), // coordinates "text" => 0, // show text or not? ); break; case 3: // TEMPLATE FOUR // Another interesting overlaying effect one - three tall panels overlay a dominant single background image. $templates["img"][0] = array ( "imgW"=>pm(100, $imagexL), "imgH"=>pm(100, $imageyL), // width and height of image "imgX"=>pm(0, $imagexL), "imgY"=>pm(0, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][1] = array ( "imgW"=>pm(28, $imagexL), "imgH"=>pm(70, $imageyL), // width and height of image "imgX"=>pm(5, $imagexL), "imgY"=>pm(8, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][2] = array ( "imgW"=>pm(28, $imagexL), "imgH"=>pm(70, $imageyL), // width and height of image "imgX"=>pm(36, $imagexL), "imgY"=>pm(16, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][3] = array ( "imgW"=>pm(28, $imagexL), "imgH"=>pm(70, $imageyL), // width and height of image "imgX"=>pm(67, $imagexL), "imgY"=>pm(24, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["squares"][0] = array ( pm(5, $imagexL), pm(8, $imageyL), // Point 1 (x, y) pm(33, $imagexL), pm(78, $imageyL), // Point 2 (x, y) ); $templates["squares"][1] = array ( pm(36, $imagexL), pm(16, $imageyL), // Point 1 (x, y) pm(64, $imagexL), pm(86, $imageyL), // Point 2 (x, y) ); $templates["squares"][2] = array ( pm(67, $imagexL), pm(24, $imageyL), // Point 1 (x, y) pm(95, $imagexL), pm(94, $imageyL), // Point 2 (x, y) ); break; case 4: // TEMPLATE FIVE - for single images! $templates["img"][0] = array ( "imgW"=>pm(100, $imagexL), "imgH"=>pm(100, $imageyL), // width and height of image "imgX"=>pm(0, $imagexL), "imgY"=>pm(0, $imageyL), // coordinates "text" => 1, // show text or not? ); break; case -1: // TEMPLATE FIVE - for single images! $templates["img"][0] = array ( "imgW"=>pm(100, $imagexL), "imgH"=>pm(100, $imageyL), // width and height of image "imgX"=>pm(0, $imagexL), "imgY"=>pm(0, $imageyL), // coordinates "text" => 1, // show text or not? ); break; case 5: // TEMPLATE SIX - Another arrangement of boxes, but some have bigger borders than others // Stolen from http://www.aikidoonline.com/Manga%20comic%20pages/images/images.part2/takemusu02-02v.jpg $templates["img"][0] = array ( "imgW"=>pm(37.3, $imagexL), "imgH"=>pm(21.25, $imageyL), // width and height of image "imgX"=>pm(9, $imagexL), "imgY"=>pm(6.25, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][1] = array ( "imgW"=>pm(47.42, $imagexL), "imgH"=>pm(26.63, $imageyL), // width and height of image "imgX"=>pm(44.5, $imagexL), "imgY"=>pm(0, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][2] = array ( "imgW"=>pm(84.5, $imagexL), "imgH"=>pm(30.42, $imageyL), // width and height of image "imgX"=>pm(9, $imagexL), "imgY"=>pm(28.52, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][3] = array ( "imgW"=>pm(56.49, $imagexL), "imgH"=>pm(39.73, $imageyL), // width and height of image "imgX"=>pm(0, $imagexL), "imgY"=>pm(60.69, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][4] = array ( "imgW"=>pm(35.67, $imagexL), "imgH"=>pm(39.31, $imageyL), // width and height of image "imgX"=>pm(56.49, $imagexL), "imgY"=>pm(60.69, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["lines"][0] = array ( pm(0, $imagexL), pm(0, $imageyL), // Point 1 (x, y) pm(45, $imagexL), pm(0, $imageyL), // Point 2 (x, y) pm(12.518, $imageyL), // Optional thickness ); $templates["lines"][1] = array ( pm(4.4329, $imagexL), pm(0, $imageyL), // Point 1 (x, y) pm(4.4329, $imagexL), pm(60, $imageyL), // Point 2 (x, y) pm(8.8659, $imagexL), ); $templates["lines"][2] = array ( pm(44.7422, $imagexL), pm(0, $imageyL), // Point 1 (x, y) pm(44.7422, $imagexL), pm(28.8209, $imageyL), // Point 2 (x, y) ); $templates["lines"][3] = array ( pm(0, $imagexL), pm(27.5109, $imageyL), // Point 1 (x, y) pm(100, $imagexL), pm(27.5109, $imageyL), // Point 2 (x, y) pm(3.0567, $imageyL), ); $templates["lines"][4] = array ( pm(0, $imagexL), pm(58.98, $imageyL), // Point 1 (x, y) pm(100, $imagexL), pm(58.98, $imageyL), // Point 2 (x, y) pm(3.0567, $imageyL), ); $templates["lines"][5] = array ( pm(95.876, $imagexL), pm(0, $imageyL), // Point 1 (x, y) pm(95.876, $imagexL), pm(100, $imageyL), // Point 2 (x, y) pm(8.8659, $imagexL), ); $templates["lines"][6] = array ( pm(56.288, $imagexL), pm(60.116, $imageyL), // Point 1 (x, y) pm(56.288, $imagexL), pm(100, $imageyL), // Point 2 (x, y) ); break; case 6: // TEMPLATE SEVEN - Two biggies top and bottom with three smaller ones down the middle. Nice balance. // Stolen from http://tn3-2.deviantart.com/fs11/300W/i/2006/235/1/f/Graphic_novel_03___COLOR_by_JSA.jpg $templates["img"][0] = array ( "imgW"=>pm(100, $imagexL), "imgH"=>pm(40, $imageyL), // width and height of image "imgX"=>pm(0, $imagexL), "imgY"=>pm(6, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][1] = array ( "imgW"=>pm(100, $imagexL), "imgH"=>pm(37.5, $imageyL), // width and height of image "imgX"=>pm(0, $imagexL), "imgY"=>pm(57, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][2] = array ( "imgW"=>pm(39, $imagexL), "imgH"=>pm(32, $imageyL), // width and height of image "imgX"=>pm(12.5, $imagexL), "imgY"=>pm(10.5, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][3] = array ( "imgW"=>pm(77, $imagexL), "imgH"=>pm(16, $imageyL), // width and height of image "imgX"=>pm(12.6, $imagexL), "imgY"=>pm(43, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][4] = array ( "imgW"=>pm(35, $imagexL), "imgH"=>pm(31.5, $imageyL), // width and height of image "imgX"=>pm(12.5, $imagexL), "imgY"=>pm(60, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["squares"][0] = array ( pm(12.5, $imagexL), pm(10.5, $imageyL), // Point 1 (x, y) pm(51.5, $imagexL), pm(42.3, $imageyL), // Point 2 (x, y) ); $templates["squares"][1] = array ( pm(12.6, $imagexL), pm(43.1, $imageyL), // Point 1 (x, y) pm(90, $imagexL), pm(59.1, $imageyL), // Point 2 (x, y) ); $templates["squares"][2] = array ( pm(12.5, $imagexL), pm(60, $imageyL), // Point 1 (x, y) pm(47.1, $imagexL), pm(91.7, $imageyL), // Point 2 (x, y) ); break; case 7: // TEMPLATE EIGHT - split horizontally in three, the centre panel split in two. An inset at the bottom. // Stolen from http://www.geocities.com/nefarious_guy/042403_blankets184large.jpg $templates["img"][0] = array ( "imgW"=>pm(94, $imagexL), "imgH"=>pm(29.5, $imageyL), // width and height of image "imgX"=>pm(3, $imagexL), "imgY"=>pm(2.5, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][1] = array ( "imgW"=>pm(46, $imagexL), "imgH"=>pm(31, $imageyL), // width and height of image "imgX"=>pm(3, $imagexL), "imgY"=>pm(33.5, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["img"][2] = array ( "imgW"=>pm(45, $imagexL), "imgH"=>pm(31, $imageyL), // width and height of image "imgX"=>pm(51, $imagexL), "imgY"=>pm(33.5, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][3] = array ( "imgW"=>pm(94.5, $imagexL), "imgH"=>pm(30.5, $imageyL), // width and height of image "imgX"=>pm(3, $imagexL), "imgY"=>pm(66, $imageyL), // coordinates "text" => 1, // show text or not? ); $templates["img"][4] = array ( "imgW"=>pm(24.5, $imagexL), "imgH"=>pm(21.5, $imageyL), // width and height of image "imgX"=>pm(70.5, $imagexL), "imgY"=>pm(73.5, $imageyL), // coordinates "text" => 0, // show text or not? ); $templates["squares"][0] = array ( pm(3, $imagexL), pm(2.5, $imageyL), // Point 1 (x, y) pm(97.5, $imagexL), pm(32.5, $imageyL), // Point 2 (x, y) ); $templates["squares"][1] = array ( pm(3, $imagexL), pm(33.5, $imageyL), // Point 1 (x, y) pm(49, $imagexL), pm(64.5, $imageyL), // Point 2 (x, y) ); $templates["squares"][2] = array ( pm(51, $imagexL), pm(33.5, $imageyL), // Point 1 (x, y) pm(97.5, $imagexL), pm(64.5, $imageyL), // Point 2 (x, y) ); $templates["squares"][3] = array ( pm(3, $imagexL), pm(66, $imageyL), // Point 1 (x, y) pm(97.5, $imagexL), pm(97, $imageyL), // Point 2 (x, y) ); $templates["squares"][4] = array ( pm(70.5, $imagexL), pm(73.5, $imageyL), // Point 1 (x, y) pm(95, $imagexL), pm(95, $imageyL), // Point 2 (x, y) ); break; } // IMAGES // Generate a new colour for any colourisings $newColourRGB = array(rand(0,200), rand(0,200), rand(0,200)); $newColour = Image::rgb2hex($newColourRGB); $colourAll = false; //if(rand(0,3)==2) // { // One in three chance of colourising pages $colourAll = true; // } $imgTypes = array(1 => 'GIF', 2 => 'JPG', 3 => 'PNG'); // Loop through the template's image settings if(is_array($templates["img"])) { if (count($templates["img"]) < count($PictureData)) { $imgCount = count($PictureData); } else { $imgCount = count($templates["img"]); } for($i=0; $i<$imgCount; $i++) { $imageFullPath = $imgLoc . $PictureData[$i]["O"] . "/"; $imageFullPathFile = $imageFullPath . $PictureData[$i]["P"]; if(!is_file($imageFullPathFile)) { return itDead($imagex, $imagey, "The file\r\n" . $PictureData[$i]["P"] . "\r\nis dead."); } if(!$imLLspecs = @getimagesize($imageFullPathFile)) { return itDead($imagex, $imagey, $PictureData[$i]["P"] . "\r\ndoesn't exist.\r\nThere may not be enough images."); } // To load on images, grab em, draw polys on em, and set the colour of the poly to be transparent. Then merge. Let's try it. $imLLspecs = getimagesize($imageFullPathFile); // Some pics are big and use up a lot of memory to process. If too large, we run out of allocated memory. if($imLLspecs[0] * $imLLspecs[1] > 1440000) { $imLL = imagecreatetruecolor(50, 50); $imLLspecs[0] = 50; $imLLspecs[1] = 50; //continue; } else { // Handle GIFs (1), JPEGs (2) and PNGs(3) switch ($imLLspecs[2]) { case 1: // GIF $imLL = imagecreatefromgif($imageFullPathFile); break; case 2: // JPEG $imLL = imagecreatefromjpeg($imageFullPathFile); break; case 3: // PNG $imLL = imagecreatefrompng($imageFullPathFile); break; default: $imLL = imagecreatetruecolor(50, 50); $imLLspecs[0] = 50; $imLLspecs[1] = 50; break; } } //Take the middle of the image, cropped to the size specified in the template. //Source X = (Image width - Specified width) / 2. //Source Y = (Image height - Specified height) / 2. $TmpIm = $templates["img"][$i]; if($TmpIm["imgW"] <= 0 && $TmpIm["imgH"] <= 0) { continue; } // Hmmm. If the picture is too short, extend it high and make sure its width remains the same ratio. // But if it is too slim, extend its width to fill the wide frame. We must ensure the height is no smaller if it has already been adjusted. // So, adjust height if needed. If new /current width is too slim, make it fatter. In theory, if this is the case after extending its height, // this move will only make it taller. if($imLLspecs[1] < $TmpIm["imgH"]) { $newHeight = $TmpIm["imgH"]; $newWidth = $imLLspecs[0] * ($newHeight / $imLLspecs[1]); } else { $newWidth = $imLLspecs[0]; // This is the case if the picture is bigger than the frame in both directions. $newHeight = $imLLspecs[1]; // But is overwritten if the picture is too slim. Should work. } if($newWidth < $TmpIm["imgW"]) { $newWidth = $TmpIm["imgW"]; $newHeight = $imLLspecs[1] * ($newWidth / $imLLspecs[0]); } // Resize to fill template height/width? $image_r = imagecreatetruecolor($newWidth, $newHeight); imagecopyresized($image_r, $imLL, 0, 0, 0, 0, $newWidth, $newHeight, $imLLspecs[0], $imLLspecs[1]); $cropImY=0; $cropImX=0; if($newWidth > $TmpIm["imgW"]) { // Randomly pick an area along the image's width $cropImX = rand(0,round($newWidth - $TmpIm["imgW"])); } if($newHeight > $TmpIm["imgH"]) { // Bias the cropping towards the top (where faces tend to be) $cropImY = rand(round(($newHeight - $TmpIm["imgH"])/3),round(($newHeight - $TmpIm["imgH"])/5)); } $imCropped = imagecreatetruecolor($TmpIm["imgW"], $TmpIm["imgH"]); imagecopymerge($imCropped, $image_r, 0, 0, $cropImX, $cropImY, $TmpIm["imgW"], $TmpIm["imgH"], 100); $imageEffect = rand(1,3); switch($imageEffect) { //case 2: //$image_r = greyIt($image_r, $newWidth, $newHeight); // Image::greyscale($imCropped); // Image::colourise($imCropped, $newColour); // break; case 3: Image::threshold($imCropped, 120); break; default: if($colourAll) { // Don't colourise if we've applied other effects Image::colourise($imCropped, $newColour); } break; } //imagecopymerge($im, $image_r, $TmpIm["imgX"], $TmpIm["imgY"], $cropImX, $cropImY, $TmpIm["imgW"], $TmpIm["imgH"], 100); imagecopymerge($im, $imCropped, $TmpIm["imgX"], $TmpIm["imgY"], 0, 0, $TmpIm["imgW"], $TmpIm["imgH"], 100); } } $imgFramingOverlay = imagecreatetruecolor($imagex, $imagey); $trans_colour = imagecolorallocatealpha($imgFramingOverlay, 0, 0, 0, 127); imagefill($imgFramingOverlay, 0, 0, $trans_colour); imagecolortransparent($imgFramingOverlay, $trans_colour); $black = imagecolorallocate($imgFramingOverlay, 0, 0, 0); $white = imagecolorallocate($imgFramingOverlay, 255, 255, 255); imagesavealpha( $imgFramingOverlay, true ); // Draw the lines - first the black outlines, then the white insides. Seamless. imagesetthickness($imgFramingOverlay, $frameSpacing + ($penWidth * 2)); imagerectangle($imgFramingOverlay, 0, 0, $imagexL, $imageyL, $black); if(is_array($templates["squares"])) { foreach ($templates["squares"] as $poly) { imagerectangle($imgFramingOverlay, $poly[0], $poly[1], $poly[2], $poly[3], $black); } } if(is_array($templates["lines"])) { foreach ($templates["lines"] as $poly) { if(isset($poly[4])) { // If this line is supposed to be drawn at a thickness other than the default.... imagesetthickness($imgFramingOverlay, $poly[4] + ($penWidth * 2)); imageline($imgFramingOverlay, $poly[0], $poly[1], $poly[2], $poly[3], $black); imagesetthickness($imgFramingOverlay, $frameSpacing + ($penWidth * 2)); // Set it back } imageline($imgFramingOverlay, $poly[0], $poly[1], $poly[2], $poly[3], $black); } } imagesetthickness($imgFramingOverlay, $frameSpacing); imagerectangle($imgFramingOverlay, 0, 0, $imagexL, $imageyL, $white); if(is_array($templates["squares"])) { foreach ($templates["squares"] as $poly) { imagerectangle($imgFramingOverlay, $poly[0], $poly[1], $poly[2], $poly[3], $white); } } if(is_array($templates["lines"])) { foreach ($templates["lines"] as $poly) { if(isset($poly[4])) { // If this line is supposed to be drawn at a thickness other than the default.... imagesetthickness($imgFramingOverlay, $poly[4]); imageline($imgFramingOverlay, $poly[0], $poly[1], $poly[2], $poly[3], $white); imagesetthickness($imgFramingOverlay, $frameSpacing); // Set it back } imageline($imgFramingOverlay, $poly[0], $poly[1], $poly[2], $poly[3], $white); } } // For balloons - pick a shape. Place it along the top or side of each image., and then randomly either display or don't - 1/3 chance if(is_array($templates["img"])) { for($i=0; $i<$imgCount; $i++) { if($templates["img"][$i]["text"] == 1 && rand(1,3)>1) // Check the flag, to see if we want the text or not. and 2/3 chance of showing it { if(rand(1,3)==2) { $textIndex = "T"; } else { $textIndex = "D"; } if(rand(2,2) == 2 && is_array($templates["img"][$i]) && $PictureData[$i][$textIndex] != "") { $imgData = $templates["img"][$i]; imagetxttextfit($imgFramingOverlay, round(8 * $percent), 0, $imgData["imgX"], $imgData["imgY"], $imgData["imgW"], $imgData["imgH"], $black, $PictureData[$i][$textIndex], $penWidth); } } } } // Resize - acheiving anti-alias and smaller images. // $image_p = imagecreatetruecolor($imagex, $imagey); // imagecopyresampled($image_p, $im, 0, 0, 0, 0, $imagex, $imagey, $imagexL, $imageyL); if(is_array($col)) { // $im_colour = imagecreatetruecolor($imagex, $imagey); // $colourise = imagecolorallocate($im_colour, $col["r"], $col["g"], $col["b"]); // imagefill($im_colour, 0, 0, $colourise); // imagecopymerge($image_p, $im_colour, 0, 0, 0, 0, $imagex, $imagey, $colWeight); $userColour = Image::rgb2hex($col); Image::colourise($im, $userColour); } return $imgFramingOverlay; } /* function greyIt($sourceImage, $img_width, $img_height) { // convert to grayscale // note: this will NOT affect your original image, unless // originalFileName and destinationFileName are the same for ($y = 0; $y <$img_height; $y++) { for ($x = 0; $x <$img_width; $x++) { $rgb = imagecolorat($sourceImage, $x, $y); $red = ($rgb >> 16) & 0xFF; $green = ($rgb >> 8) & 0xFF; $blue = $rgb & 0xFF; $gray = round(.299*$red + .587*$green + .114*$blue); // shift gray level to the left $grayR = $gray << 16; // R: red $grayG = $gray << 8; // G: green $grayB = $gray; // B: blue // OR operation to compute gray value $grayColor = $grayR | $grayG | $grayB; // set the pixel color imagesetpixel ($sourceImage, $x, $y, $grayColor); imagecolorallocate ($sourceImage, $gray, $gray, $gray); } } return $sourceImage; }*/ function itDead($x, $y, $z) { $im = imagecreatetruecolor($x, $y); $black = imagecolorallocate($im, 0, 0, 0); $white = imagecolorallocate($im, 255, 255, 255); imagefill($im, 0, 0, $black); imagettftext($im, 15, 0, 15, $y/5, $white, "comic", "Fail!!1!1"); imagettftext($im, 7, 0, 15, $y/3, $white, "comic", $z); imagettftext($im, 7, 0, $x/3, $y - $y/6, $white, "comic", "www.llamalan.co.uk"); return $im; } function pm($x, $y) { // The PM function (polygon mark) - parameter one is the percentage wanted of parameter two. $z = $y * ($x / 100); return round($z); } function removeBBCode($x) { // phpbb3's smilies are saved in this format: // // So we want to // a) Drop // c) drop everything from that character onwards // Regular Expression to kill off the HTML tag // We don't want to kill comments yet as that contains the smiley itself, hence the [^!] // the part ".+" matches any string one or more times. // the part "\/>" escapes the forward slash character so we can ask it to go as far as the literal string "/>" // We want to remove the 2nd smiley comment as well $htmlStringSearch = "/<[^!].+?>/"; // Identify smilies. We may be able to do them all in one foul swoop without a fowl loop. // And we can! Woot! If using groups in regular expressions, the matches can be used in replacement strings as $1 (1st group), $2 (2nd group), etc. // The pattern \s* matches 0 or more white space characters $smileySearch = "//"; // So far I've used the question mark after the + (one or more) condition so the matching is not 'greedy'. // Basically, it doesn't keep going even after stumbling over the rest of the pattern //... I think $remainingBBSearch = "/\[.+?\]/"; $arySearches = array($htmlStringSearch, $smileySearch, $remainingBBSearch); $aryReplacements = array("", "$1", ""); return preg_replace($arySearches, $aryReplacements, $x); } function imagetxttextfit($im, $size, $angle, $x, $y, $w, $h, $color, $text, $penWidth) { $black = imagecolorallocate($im, 0, 0, 0); $white = imagecolorallocate($im, 255, 255, 255); $text=html_entity_decode($text); // Drop "'s and stuff and use proper chars. Until the web gains sentience, this should not be optional. $text=removeBBCode($text); // Remove any phpbb markup. Particularly troublesome are the smilies. // Start location - Y. Anywhere from top to bottom. // But if a title, it must be top or bottom // If Y <= image height / 3, BoxWidth should be imageWidth/4 and X should be 0+rand(15) or (ImageWidth-(rand(15)-BoxWidth) if(strlen($text) < 25 && rand(1,2)==2) { $size *= 2.5; //$font = "comicbd.ttf"; $font="badabb.ttf"; if (rand(1,2)==2) { $boxY = $y + 10 + rand(0, 30); } else { $boxY = $y + rand($h-250, $h-50); } $boxW = $w * 0.85; $boxX = $x + 10 + rand(0,$w-$boxW+30); } else { //$font = "comic.ttf"; $font="laffayette.ttf"; $boxY = $y + 10 + rand(0, $h); if($boxY-$y <= $h * 0.7) { $boxW = $w*0.25; if (rand(1,2)==2) { $boxX = $x + 10 + rand(0,15); } else { $boxX = ($w+$x) - rand(10,25) - $boxW; } } else { $boxW = $w*0.65; $boxX = $x + 10 + rand(0,$w-$boxW+30); } } $pieces = explode(" ", $text); $count = 0; // $ii = 0; // Loop at least once $size++; // The following loop contains other loops. // The first loop inside the 'do' runs through each word of the text, adding it to the string. // This is done as a loop so that we can work out when to insert a carriage return. // Using the handy imagetftbbox function, we can find out if it is too many pixels wide. // If so, insert a carriage return and continue on the next line. // The containing 'do' loop runs at least once, and repeats the whole process if the box is too high. // If it has to repeat, the font is reduced in size by one, and we try again from scratch. // Eventually, we end up with a nicely filled box that fits inside whatever size of frame is given it. do { // loop. Build newtxt from $pieces until the length of it is greater than linelen. insert \r\n, start again. $i=0; $newText=""; $check = 0; $size--; $count++; while($i < count($pieces) && $check<100) { $check++; $j=""; // Find out the current width of the text $bbox = imagettfbbox ($size, $angle, $font, $j . $pieces[$i]); $textWidth = $bbox[2] - $bbox[0]; // While this width is less than the supplied box width, keep adding them words // If this occurs at least once, check is 0. If it is greater, it means that the next word // cannot fit on one line // Note the calculation $boxW-12 : Later on the text is placed 6px away from left border, so double this to get 6px either side while($textWidth < ($boxW-12) && $i < count($pieces)) { $j .= $pieces[$i]; $i++; $check = 0; if($i < count($pieces)) { $j .= " "; } // Re-evaluate the width of the text $bbox = imagettfbbox ($size, $angle, $font, $j . $pieces[$i]); $textWidth = $bbox[2] - $bbox[0]; } if($check > 0) { // This word can't fit. Reduce font size and try again. $size--; } else { // Cannot squeeze any more words onto this line. Carriage return! $newText .= $j; $newText .= "\r\n"; } } $bbox = imagettfbbox ($size, $angle, $font, $newText); $textWidth = $bbox[2] - $bbox[0]; $textHeight = $bbox[1] - $bbox[7]; $boxH = $textHeight + 10; } while($boxH > $h && $count < 100); $count = 0; // every chance that an image may be too slim with a box too high, which will blatter the server without a safeguard while($boxY + $boxH > ($y + $h - 5) && $count < 100) { $boxY -= 10; $count++; } while($boxX + $boxW > ($x + $w) && $count < 100) { $boxX -= 10; $count++; } while($boxY < 0 && $count < 100) { $boxY += 5; $count++; } // To draw a box/ellipse with the black edge, draw black first offset by penwidth, then draw a size with double the pen width added on... // make sense? Thought not. $penWidth2 = $penWidth*2; // The ellipses only work if the box is not too short. Otherwise, they are way too long. Hence, the check to ensure the box width is nor more than 8 times the height. // Also, only use ellipses if the text takes more than one line. A bit silly otherwise. if(rand(1,2)==2 && $boxW < ($boxH*4) && $boxW < ($x*0.8) && strstr($newText, "\r\n")) { imagefilledellipse ($im, $boxX+round($boxW/2)-5, $boxY+round($boxH/2)-5, ($boxW*1.35)+$penWidth2, ($boxH*1.3)+$penWidth2, $black); imagefilledellipse ($im, $boxX+round($boxW/2)-5, $boxY+round($boxH/2)-5, $boxW*1.35, $boxH*1.3, $white); } else { imagefilledrectangle ($im, $boxX-$penWidth, $boxY-$penWidth, $boxW + $boxX +$penWidth , $boxH + $boxY + $penWidth, $black); imagefilledrectangle ($im, $boxX, $boxY, $boxW +$boxX, $boxH + $boxY, $white); } $boxX += 6; $boxY += 6 + $size; imagettftext($im, $size, $angle, $boxX, $boxY, $color, $font, $newText); } // // class.image.php // version 1.0.0, 2004-08-16 // // Description // // A PHP library of helpful image processing methods. This class does not // need to be instantiated. // // Author // // Andrew Collington, 2004 // php@amnuts.com, http://php.amnuts.com/ // // Feedback // // There is message board at the following address: // // http://php.amnuts.com/forums/index.php // // Please use that to post up any comments, questions, bug reports, etc. You // can also use the board to show off your use of the script. // // License // // This class is available free of charge for personal or non-profit work. If // you are using it in a commercial setting, please contact php@amnuts.com for // payment and licensing terms. // // Support // // If you like this script, or any of my others, then please take a moment // to consider giving a donation. This will encourage me to make updates and // create new scripts which I would make available to you. If you would like // to donate anything, then there is a link from my website to PayPal. // // Examples // // $img = imagecreatefromjpeg('original.jpg'); // Image::colourise($img, '4c63f2'); // imagejpeg($img, 'processed.jpg', 90); // // $img = imagecreatefromjpeg('original.jpg'); // Image::threshold($img, 128); // imagejpeg($img, 'processed.jpg', 90); // // $img = imagecreatefromjpeg('original.jpg'); // Image::greyscale($img); // imagejpeg($img, 'processed.jpg', 90); // // $hex = '#45F2C3'; // $hls = Image::rgb2hls(Image::hex2rgb($hex)); // $hls[0] = 192; // $hls[2] = 0.15; // echo Image::rgb2hex(Image::hls2rgb($hls)); // class Image { /** * Gathers the GD version information * * Sometimes a check for the GD version like this: * * (function_exists('imagecreatetruecolor')) ? 2 : 1; * * can fail. This method retrieves the GD information based on what PHP * reports to be installed. It can return the parsed version as an array, * or just the major version if you want to do a simple check. * * @return int|array * @param bool $justMajor * @access public */ function getGDVersion($justMajor = true) { static $version = array(); if (empty($version)) { ob_start(); phpinfo(); $buffer = ob_get_contents(); ob_end_clean(); if (preg_match('|GD Version