SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    PHP Guru lampcms.com's Avatar
    Join Date
    Jan 2009
    Posts
    921
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    How do you clone a GD resouce?

    I stubled upon interesting problem.
    I work with a GD resource created by

    $hdlOrig =imagecreatefromjpeg('image.jpg');

    Now I have a GD resource, but I want to make several different images from this resource, so I don't want to work with original resource. Instead I want to clone the resource and then work with a cloned one.

    I am surprised there appears to be no way to just clone a GD resource. Sure, I can just create another resource with imagecopy($orig) but that may degrade the quality.

    Simply assigning the $hdlWork = $hdlOrig will not work because resources are passed by references, so it will just point to the same resource.

    I wonder how other developers handle this.

  2. #2
    SitePoint Mentor silver trophy
    Rubble's Avatar
    Join Date
    Dec 2005
    Location
    Cambridge, England
    Posts
    2,443
    Mentioned
    82 Post(s)
    Tagged
    3 Thread(s)
    Why do you not want to work with the original as it will not be modified ?

    Have you tried using the input image more than once ?

    PHP Code:
    <?php
    // Set the path to the image to resize
    $input_image "yorkshire.jpg";
    // Get the size of the original image into an array
    $size getimagesize$input_image );
    //Medium
    // Set the new width of the image
    $Medium_width "400";
    // Calculate the height of the new image to keep the aspect ratio
    $Medium_height = ( int )(( $Medium_width/$size[0] )*$size[1] );
    // Create a new true color image in the memory
    $Medium ImageCreateTrueColor$Medium_width$Medium_height );
    // Create a new image from file 
    $src_img ImageCreateFromJPEG$input_image );
    // Create the resized image
    ImageCopyResampled$Medium$src_img0000$Medium_width$Medium_height$size[0], $size[1] );
    // Save the image as resized.jpg
    ImageJPEG$Medium"medium.jpg" );
    // Clear the memory of the tempory image 
    ImageDestroy$Medium );
    //Thumbnail
    // Set the new width of the image
    $thumb_width "200";
    // Calculate the height of the new image to keep the aspect ratio
    $thumb_height = ( int )(( $thumb_width/$size[0] )*$size[1] );
    // Create a new true color image in the memory
    $thumbnail ImageCreateTrueColor$thumb_width$thumb_height );
    // Create a new image from file 
    $src_img ImageCreateFromJPEG$input_image );
    // Create the resized image
    ImageCopyResampled$thumbnail$src_img0000$thumb_width$thumb_height$size[0], $size[1] );
    // Save the image as resized.jpg
    ImageJPEG$thumbnail"thumbnail.jpg" );
    // Clear the memory of the tempory image 
    ImageDestroy$thumbnail );
    ?>

  3. #3
    PHP Guru lampcms.com's Avatar
    Join Date
    Jan 2009
    Posts
    921
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Why do you not want to work with the original as it will not be modified ?
    Basically because I write text on top of the image. Let's say I want to create 3 new images from the original. I want to write different text (watermark) on top of the original, then save it as new image. If I write on top of original GD resource image, then I will not be able to reuse it again because it will now contain text.

    So I need an extra step clone(), like
    clone()->writeText('some test')->save('img1.jpg')
    ->clone()->writeText('text 2')->save('img2.jpg')
    ->clone()->writeText('text 3')->save('img3.jpg');

    Here clone() seems to be the most logical and most efficient way to go. I think it's an oversight in design of php GD to not have the clone() method that would just make exact copy of in-memory GD resource.

    I googled about this and found one php script that also needed this method and ended up using the imagecreatetruecolor() and then imagecopy()

  4. #4
    . shoooo... silver trophy logic_earth's Avatar
    Join Date
    Oct 2005
    Location
    CA
    Posts
    9,013
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)
    Logic without the fatal effects.
    All code snippets are licensed under WTFPL.


  5. #5
    PHP Guru lampcms.com's Avatar
    Join Date
    Jan 2009
    Posts
    921
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by logic_earth View Post
    Yes, I thought about it. I tried to use stream wrappers like php://memory and php://temp

    Unfortunately that did not work because even though imagecreatefromgd2() supports stream wrappers as input, the imagegd2 does not support stream wrappers as destination.

    So the only way to do this is to create a temporary file to save gd2 data and then load from that file, then unlink the temp file.
    This works, but probably not very efficient since it involves a disk write, disk read, and deleting of file.

    Again, looks like an oversight in design to allow using stream wrapper for
    imagecreatefromgd2() but not for imagegd2()

  6. #6
    SitePoint Mentor silver trophy
    Rubble's Avatar
    Join Date
    Dec 2005
    Location
    Cambridge, England
    Posts
    2,443
    Mentioned
    82 Post(s)
    Tagged
    3 Thread(s)
    If you want more functions use imagemagick.

    I am afraid I still do not see the problem; I forgot to delete one line out of my example above and here it is again. You read the image into:
    PHP Code:
    $src_img ImageCreateFromJPEG$input_image ); 
    This is used in both image modifications without reading the original in again or effecting it.
    PHP Code:
    <?php
    // Set the path to the image to resize
    $input_image "yorkshire.jpg";
    // Get the size of the original image into an array
    $size getimagesize$input_image );
    //Medium
    // Set the new width of the image
    $Medium_width "400";
    // Calculate the height of the new image to keep the aspect ratio
    $Medium_height = ( int )(( $Medium_width/$size[0] )*$size[1] );
    // Create a new true color image in the memory
    $Medium ImageCreateTrueColor$Medium_width$Medium_height );
    // Create a new image from file 
    $src_img ImageCreateFromJPEG$input_image );
    // Create the resized image
    ImageCopyResampled$Medium$src_img0000$Medium_width$Medium_height$size[0], $size[1] );
    // Save the image as resized.jpg
    ImageJPEG$Medium"medium.jpg" );
    // Clear the memory of the tempory image 
    ImageDestroy$Medium );
    //Thumbnail
    // Set the new width of the image
    $thumb_width "200";
    // Calculate the height of the new image to keep the aspect ratio
    $thumb_height = ( int )(( $thumb_width/$size[0] )*$size[1] );
    // Create a new true color image in the memory
    $thumbnail ImageCreateTrueColor$thumb_width$thumb_height );
    // Create the resized image
    ImageCopyResampled$thumbnail$src_img0000$thumb_width$thumb_height$size[0], $size[1] );
    // Save the image as resized.jpg
    ImageJPEG$thumbnail"thumbnail.jpg" );
    // Clear the memory of the tempory image 
    ImageDestroy$thumbnail );
    ?>

  7. #7
    PHP Guru lampcms.com's Avatar
    Join Date
    Jan 2009
    Posts
    921
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Rubble, your code is only for resizing of image. What if you want to write some text on top of original and then save it, then write different text and save it as another file, then another different text, etc...

    For this you need a way to keep re-creating the gd resource from the original over and over again. The clone() would have been the most efficient way to do this.

    I've been using magickwand from ImageMagic before, I just can't remember if it has the clone(), I have to look into imagick extension, but right now I need to make my script work with GD only.

    Sure, there are several workarounds to clone the gd resource, the best one is probably to save gd resource with imagegd2() then load from file with imagecreatefromgd2()


Bookmarks

Posting Permissions

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