We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 17855
    • 43 Posts
    hello -

    I've been trying to return an image straight to the browser. The idea is to return a PNG when the URL is called, e.g domain.com/image

    I've borrowed some code from the web and whereas outside of MODx the following works, as a snippet it doesn't return anything. I just see a small image log in the browser.

    It seems you cant return $image or write to the browser imagepng($image); with or without ob_start();. It must be Revo's parsing process getting involved but I'm not smart enough to figure it out.

    I've setup my test site with a PNG content type for the url (eg. domain.com/image).

    I'm sure I could return an image referenced within an <img> but I want to be able to pull the image in to other sites as an image.

    I've also tried https://forums.modx.com/index.php?topic=67177.0 but with no luck.

    Any ideas appreciated

    <?php
    // PHP placeholder images
    // Version: 0.1
    // Author: Hinerangi Courtenay - @sky_maiden
    
    // Usage (all parameters are optional):
    // <img src="placeholder.php?size=400x150&bg=eee&fg=999&text=Generated+image" alt="Placeholder image" />
    
    // Inspired by http://placehold.it/
    
    
    // Dimensions
    $getsize    = isset($_GET['size']) ? $_GET['size'] : '100x100';
    $dimensions = explode('x', $getsize);
    
    // Create image
    $image      = imagecreate($dimensions[0], $dimensions[1]);
    
    // Colours
    $bg         = isset($_GET['bg']) ? $_GET['bg'] : 'ccc';
    $bg         = hex2rgb($bg);
    $setbg      = imagecolorallocate($image, $bg['r'], $bg['g'], $bg['b']);
    
    $fg         = isset($_GET['fg']) ? $_GET['fg'] : '555';
    $fg         = hex2rgb($fg); 
    $setfg      = imagecolorallocate($image, $fg['r'], $fg['g'], $fg['b']);
    
    // Text
     $text       = isset($_GET['text']) ? strip_tags($_GET['text']) : $getsize;
     $text       = str_replace('+', ' ', $text);
    
    // Text positioning
    $fontsize   = 4;
    $fontwidth  = imagefontwidth($fontsize);    // width of a character
    $fontheight = imagefontheight($fontsize);   // height of a character
    $length     = strlen($text);                // number of characters
    $textwidth  = $length * $fontwidth;         // text width
    $xpos       = (imagesx($image) - $textwidth) / 2;
    $ypos       = (imagesy($image) - $fontheight) / 2;
    
    //imagealphablending($image, true); // setting alpha blending on
    //imagesavealpha($image, true); // save alphablending setting 
    
    
    // Generate text
    imagestring($image, $fontsize, $xpos, $ypos, $text, $setfg);
    
    // Render image
    ob_start();
    imagepng($image);
    $output = ob_get_contents();
    ob_end_clean();
    
    return $output;
    
    
    // Convert hex to rgb (modified from csstricks.com)
    function hex2rgb($colour)
    {
        $colour = preg_replace("/[^abcdef0-9]/i", "", $colour);
        if (strlen($colour) == 6)
        {
            list($r, $g, $b) = str_split($colour, 2);
            return Array("r" => hexdec($r), "g" => hexdec($g), "b" => hexdec($b));
        }
        elseif (strlen($colour) == 3)
        {
            list($r, $g, $b) = array($colour[0] . $colour[0], $colour[1] . $colour[1], $colour[2] . $colour[2]);
            return Array("r" => hexdec($r), "g" => hexdec($g), "b" => hexdec($b));    
        }
        return false;
    }
    
    ?>
      • 3749
      • 24,544 Posts
      Without an img tag, I don't think the browser knows what to do with an image. You can, however, have your script return the image and specify the script in the src attribute of the img tag. This is how the MODX Captcha extra works. The image is generated by the script.
      <img src="[[++assets_url]]components/captcha/captcha.php" alt="Captcha Image" />

      See the code in the core/components/captcha/captcha.plugin.php file.
        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
        • 10208 ☆ A M B ☆
        • 1,780 Posts
        Last time I did this, I set the resource to the content type .jpg, resource to static resource, and applied the image file to the source.

        You'll have to add .jpg to the content types first though.

        Name: JPG
        MIME Type: application/jpg
        File Extension: .jpg
        Binary: yes
        Desc: JPG Content Type

        Do the same as above for PDF content type, which also can be served as a resource that makes for much easier linking and file updating throughout the site.


          Frogabog- MODX Websites in Portland Oregon
          "Do yourself a favor and get a copy of "MODX - The Official Guide" by Bob Ray. Read it.
          Having server issues? These guys have MODX Hosting perfected - SkyToaster
          • 17855
          • 43 Posts
          Thanks BobRay + Frogabog

          @BobRay: I think it is possible, it's just finding my route with MODx as I can do it outside of MODx

          @Frogabog: Thanks, I've double checked my settings and still can't get it to work. What do you mean by:

          and applied the image file to the source.

          If you've got 2 mins to give me a step by step I'll try and reproduce.

          I've also tried using phpthumbof and also tried the following with an existing image:

              header('Content-Description: File Transfer');
              header('Content-Type: image/jpeg');
              header('Content-Transfer-Encoding: binary');
              header('Expires: 0');
              header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
              header('Pragma: public');
              header('Content-Length: '.filesize('cat-small.d054b748c4c9c82abc105fcc94d051791.jpg'));
              readfile('cat-small.d054b748c4c9c82abc105fcc94d051791.jpg');
              ob_end_flush


          This works outside of MODx but not as a snippet.

          Two headers for comparison attached.

          I'm a bit stuck. Have tried magicImage snippet, but cant get that to work either. phpthumbof works though, so all seems good with GD etc

          https://forums.modx.com/index.php?topic=67177.0
            • 17855
            • 43 Posts
            I've moved this on, using the following code in a snippet:

                header('Content-Description: File Transfer');
                header('Content-Type: image/png');
                header('Content-Transfer-Encoding: binary');
                header('Expires: 0');
                header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
                header('Pragma: public');
                
                $image = imagecreate (150, 120);
                $background = ImageColorAllocate ($image, 00, 00, 00);
                $white = ImageColorAllocate ($image, 255, 255, 255);
                ImageTTFText ($image, 18, 0, 0, 16, $white, "assets/fonts/arial.ttf", "this");
                ImagePNG($image);
                die();


            It doesn't work if you chance the content type in the manager, I think the rendering process then ignores the snippet even in a blank template. Still this test works, so I will try and improve on this.
              • 9102 ☆ A M B ☆
              • 318 Posts
              Looks like you are doing what I would have suggested, which is putting a die() statement after sending the headers and image. I found, as you did, that the code doesn't work inside MODX without the die() call at the end - apparently the MODX process keeps running and doesn't actually return the image to the browser for some reason. I never did find out why and I'm sure there's a better way to do it, but this worked for me and still works in 2.2.12.
                • 10208 ☆ A M B ☆
                • 1,780 Posts
                What I meant was make a static resource, with a content type of .jpg. (create the content type first). The static resource file would be your image.jpg file (static resource file source).

                This is really as simple as you see above. All you want to do is have a resource display an image, right? If so, it most certainly does not need to be convoluted.

                  Frogabog- MODX Websites in Portland Oregon
                  "Do yourself a favor and get a copy of "MODX - The Official Guide" by Bob Ray. Read it.
                  Having server issues? These guys have MODX Hosting perfected - SkyToaster
                  • 17855
                  • 43 Posts
                  Thanks @freejung - I think I've got it sorted now and thanks for taking the time to look at my PM. die() seems like the answer!

                  @frogabog - thanks for the overview, I'm now using the code above and all works