1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Fixed XenForo_Image_Gd PNG transparency

Discussion in 'Resolved Bug Reports' started by Ralle, Nov 19, 2013.

  1. Ralle

    Ralle Active Member

    I was using the Addon called Custom Node Icon. I was not very happy with the fact that when I uploaded a PNG, the transparency disappeared. Turns out that this is an issue with XenForo, not Custom Node Icon. Well, I suppose they could have rewritten XenForo_Image_Gd, but the whole point of XenForo is that we can all re-use what you guys have created for us. The Addon takes an image you upload, maybe resizes it and outputs it into a folder, but most of the time it does not process the image at all, it merely loads it in and saves it back to disk. This process should not cause any significant data loss I think. But it does, the transparency of PNG files (and possibly other formats too, GIF?) disappears. I found on StackOverflow that you have to add a few lines of code to make sure that transparency is kept. Here is my modified output function for XenForo_Image_Gd:
    PHP:
        public function output($outputType$outputFile null$quality 85)
        {
            switch (
    $outputType)
            {
                case 
    IMAGETYPE_GIF$success imagegif($this->_image$outputFile); break;
                case 
    IMAGETYPE_JPEG$success imagejpeg($this->_image$outputFile$quality); break;
                case 
    IMAGETYPE_PNG:
                    
    // Ralle: hack to save transparency
                    
    $background imagecolorallocate($this->_image000);
                    
    imagecolortransparent($this->_image$background);
                    
    imagealphablending($this->_imagefalse);
                    
    imagesavealpha($this->_imagetrue);
                    
    // Ralle end

                    // "quality" seems to be misleading, always force 9
                    
    $success imagepng($this->_image$outputFile9PNG_ALL_FILTERS);
                    break;

                default:
                    throw new 
    XenForo_Exception('Invalid output type given. Expects IMAGETYPE_XXX constant.');
            }

            return 
    $success;
        }
    I read somewhere that this was a feature because you want people to use real life pictures as your profile picture. But if the image class has to be useful for Addons too, this quickly becomes a flaw.
    I hope you will consider adding this to the XenForo codebase.

    Thank you.
     
  2. digitalpoint

    digitalpoint Well-Known Member

    I have an addon that resizes PNG images (using XenForo's normal function with GD), and it preserves the transparency just fine. Maybe it's something to do with the version of PHP (maybe GD was improved in the newer versions?). I'm using PHP 5.5.6.
     
    Adam Howard likes this.
  3. Ralle

    Ralle Active Member

    Would it be too much to ask you to show us the code that processes the image?
     
  4. digitalpoint

    digitalpoint Well-Known Member

    Nothing fancy really...

    PHP:
    $image XenForo_Image_Abstract::createFromFile($filenameIMAGETYPE_PNG);
    $image->thumbnail(128);
    $image->output(IMAGETYPE_PNG);
     
  5. Mike

    Mike XenForo Developer Staff Member

    Transparency seems to be maintained for me in PHP 5.3 and 5.4 as well.

    Can you provide a simplified test case with your code that reproduces the issue? (Please include the image that reproduces it, as that may be relevant.)
     
  6. Ralle

    Ralle Active Member

    I will upload a test case at another time. I believe the bug would appear when digitalpoint removes line 2 from his code, but I have not tested it in this exact case. The bug in my addon appears when it does not have to transform the image in any way.
    I am running PHP version 5.4.17.

    Edit: I just looked at the source again. The code I added to the Gd.php file is run when you call the thumbnail function, but not if you don't.
     
  7. digitalpoint

    digitalpoint Well-Known Member

    Just out of curiosity, why would you want to load it into the Image class and output it when you aren't manipulating the image in any way? Wouldn't it make more sense to just use the original image?
     
    Adam Howard likes this.
  8. Ralle

    Ralle Active Member

    Agreed, it is stupid. But the code should not change the image in any significant way. But it removes the transparency, which I consider a fault in the library. The code that preserves the transparency should be moved from the thumbnail function to somewhere else so it is called even if no thumbnail is created.
    Anyway, this addon I was talking about checks if the image has the exact size of the node icons. If not, it resizes them, but I was uploading the correct size every time which resulted in the addon not having to modify the image.
     
  9. Mike

    Mike XenForo Developer Staff Member

    I can't reproduce it without transforms either. Please include the test case and an example image. It'd also be worth seeing the details about your GD install from PHP info.
     
  10. Ralle

    Ralle Active Member

    I finally found time to reproduce this and make a simple test.

    I am running on a Mac running OS X Mavericks using the built-in PHP, Apache and have installed MySQL myself. So far it has worked fine.

    Here is my phpinfo():
    https://dl.dropboxusercontent.com/u/323865/2013-12-05 phpinfo for xenforo.html

    Here is the image I was testing with, I zipped it so service will convert it and skew the results:
    https://dl.dropboxusercontent.com/u/323865/2013-12-05 test image for xenforo.zip

    Here is my test script:
    PHP:
    <?php

    $startTime 
    microtime(true);
    $fileDir dirname(__FILE__);

    require(
    $fileDir '/library/XenForo/Autoloader.php');
    XenForo_Autoloader::getInstance()->setupAutoloader($fileDir '/library');

    XenForo_Application::initialize($fileDir '/library'$fileDir);
    XenForo_Application::set('page_start_time'$startTime);

    $filename 'test.png';
    $filename2 'test2.png';

    $image XenForo_Image_Abstract::createFromFile($filenameIMAGETYPE_PNG);
    // $image->thumbnail(30);
    $image->output(IMAGETYPE_PNG$filename2);
    It works fine if I uncomment the thumbnail() call (and the image is bigger than the size).

    Otherwise this is what:
    https://dl.dropboxusercontent.com/u/323865/2013-12-05 result image for xenforo.zip

    Which has no transparency.
     
  11. Mike

    Mike XenForo Developer Staff Member

    This appears to be image specific, though I haven't delved into the specific conditions. I was able to reproduce with the given image, but not with the XF smilies sprite, for example.

    But disabling alpha blending and saving the alpha channel is what's needed for PNGs.
     
  12. Ralle

    Ralle Active Member

    Does Fixed mean that you are planning on releasing a fix or that you don't consider it a bug?
     
  13. Brogan

    Brogan XenForo Moderator Staff Member

    It means it is fixed and will be in the next release.
     
  14. Ralle

    Ralle Active Member

    Awesome. Thank you for clearing this up.
     

Share This Page