aspacecodyssey Posted August 18, 2009 Share Posted August 18, 2009 Hi -- first time poster here. Couldn't find an issue quite like this one by searching the forums, and I'm certainly R-ingTFM. I'm using jQuery cycle http://malsup.com/jquery/cycle/ to power a "create your own backpack" application for a client's website. Essentially, the concept is as follows: each piece of a backpack is a separate .png image, all the same dimensions, where the actual "piece" is placed inside the transparent area in its proper location. These pieces are overlayed atop one another the create the effect of the user being able to pick and choose the color of each piece. My issue is this: I want the user to be able to then save the created bag. This is how far I am: The URLs of the "current" images in the cycle are being passed to hidden form fields. When you hit the "Submit" button, those fields should be and are properly passed into the process of merging them. There's where I'm having an issue. There aren't a set amount of "pieces" for each different bag, so the amount of items in the array of images is also not finite. Essentially, I just want to take all of the images and lay them on top of one another to create one image. Here's the code for the page: <?php session_start(); if(!isset($_SESSION["user"])) { header("location:index.php"); } $page = 'Design Your Own Bag'; $bag = $_GET['bag']; include 'header.php'; ?> First, choose a bag style below. Then knock yourself out (colloquially speaking).<br /> <br /> <ul id="linenav"> <li><a href="?bag=10586s"><img src="images/design/lines/10586s_t.png" width="145" height="145" alt="" /></a></li> <li><a href="?bag=10602"><img src="images/design/lines/10602_t.png" width="145" height="145" alt="" /></a></li> <li><a href="?bag=10702"><img src="images/design/lines/10702_t.png" width="145" height="145" alt="" /></a></li> <li><a href="?bag=10576mb"><img src="images/design/lines/10576mb_t.png" width="145" height="145" alt="" /></a></li> <li><a href="?bag=10120m"><img src="images/design/lines/10120m_t.png" width="145" height="145" alt="" /></a></li> <li><a href="?bag=10505" class="last"><img src="images/design/lines/10505_t.png" width="145" height="145" alt="" /></a></li> </ul> <div id="load"></div> <div id="design-wrap" class="hide"> <div id="linecycle"> <?php if (isset($bag)) { if ($bag=='10586s' || $bag=='10702' || $bag=='10602' || $bag=='10576mb' || $bag=='10120m' || $bag=='10505') { switch ($bag) { case '10505': $options = array('Front-Top Panel' => 'ft', 'Front-Bottom Panel' => 'fb', 'Top/Sides' => 'top', 'Trim' => 'trim', 'Handle' => 'handle'); break; case '10602': $options = array('Body' => 'body', 'Trim' => 'trim', 'Front Panel' => 'fp', 'Pocket Panel' => 'pp', 'Handle' => 'handle'); break; case '10702': $options = array('Body' => 'body', 'Trim' => 'trim', 'Panel' => 'p', 'Handle' => 'handle'); break; case '10576mb': $options = array('Body' => 'body', 'Trim' => 'trim', 'Front Panel' => 'fp', 'Pocket Panel' => 'pp', 'Handle' => 'handle'); break; case '10120m': $options = array('Flap' => 'flap', 'Body' => 'body', 'High Trim' => 'ht', 'Low Trim' => 'lt'); break; case '10586s': $options = array('Body' => 'body', 'Panel' => 'p', 'Front Panel' => 'fp', 'High Trim' => 'ht', 'Low Trim' => 'lt'); break; default: echo '<img class="hidden" src="images/load.gif" alt="" />'; break; } unset($value); $count = count($options); $backpat = implode(array_slice($options, 0, 1)); echo "\n";?> <div class="patternacc <?php echo 'n'.$count; ?>"> <?php foreach($options as $call => $part) { echo "\n"; ?> <a href="#"><?php echo $call; ?></a> <div> <ul class="patternnav" id="pn-<?php echo $bag.'-'.$part; ?>"> <?php include 'patternnav.php'; ?> </ul> </div> <?php } echo "\n"; ?> </div> <div class="lineimg"> <img class="topimg" src="images/design/lines/<?php echo $bag; ?>.png" width="455" height="455" alt="" /> <?php foreach($options as $call => $part) { echo "\n"; ?> <div id="pc-<?php echo $bag.'-'.$part; ?>"> <?php if ($part == $backpat) { $bagpath = ''; $partpath = ''; $ext = '.gif'; } else { $bagpath = $bag.'/'; $partpath = $part.'/'; $ext = '.png'; } include 'patterncycle.php'; ?> </div> <?php } ?> </div> <div class="clear"></div> <div id="savebag"> To save your bag, click the “Save Bag” button below. Then show it to all your friends!<br /> <br /> <form method="post" action="testpost.php"> <div class="hidden"> <?php $i = 1; foreach($options as $call => $part) { ?> <textarea id="output<?php echo $bag.$part; ?>" rows="" cols="" name="<?php echo 'part'.$i; ?>"></textarea> <?php $i = $i + 1; } ?> </div> <p><input type="submit" name="submit" id="savebag-btn" value="Save Bag" /></p> </form> </div> <?php } else { echo '<META HTTP-EQUIV="Refresh" Content="0; URL=partner-design.php">'; exit; } } ?> </div> </div> <?php include 'footer.php'; ?> And here is the process code: <?php if (isset($_POST['submit'])) { $postcount = count($_POST); $postcount = $postcount - 1; $partarr = array(); for ($i = 1; $i <= $postcount; $i++) { $part = 'part'.$i; $part = $_POST[$part]; $partarr[$i] = $part; } header ("Content-type: image/png"); $imgBuf = array (); $iOut = imagecreatetruecolor("455","455"); foreach ($partarr as $link) { switch(substr($link,strrpos ($link,".")+1)) { case 'png': $iTmp = imagecreatefrompng($link); break; case 'gif': $iTmp = imagecreatefromgif($link); break; array_push ($imgBuf,$iTmp); } } for ($j = 1; $j <= $postcount; $j++) { imagecopy ($iOut,$imgBuf[$j],0,0,0,0,imagesx($imgBuf[$j]),imagesy($imgBuf[$j])); imagedestroy ($imgBuf[$j]); } imagepng($iOut); } ?> Quote Link to comment Share on other sites More sharing options...
jjacquay712 Posted August 19, 2009 Share Posted August 19, 2009 I'm not sure what the problem is from preventing your method from working, but instead of using gd to combine images, I would just do it client side. Here is what I would do: <?php // $url_array is an array holding the url's for the images to combine foreach ( $url_array as $url ) { echo '<div style="background-image: url(\'' . $url . '\'); width: 100px; height: 100px;">'; } foreach ( $url_array as $url ) { echo '</div>'; } ?> Quote Link to comment Share on other sites More sharing options...
jjacquay712 Posted August 19, 2009 Share Posted August 19, 2009 Working Code Example: <?php $url_array[] = "http://us.i1.yimg.com/us.yimg.com/i/us/av/logo.gif"; $url_array[] = "http://www.google.com/intl/en_ALL/images/logo.gif"; $url_array[] = "http://l.yimg.com/a/i/ww/beta/y3.gif"; foreach ( $url_array as $url ) { echo '<div style="background-image: url(\'' . $url . '\'); width: 1000px; height: 1000px;">'; } foreach ( $url_array as $url ) { echo '</div>'; } ?> Quote Link to comment Share on other sites More sharing options...
aspacecodyssey Posted August 19, 2009 Author Share Posted August 19, 2009 Here: http://www.topzipco.com/ I've set up a test user/pass: User: test Pass: passwd123 From there, click on "Design Your Own Bag", choose a bag, and test it out. Inside the page itself, I'm already doing what that solution would accomplish -- namely, overlaying the images to create the illusion of one single image. What I need to do now is to actually merge them into one image for real, so that the user can save that image. I'm just getting a black, blank image right now. I've changed it slightly in testing, so here's where I'm at: <?php if (isset($_POST['submit'])) { $postcount = count($_POST); // COUNTS THE AMOUNT OF POST VARIABLES $postcount = $postcount - 2; // DECREASES BY TWO FOR NEXT STEP $partover = $_POST['partover']; // PULLS IN ONE EXTRA IMAGE (THE TOP LINE DRAWING OF THE BACKPACK) $partarr = array(); for ($i = 1; $i <= $postcount; $i++) { $part = 'part'.$i; $part = $_POST[$part]; $partarr[$i] = $part; } $partarr[$i] = $partover; // NOW WE HAVE THE URL'S OF THE IMAGES IN AN ARRAY header ("Content-type: image/png"); $imgBuf = array (); $iOut = imagecreatetruecolor("455","455"); foreach ($partarr as $link) { switch(substr($link,strrpos ($link,".")+1)) { case 'png': $iTmp = imagecreatefrompng($link); break; case 'gif': $iTmp = imagecreatefromgif($link); break; array_push ($imgBuf,$iTmp); } } for ($j = 1; $j <= $postcount; $j++) { imagecopy ($iOut,$imgBuf[$j],0,0,0,0,imagesx($imgBuf[$j]),imagesy($imgBuf[$j])); imagedestroy ($imgBuf[$j]); } imagepng($iOut); } ?> Quote Link to comment Share on other sites More sharing options...
aspacecodyssey Posted August 19, 2009 Author Share Posted August 19, 2009 I feel like this might be closer -- still not working though. <?php if (isset($_POST['submit'])) { $postcount = count($_POST); // COUNTS THE AMOUNT OF POST VARIABLES $postcount = $postcount - 2; // DECREASES BY TWO FOR NEXT STEP $partover = $_POST['partover']; // PULLS IN ONE EXTRA IMAGE (THE TOP LINE DRAWING OF THE BACKPACK) $partarr = array(); for ($i = 1; $i <= $postcount; $i++) { $part = 'part'.$i; $part = $_POST[$part]; $partarr[$i] = $part; } $partarr[$i] = $partover; // NOW WE HAVE THE URL'S OF THE IMAGES IN AN ARRAY header ("Content-type: image/png"); $iOut = imagecreatetruecolor("455","455"); foreach ($partarr as $link) { switch(substr($link,strrpos ($link,".")+1)) { case 'png': $iTmp = imagecreatefrompng($link); break; case 'gif': $iTmp = imagecreatefromgif($link); break; } imagecopy($iOut,$iTmp,0,0,0,0,455,455); imagedestroy ($iTmp); } imagepng($iOut); } ?> Quote Link to comment Share on other sites More sharing options...
thebadbad Posted August 19, 2009 Share Posted August 19, 2009 I didn't read through your code, but I once wrote a simple function to merge two or more PNG images. Have a look: <?php //function merge_png() takes two or more URLs or paths to PNG files as arguments, and merges the PNGs function merge_png() { //check and store arguments if (func_num_args() < 2) { trigger_error('Wrong parameter count for merge_png()', E_USER_ERROR); return false; } $args = func_get_args(); //set image width and height $w = 80; $h = 100; //create blank, fully transparent canvas $im = imagecreatetruecolor($w, $h); imagesavealpha($im, true); $trans_color = imagecolorallocatealpha($im, 0, 0, 0, 127); imagefill($im, 0, 0, $trans_color); //merge PNGs foreach($args as $url) { $dest_im = imagecreatefrompng(str_replace(' ', '%20', $url)); imagecopy($im, $dest_im, 0, 0, 0, 0, $w, $h); } //output final image header('Content-type: image/png'); imagepng($im); imagedestroy($im); return true; } //usage //image credits goes to the creator merge_png( 'http://www.anitaria.com/images/avatars/equips/Mid Tone.png', 'http://www.anitaria.com/images/avatars/equips/Glasses.png' ); ?> Would be easy to make it take an array instead of several arguments. Quote Link to comment Share on other sites More sharing options...
aspacecodyssey Posted August 19, 2009 Author Share Posted August 19, 2009 I tried it, first testing without trying to implement the array on top of it, i.e.: <?php //function merge_png() takes two or more URLs or paths to PNG files as arguments, and merges the PNGs function merge_png() { //check and store arguments if (func_num_args() < 2) { trigger_error('Wrong parameter count for merge_png()', E_USER_ERROR); return false; } $args = func_get_args(); //set image width and height $w = 455; $h = 455; //create blank, fully transparent canvas $im = imagecreatetruecolor($w, $h); imagesavealpha($im, true); $trans_color = imagecolorallocatealpha($im, 0, 0, 0, 127); imagefill($im, 0, 0, $trans_color); //merge PNGs foreach($args as $url) { $dest_im = imagecreatefrompng(str_replace(' ', '%20', $url)); imagecopy($im, $dest_im, 0, 0, 0, 0, $w, $h); } //output final image header('Content-type: image/png'); imagepng($im); imagedestroy($im); return true; } //usage //image credits goes to the creator merge_png( 'http://www.topzipco.com/images/design/patterns/10586s/fp/pattern00-11.png', 'http://www.topzipco.com/images/design/patterns/10586s/ht/pattern00-115.png', 'http://www.topzipco.com/images/design/patterns/10586s/lt/pattern00-1795.png', 'http://www.topzipco.com/images/design/patterns/10586s/p/pattern00-469.png', 'http://www.topzipco.com/images/design/lines/10586s.png' ); ?> I'm so lost here. This seems like it should work. Quote Link to comment Share on other sites More sharing options...
thebadbad Posted August 19, 2009 Share Posted August 19, 2009 Doesn't it Does it not work? It does when I test it. Lol, me good at English Quote Link to comment Share on other sites More sharing options...
aspacecodyssey Posted August 19, 2009 Author Share Posted August 19, 2009 Huh -- yeah, it does work actually. It's the host I'm using -- I tested it on a different server, and it worked. Damn. Wonder if the original code will work there, too. Okay, so follow-up. It does seem like it should be a simple task to use an array instead of a list of images, but how would I do that? I'm really overthinking it. Quote Link to comment Share on other sites More sharing options...
thebadbad Posted August 19, 2009 Share Posted August 19, 2009 If allow_url_fopen is Off in the server settings, imagecreatefrompng() won't allow URLs. Could be your problem. Here's the modified function that takes an array: <?php //function merge_png() takes an array of URLs or paths to PNG files, and merges the PNGs function merge_png($pngs) { if (!is_array($pngs)) { trigger_error('Argument passed to merge_png() must be an array', E_USER_ERROR); return false; } //set image width and height $w = 455; $h = 455; //create blank, fully transparent canvas $im = imagecreatetruecolor($w, $h); imagesavealpha($im, true); $trans_color = imagecolorallocatealpha($im, 0, 0, 0, 127); imagefill($im, 0, 0, $trans_color); //merge PNGs foreach($pngs as $url) { $dest_im = imagecreatefrompng(str_replace(' ', '%20', $url)); imagecopy($im, $dest_im, 0, 0, 0, 0, $w, $h); } //output final image header('Content-type: image/png'); imagepng($im); imagedestroy($im); return true; } ?> Quote Link to comment Share on other sites More sharing options...
aspacecodyssey Posted August 19, 2009 Author Share Posted August 19, 2009 So now under that would just be merge_png($arr-name); ? Quote Link to comment Share on other sites More sharing options...
thebadbad Posted August 19, 2009 Share Posted August 19, 2009 Right. Quote Link to comment Share on other sites More sharing options...
aspacecodyssey Posted August 19, 2009 Author Share Posted August 19, 2009 Works like a charm. Test it out, it's quite fun: http://www.topzipco.com/ U: test P: passwd123 "Design Your Own Bag" > "Save Bag" It's still not working on the server I need it to work on, but the code itself works. Thanks! Quote Link to comment Share on other sites More sharing options...
thebadbad Posted August 19, 2009 Share Posted August 19, 2009 Cool, looks good Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.