Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 12 of 12
  1. #1
    New to the CF scene
    Join Date
    Sep 2013
    Posts
    4
    Thanks
    5
    Thanked 0 Times in 0 Posts

    Embedding transparent png watermark very slow...Thoughts?

    I have a function that embeds a transparent png onto an image on upload. On the local testing server and a hosting server, we are using php 5.2.17 and GD 2.0.34 with very good results (2-3 seconds per 1.5MB image). On servers running a php version higher than 5.2.17 and GD version 2.1.0, we are experiencing extremely long process/upload times (4-6 minutes per 1.5MB image). On some hosts, the function won't even complete, it just hangs forever. Any thoughts on this would be extremely helpful as I'm out of ideas at this time. Is anyone aware of any bugs in the newer PHP or GD libraries that could cause this? Below is the code to look at.

    Thanks for looking!!!!!

    PHP Code:
            function add_watermark$source_file_path$output_file_path$watermark_file_path$quality 80 ) {
                list( 
    $source_width$source_height$source_type ) = getimagesize$source_file_path );

                if ( 
    $source_type === NULL ) {
                    return 
    false;
                }

                switch ( 
    $source_type ) {
                    case 
    IMAGETYPE_GIF:
                        
    $source_gd_image imagecreatefromgif$source_file_path );
                        break;
                    case 
    IMAGETYPE_JPEG:
                        
    $source_gd_image imagecreatefromjpeg$source_file_path );
                        break;
                    case 
    IMAGETYPE_PNG:
                        
    $source_gd_image imagecreatefrompng$source_file_path );
                        break;
                    default:
                        return 
    false;
                }

                
    $overlay_gd_image imagecreatefrompng$watermark_file_path );
                
    $overlay_width imagesx$overlay_gd_image );
                
    $overlay_height imagesy$overlay_gd_image );

                
    imagecopy(
                    
    $source_gd_image,
                    
    $overlay_gd_image,
                    
    $source_width $overlay_width 10,
                    
    $source_height $overlay_height 10,
                    
    0,
                    
    0,
                    
    $overlay_width,
                    
    $overlay_height
                
    );

                
    imagejpeg$source_gd_image$output_file_path$quality );
                
    imagedestroy$source_gd_image );
                
    imagedestroy$overlay_gd_image );
            } 
            
    Here are the PHP settings used on all servers:

            
    Code:

            
    memory_limit 100M
            upload_max_filesize 
    192M
            post_max_size 
    100M
            file_uploads 
    On
            allow_url_fopen 
    On

        Reply With Quote Reply With Quote 
    Here are the PHP settings used on all servers:

    Code:
    memory_limit = 100M
    upload_max_filesize = 192M
    post_max_size = 100M
    file_uploads = On
    allow_url_fopen = On

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,979
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    First determine if the problem is with the GD or if the problem is with the upload.
    Simply place a file within the server filesystem and operate on it using these functions. If the time is reasonable even with a 1.5MB file, than I'd suggest the issue is surrounding the upload of the file itself. Unfortunately that would probably be more of an issue with the webserver configurations and not that of PHP. All you can do there to verify is log the start and end times of the PHP script. Otherwise, your problem would appear GD related despite looking fine.
    I see nothing in the function itself that should cause delays like you are seeing. You should also grab a copy of the 2.1.0 GD to see if you can replicate the behaviour on a testing environment. If you can, that screams a bug in the GD itself.

    There is a deficiency of course in the ini settings. Upload_max_filesize can never be larger than 100M since both the post and the memory limits are capped at 100MB. But 100MB should be more than plenty for any uploaded image.

    Make sure you check error logs as well, both php and httpd.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • Users who have thanked Fou-Lu for this post:

    roos3342 (09-10-2013)

  • #3
    New to the CF scene
    Join Date
    Sep 2013
    Posts
    4
    Thanks
    5
    Thanked 0 Times in 0 Posts
    Thanks for the thoughts Fou-Lu.

    I have followed your recommendation and determined that the upload is working correctly and the issue appears to be with GD.

    I will get a copy of 2.1.0 and attempt to recreate the issue on a local testing server.

    I have searched the internet high and low looking to see if anyone else has documented this as an issue with this version of GD, but I can not seem to find anyone else documenting this issue.

    Thanks again for the thoughts!

  • #4
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,979
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    I would take each operation and surround them with simple logging for start and end times. Find out which function is the culprit.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • Users who have thanked Fou-Lu for this post:

    roos3342 (09-10-2013)

  • #5
    Senior Coder CFMaBiSmAd's Avatar
    Join Date
    Oct 2006
    Location
    Denver, Colorado USA
    Posts
    2,958
    Thanks
    2
    Thanked 304 Times in 296 Posts
    edit: basically the same as Fou-Lu's reply above -

    You need to further narrow down which of the statements in the posted code is causing the problem. Use microtime(true), before and after each statement, calculating and displaying the time difference, to find out which of the statements is taking longer than expected.

    What is the significance of showing the allow_url_fopen = On setting? Are you reading any of the input files using a URL? If so, there may be a contention problem and you are waiting for a response from a server that isn't happening.
    If you are learning PHP, developing PHP code, or debugging PHP code, do yourself a favor and check your web server log for errors and/or turn on full PHP error reporting in php.ini or in a .htaccess file to get PHP to help you.

  • Users who have thanked CFMaBiSmAd for this post:

    roos3342 (09-10-2013)

  • #6
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,979
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    Quote Originally Posted by CFMaBiSmAd View Post
    What is the significance of showing the allow_url_fopen = On setting? Are you reading any of the input files using a URL? If so, there may be a contention problem and you are waiting for a response from a server that isn't happening.
    I was thinking of this exact thing as well. I'm curious if there is a remote image being included (such as the watermark?) which could be dragging it down.

    Edit:
    In particular, right here: $overlay_gd_image = imagecreatefrompng( $watermark_file_path );. I'm curious if this function call is the cause of the slowness.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • Users who have thanked Fou-Lu for this post:

    roos3342 (09-10-2013)

  • #7
    New to the CF scene
    Join Date
    Sep 2013
    Posts
    4
    Thanks
    5
    Thanked 0 Times in 0 Posts
    Thanks again.

    The Image is being read from a URL. The image can be uploaded by the user to be used within the plugin.

    I will take your recommendations as to the microtime(true) and do some testing to see what I can come up with.

    I am currently getting my server setup with the versions of php and GD that are on the host and trying to replicate the problem as well.

    You got me thinking that the call to the watermark image could be the problem here. It's strange that it works on older versions of PHP and GD tho. I'm wondering if there was a change somewhere in the newer ones that is causing this.

    Thanks!

  • #8
    Senior Coder
    Join Date
    Sep 2010
    Posts
    1,899
    Thanks
    15
    Thanked 226 Times in 226 Posts
    Quote Originally Posted by roos3342 View Post
    I have a function that embeds a transparent png onto an image on upload. On the local testing server and a hosting server, we are using php 5.2.17 and GD 2.0.34 with very good results (2-3 seconds per 1.5MB image). On servers running a php version higher than 5.2.17 and GD version 2.1.0, we are experiencing extremely long process/upload times (4-6 minutes per 1.5MB image). On some hosts, the function won't even complete, it just hangs forever. Any thoughts on this would be extremely helpful as I'm out of ideas at this time. Is anyone aware of any bugs in the newer PHP or GD libraries that could cause this? Below is the code to look at.

    Thanks for looking!!!!!
    Please to explain exactly what you are doing. Are you modifying the image to include a watermark, or just overlaying it with an image with a watermark. There are much more efficient ways of overlaying a watermark image. And G-D isn't the only game in town, you have Imagemagick, you can also make a library of images to be used for watermarking purposes, by the overlay method or by composing them with the uploaded image. There is also .svg, which can be used with the overlay method to make a convincing watermark, and to prevent clicking the images. Canvas can be used too, you can download the image by right clicking with some browsers, but it will retain the watermark.
    Welcome to http://www.myphotowizard.net

    where you can edit images, make a photo calendar, add text to images, and do much more.


    When you know what you're doing it's called Engineering, when you don't know, it's called Research and Development. And you can always charge more for Research and Development.

  • Users who have thanked DrDOS for this post:

    roos3342 (09-10-2013)

  • #9
    New to the CF scene
    Join Date
    Sep 2013
    Posts
    4
    Thanks
    5
    Thanked 0 Times in 0 Posts
    Dr. Dos,

    The main goal is to add a watermark to an image that is uploaded. This is being used in a plugin being developed for wordpress and more specifically a woocommerce extension that will upload photos and automatically create products and variations with the photos.

    The goal is to upload the images and create watermarked images for anything that will be for "public" viewing. There is a default watermark that can be used, or the user can upload their own png file for a watermark. The way the plugin is working now is it's overlaying the watermark, then creating various sized images with the watermark embedded which are then served as images. If someone would right click and download the image currently, they watermark will be intact since it is now a part of the image.

    With the automatic product creation, a downloadable product can be created. This product will not have the watermark added to it and it is created in a separate secure folder that purchasers will get a download link to access the specific pictures they purchase for download.

    We have looked at using ImageMagick, or more specifically Imagick php module, but what we found is many hosting environments do not have this installed. More have the GD library installed and bundled with the PHP versions they have. We have not completely ruled out ImageMagick yet. I will have a look at some of the others you have mentioned and see how we can maybe use them as opposed to GD.

    I hope I have given a more clear idea of what this is trying to accomplish, if not, let me know so I can expand on this more!

  • #10
    Senior Coder
    Join Date
    Sep 2010
    Posts
    1,899
    Thanks
    15
    Thanked 226 Times in 226 Posts
    I do not see where this comes from.

    IMAGETYPE_GIF, etc.

    My version of getimagesize returns image/gif , etc. which seems to be what the case should be in the switch statement.
    PHP Code:
    $s getimagesize$source_file_path )
    $source_width $s[0];
    $source_height $s[1];
    $source_type $s['mime'];
    Or 
    maybe $source_type = ${$s['mime']}; 
    $source_type will be image/gif. Or maybe you're using predefined stuff.
    Last edited by DrDOS; 09-10-2013 at 07:06 PM.
    Welcome to http://www.myphotowizard.net

    where you can edit images, make a photo calendar, add text to images, and do much more.


    When you know what you're doing it's called Engineering, when you don't know, it's called Research and Development. And you can always charge more for Research and Development.

  • #11
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,979
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    Imagemagick is an option of course; PHP wise you'd need the PECL otherwise you'll need the external imagemagick and offloaded calls. I don't recommend using external if it can be avoided though.
    The $source_type is likely the result of the getimagesize index 2. The 'mime' is the textual representation of such. Using the constants is better in a switch since a change in a constant's value won't change the functionality of the code, just the underlying data. It's preferable to use the constant or a variable, but avoid the hardcoded values when possible (no 1 or "image/gif" for example, but either IMAGETYPE_GIF or $variable with an assigned string of the "image/gif" or even better the result of the image_type_to_mime_type).

    You should check out the sapi mode for each as well. One may be a module and the other a fcgi build. Especially if the watermark comes from the local machine and is accessed using the http protocol instead of the file protocol.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • #12
    Senior Coder
    Join Date
    Sep 2010
    Posts
    1,899
    Thanks
    15
    Thanked 226 Times in 226 Posts
    To use Imagemagic to the fullest you really do need the CL, as Fou-lu has said. I find it's coding to me simpler and more direct, as well as more flexible than G-D.

    Now check this out, I've just been testing it.
    PHP Code:
    <!DOCTYPE html>
    <
    html>
    <
    head>
    <
    meta content="text/html; charset=utf-8" http-equiv="content-type">
        <
    title></title>
    <
    style type="text/css">
    body
    {
    margin:0 auto;
    font-size:24px;
    }
    #theimg, #mysvg
    {
    left:0;top:0;
    position:absolute;
    }
    </
    style>
    </
    head>
    <
    body>
    <
    div id="bkg">
    <
    img id="theimg" src="37966-2560x1600.jpg" />
    <
    svg id="mysvg" xml="http://www.w3.org/2000/svg" version="1.1"
    width="1000"
    height="1000"
    style="background-color: transparent;z-index:20;">
    <
    text id="txt" x="600" y="0" stroke="black"  fill="aqua" 
    transform="rotate(30, 0, 0)">This is a watermark.</text>
    </
    svg>
    </
    div>
    <
    script type="text/javascript">
    im=document.getElementById("theimg");
    im.onload=function()
    {
    =document.getElementById("mysvg");
    =document.getElementById("txt");
    m.setAttribute("width",im.offsetWidth);
    m.setAttribute("height",im.offsetHeight);
    t.setAttribute("x",im.offsetWidth/3);
    m.style.fontSize = (im.offsetWidth/20)+"px";
    m.style.fontFamily "Georgia";
    }
    </script>
    </body>
    </html> 
    The rotate angle, 30deg, should be the diagonal of the image.

    It lets you put a 'phony watermark' over an image, which would probably prevent most people from trying to copy it. It also prevents it from being copied by right click on newer browsers. It won't work on IE 8.

    However, and this may be important, it isn't necessary to have a transparent png to watermark an image, you only need the relevant data to put text on the image. And you can use this to help people set up the data, then upload it to a form, and keep the data in a file or DB. This may be faster and more efficient than using a png.
    Welcome to http://www.myphotowizard.net

    where you can edit images, make a photo calendar, add text to images, and do much more.


    When you know what you're doing it's called Engineering, when you don't know, it's called Research and Development. And you can always charge more for Research and Development.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •