We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 32645
    • 377 Posts
    I’m currently running the following as a snippet to test my GD library, but rather than showing a thumbnailed picture - it spews garbage. How do I fix this?

    Garbage produced;

    ?PNG  IHDR܀’? PLTE?͞??щDAT8?퐱 ð E傖϶BNጙU??)+Ն$)9@K?آ뱿? ?Ր?1??؍?8?9q?sU霌C~Ť뇹q?ˋΦQ??>0.,ۢ?ݨǭ?3ƴ??pD?蜽?Ylŏ74Ӕ?ۻ?kyĔkḲL??wT?9%fLC稺(ݸPU?쥻’?g.[{A?ᰶ„p襏??ºI?C7IEND?B`?

    // Snippet: testGDLibrary
    $tn_image = new Thumbnail("*image location goes here*", 0, 0, 25);
    $tn_image->show();
    
    class Thumbnail {
        var $errmsg	    = "";
        var $error	    = false;
        var $format	    = "";
        var $file	    = "";
        var $max_width  = 0;
        var $max_height = 0;
        var $percent    = 0;
    
        function Thumbnail($file, $max_width = 0, $max_height = 0, $percent = 0) {
    	if (!file_exists($file)) {
    	    $this->errmsg = "File doesn't exists";
    	    $this->error  = true;
    	}
    	else if (!is_readable($file)) {
    	    $this->errmsg = "File is not readable";
    	    $this->error  = true;
    	}
    
    	if (strstr(strtolower($file), ".gif")) {
    	    $this->format = "GIF";
    	}
    	else if (strstr(strtolower($file), ".jpg") ||
    		 strstr(strtolower($file), ".jpeg")) {
    	    $this->format = "JPEG";
    	}
    	else if (strstr(strtolower($file), ".png")) {
    	    $this->format = "PNG";
    	}
    	else {
    	    $this->errmsg = "Unknown file format";
    	    $this->error  = true;
    	}
    
    	if ($max_width == 0 && $max_height == 0 && $percent == 0) {
    	    $percent = 100;
    	}
    
    	$this->max_width  = $max_width;
    	$this->max_height = $max_height;
    	$this->percent	  = $percent;
    	$this->file	  = $file;
        }
    
        function calc_width($width, $height) {
    	$new_width  = $this->max_width;
    	$new_wp     = (100 * $new_width) / $width;
    	$new_height = ($height * $new_wp) / 100;
    	return array($new_width, $new_height);
        }
    
        function calc_height($width, $height) {
    	$new_height = $this->max_height;
    	$new_hp     = (100 * $new_height) / $height;
    	$new_width  = ($width * $new_hp) / 100;
    	return array($new_width, $new_height);
        }
    
        function calc_percent($width, $height) {
    	$new_width  = ($width * $this->percent) / 100;
    	$new_height = ($height * $this->percent) / 100;
    	return array($new_width, $new_height);
        }
    
        function return_value($array) {
    	$array[0] = intval($array[0]);
    	$array[1] = intval($array[1]);
    	return $array;
        }
    
        function calc_image_size($width, $height) {
    	$new_size = array($width, $height);
    
    	if ($this->max_width > 0 && $width > $this->max_width) {
    	    $new_size = $this->calc_width($width, $height);
    
    	    if ($this->max_height > 0 && $new_size[1] > $this->max_height) {
    		$new_size = $this->calc_height($new_size[0], $new_size[1]);
    	    }
    
    	    return $this->return_value($new_size);
    	}
    
    	if ($this->max_height > 0 && $height > $this->max_height) {
    	    $new_size = $this->calc_height($width, $height);
    	    return $this->return_value($new_size);
    	}
    
    	if ($this->percent > 0) {
    	    $new_size = $this->calc_percent($width, $height);
    	    return $this->return_value($new_size);
    	}
        }
    
        function show_error_image() {
    	header("Content-type: image/png");
    	$err_img   = ImageCreate(220, 25);
    	$bg_color  = ImageColorAllocate($err_img, 0, 0, 0);
    	$fg_color1 = ImageColorAllocate($err_img, 255, 255, 255);
    	$fg_color2 = ImageColorAllocate($err_img, 255, 0, 0);
    	ImageString($err_img, 3, 6, 6, "ERROR:", $fg_color2);
    	ImageString($err_img, 3, 55, 6, $this->errmsg, $fg_color1);
    	ImagePng($err_img);
    	ImageDestroy($err_img);
        }
    
        function show($name = "") {
    	if ($this->error) {
    	    $this->show_error_image();
    	    return;
    	}
    
    	$size      = GetImageSize($this->file);
    	$new_size  = $this->calc_image_size($size[0], $size[1]);
    	#
    	# Good idea from Mariano Cano Pérez
    	# Requires GD 2.0.1 (PHP >= 4.0.6)
    	#
    	if (function_exists("ImageCreateTrueColor")) {
    	    $new_image = ImageCreateTrueColor($new_size[0], $new_size[1]);
    	}
    	else {
    	    $new_image = ImageCreate($new_size[0], $new_size[1]);
    	}
    
    	switch ($this->format) {
    	    case "GIF":
    		$old_image = ImageCreateFromGif($this->file);
    		break;
    	    case "JPEG":
    		$old_image = ImageCreateFromJpeg($this->file);
    		break;
    	    case "PNG":
    		$old_image = ImageCreateFromPng($this->file);
    		break;
    	}
    
    	ImageCopyResized($new_image, $old_image, 0, 0, 0, 0, $new_size[0], $new_size[1], $size[0], $size[1]);
    
    	switch ($this->format) {
    	    case "GIF":
    		if (!empty($name)) {
    		    ImageGif($new_image, $name);
    		}
    		else {
    		    header("Content-type: image/gif");
    		    ImageGif($new_image);
    		}
    		break;
    	    case "JPEG":
    		if (!empty($name)) {
    		    ImageJpeg($new_image, $name);
    		}
    		else {
    		    header("Content-type: image/jpeg");
    		    ImageJpeg($new_image);
    		}
    		break;
    	    case "PNG":
    		if (!empty($name)) {
    		    ImagePng($new_image, $name);
    		}
    		else {
    		    header("Content-type: image/png");
    		    ImagePng($new_image);
    		}
    		break;
    	}
    
    	ImageDestroy($new_image);
    	ImageDestroy($old_image);
    	return;
        }
    
        function save($name) {
    	$this->show($name);
        }
    }
    
      • 28042 ☆ A M B ☆
      • 24,524 Posts
      That’s not garbage, that’s the binary representation of your thumbnail. Consider this a step in the right direction; now you just need to specify to the browser that this thing is an image so it will display it appropriately.
        Studying MODX in the desert - http://sottwell.com
        Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
        Join the Slack Community - http://modx.org
        • 32645
        • 377 Posts
        Is there an example? I’m still stumped as to how to make it generate the image; I mean it already has a header function in there telling it’s a jpeg or png... what else am I missing?
          • 28042 ☆ A M B ☆
          • 24,524 Posts
          Sorry...that’s the extent of my knowlege on the subject! I’m sure someone else who knows more will respond in a short time.
            Studying MODX in the desert - http://sottwell.com
            Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
            Join the Slack Community - http://modx.org
            • 10487 MODX Staff
            • 1,535 Posts
            Quote from: worchyld at Jun 05, 2006, 09:26 AM

            Is there an example? I’m still stumped as to how to make it generate the image; I mean it already has a header function in there telling it’s a jpeg or png... what else am I missing?
            I could be wrong but I don’t think header redirects will function correctly when contained within a snippet - which would explain the binary representation being outputted.

            Does the script work if called external to MODx?
              Garry Nutting
              Senior Developer
              MODX, LLC

              Email: [email protected]
              Twitter: @garryn
              Web: modx.com
              • 22303 MODX Staff
              • 10,725 Posts
              That’s correct, and I’m trying to think of how you might change the content-type on the fly and have the output reflect that, but I’m not sure of the best way to approach this myself. I just used something similar to create PNG line graphs on the fly from a set of data and simply changed the content type of a document to image/png (after adding that as a valid content-type in System Settings) containing that snippet. I suppose setting the document content type from the snippet should be possible as well, but, you’d probably need to include this (via img tags or CSS) as you would any valid image file in a page for it to be really useful. Otherwise, the entire output of the page is limited to the image type being returned and you’d have to change it dynamically in the snippet, depending on what type of image was being returned.
                • 28042 ☆ A M B ☆
                • 24,524 Posts
                So how does the text-to-image snippet that makes images of text using a given font work? I’ve used it and it works great. But I don’t know how it works.
                  Studying MODX in the desert - http://sottwell.com
                  Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
                  Join the Slack Community - http://modx.org
                  • 22303 MODX Staff
                  • 10,725 Posts
                  The same way that veriword works when generating the captcha codes for the websignup snippet. It is called as an external script directly from an img tag’s src attribute:

                  <img align="top" src="manager/includes/veriword.php?rand=<?php echo rand(); ?>


                  It always returns the same type of image, so the header being set in that standalone script handles only the content type of the jpeg image returned.

                  In the case of this test script in question, it tries to create all the various image types and set the response header appropriately, so you’d either need to run it as an external php script, pick a specific image type, or find a way to set the content type in the $modx->documentObject so you can return the proper content type based on what type of image the script is returning in the response.
                    • 32645
                    • 377 Posts
                    Thank you for your help, I will try your options out today. Thank you once again.
                      • 25662
                      • 7 Posts
                      I needed to address a similar problem where I have a snippet in a page that can return multiple content types. As suggested above, i first tried adding this in my snippet, ($mime contains "image/jpg" or whatever):

                      $modx->documentObject['contentType'] = $mime;


                      However, this alone did not help. A grep of the source indicated that this field is not referenced when the content type header is created. I ended up modifying this code in manager/includes/document.parser.class.inc.php at line 470 (in rev 0.9.6.1p2):

                      $type='';
                      if (!empty($this->documentObject['contentType'])) {
                          $type = $this->documentObject['contentType'];
                      }
                      else {
                          $type = !empty ($this->contentTypes[$this->documentIdentifier]) ? $this->contentTypes[$this->documentIdentifier] : "text/html";
                      }
                      


                      The line of code inside the else is the pre-existing code at line 470.