GD library: imagecopyresampled() creating black images...

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
lostInSpace
Forum Newbie
Posts: 3
Joined: Thu Oct 02, 2008 5:04 am

GD library: imagecopyresampled() creating black images...

Post by lostInSpace »

Hey all,

I'm trying to use the GD library to create thumbnails of images being uploaded...I can get the script to work BUT, the thumbnails turn out all black...

Here's the code:

Code: Select all

 
        private function createthumb($name,$filename,$new_w,$new_h)
        {
            $system=explode(".",$name);
            if (preg_match("/jpg|jpeg/",$system[1])){$src_img=imagecreatefromjpeg($name);}
            if (preg_match("/png/",$system[1])){$src_img=imagecreatefrompng($name);}
            $old_x=imageSX($src_img);
            $old_y=imageSY($src_img);
            if ($old_x > $old_y) 
            {
                $thumb_w=$new_w;
                $thumb_h=$old_y*($new_h/$old_x);
            }
            if ($old_x < $old_y) 
            {
                $thumb_w=$old_x*($new_w/$old_y);
                $thumb_h=$new_h;
            }
            if ($old_x == $old_y) 
            {
                $thumb_w=$new_w;
                $thumb_h=$new_h;
            }
            $dst_img=ImageCreateTrueColor($thumb_w,$thumb_h);
            
            imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y); 
            if (preg_match("/png/",$system[1]))
            {
                imagepng($dst_img,$filename); 
            } else {
                imagejpeg($dst_img,$filename); 
            }
            
            imagedestroy($dst_img); 
            imagedestroy($src_img); 
        }
 
My server is running GD version: bundled (2.0.34 compatible). Anyone had this problemo? Thanks!
User avatar
panic!
Forum Regular
Posts: 516
Joined: Mon Jul 31, 2006 7:59 am
Location: Brighton, UK

Re: GD library: imagecopyresampled() creating black images...

Post by panic! »

Might not be helpful, this this class below could do what you're trying to do quite easily

Code: Select all

  
$image=new image('something.jpg'); 
$image->resize('100','100');
$image->save('somewhere.jpg','jpg');   
 
 
new image() // you can either use a filename or a $_FILE['something'] array from an upload, you'll need to make a 'tmp' directory with write permissions for this upload thing tho
resize(h,w) // height and width, if you don't specify one of them it will work the other out proportionally, you can also use percentages.
output(location,type) //

Code: Select all

 
 
<?
class imagetype
{
    public $createfunction;
    public $outputfunction;
    public $contenttype;
    function __construct($create,$output,$contenttype)
    {
        $this->createfunction=$create;
        $this->outputfunction=$output;
        $this->contenttype=$contenttype;
    }
 
 
}
 
class image
{
    public $path;
    public $type;
 
    public $resource;
    private $types;
    
    public $height;
    public $width;
 
    function __construct($image)
    {
        global  $application;
        
        $this->types['jpg']=new imagetype('imagecreatefromjpeg','imagejpeg','image/jpeg');
        $this->types['gif']=new imagetype('imagecreatefromgif','imagegif','image/gif');
        $this->types['png']=new imagetype('imagecreatefrompng','imagepng','image/png');
 
    
 
        if(is_array($image) && array_key_exists('tmp_name',$image))
        {
            
            
            
            move_uploaded_file($image['tmp_name'],'tmp/.$image['name']);
            
            $this->path='tmp/'.$image['name'];
            
        }   
            else
        {
        
            if(is_numeric($image))
            {
                $resource=new _resource($image);    
                if(!$resource)
                {
                    return false;
                }
                $this->path='images/library/'.md5($resource->id).'/'.$resource->filename;   
            }
            else
            {
                $this->path=$image;
                if(!file_exists($this->path))
                {
                    trigger_error('file '.$this->path.' not found');
                    return false;
                }
            }
        }
    
        $fileextension=explode('.',$this->path);
 
    
        
        $this->type=$fileextension[count($fileextension)-1];
        
        if($this->type=='jpeg')
        {
            $this->type='jpg';
        }
        
 
        
        if(!$this->types[$this->type])
        {   
            trigger_error('The image type '.$this->type.' is not supported');
            return false;
        }
        
        eval("\$this->resource= &".$this->types[$this->type]->createfunction."('".$this->path."');");
        
        $this->refreshattributes();
        
        }
 
 
    function resize($width=0,$height=0)
    {
        
        if(stristr($width,'%'))
        {
            $widthpercent=true;
            $width=str_replace('%','',$width);
        }
        
        if(stristr($height,'%'))
        {
            $heightpercent=true;
            $height=str_replace('%','',$height);
        }
        
        
    
        if(!($width && $height))
        {
            if(!$height)
            {
                $proportion=$this->height/$this->width;
                $height=$width*$proportion;
                
                if(@$widthpercent)
                {
                $heightpercent=true;
                $height=$width;
                }
            }
            else
            {
                $proportion=$this->width/$this->height;
                $width=$height*$proportion;
                
                if(@$heightpercent)
                {
                $widthpercent=true;
                $width=$height;
                }
                
            }
        
        }
    
    
        if(@$heightpercent) $height=$this->height*($height/100);
    
        
        if(@$widthpercent) $width=$this->width*($width/100);
    
        
        $temp = imagecreatetruecolor($width, $height);
        
        imagecopyresampled($temp, $this->resource, 0, 0, 0, 0, $width, $height, $this->width, $this->height);
 
        
        $this->resource=$temp;
        
        $this->refreshattributes();
    
    }
    
    function refreshattributes()
    {
        $this->height=imagesy($this->resource);
        $this->width=imagesx($this->resource);
    
    
    }
    
    
    function crop($x,$y,$width,$height)
    {
    
        $temp = imagecreatetruecolor($width, $height);
        imagecopyresampled($temp, $this->resource, 0, 0, $x, $y, $width, $height, $width, $height);
        $this->resource=$temp;
 
        $this->refreshattributes();
        
        
    }
    
    function save($filename=null,$type=null)
    {
    
        if(!$filename)
        {
            $filename=$this->path;
        }
                
        
        $this->output($type,$filename);
        
    }
        
    
    function output($type=null,$file=null)
    {
    
    
        if(!$type)
        {
            $type=$this->type;
        }
            
        $output=$this->types[$type];
        
        if(!$output)
        {
            trigger_error('The image type '.$type.' is not supported');
            return false;
        
        }
    
 
        
         
        if(!$file)
        {
            
            header("Content-type: ".$output->contenttype);
            eval($output->outputfunction."(\$this->resource);");
        }else{
        
            eval($output->outputfunction."(\$this->resource,'$file');");
        }
    
        
    }
}
 
?>
 
?>
 
lostInSpace
Forum Newbie
Posts: 3
Joined: Thu Oct 02, 2008 5:04 am

Re: GD library: imagecopyresampled() creating black images...

Post by lostInSpace »

So further testing this script, it seems to be some sort of permissions problem or relative path deal, but I can't get around this:

When I run a test script from directly within the web root directory the function works correctly: using the gd library it correctly writes the appropriate thumbnail image without errors. Testing from the web root directory, I'm using the relative paths like so:

Code: Select all

 
// create thumbnail
    $imagePath = 'images/banners/abstract_blue.jpg';
    $thumbPath = 'images/banners/thumbs/thm_abstract_blue.jpg';
   
    createthumb($imagePath, $thumbPath , 50, 50);
    chmod($thumbPath, 0755);
 
..and so on...

When I run the same script in a directory immediately below the web root directory (which is where I need to run it from), relative path or not, I get errors, either the thumbnail images come out all black, or no thumbnail images is created.

I can't figure this out...any ideas?
lostInSpace
Forum Newbie
Posts: 3
Joined: Thu Oct 02, 2008 5:04 am

Re: GD library: imagecopyresampled() creating black images...

Post by lostInSpace »

Right, so in my original post, the lines below checked the system file path to get the type of image file:

Code: Select all

 
$system=explode(".",$name);
if (preg_match("/jpg|jpeg/",$system[1])){$src_img=imagecreatefromjpeg($name);}
 
...but because the full path had a '.com' in it (just the way the provider handles it, not my choice), it broke the code...I rewrote this to get around the issue by using:

Code: Select all

 
$info = getImageSize($fileFullPath);
 
then using the third element of the array returned, which gives you the image type, like so:

Code: Select all

 
    switch ($info[2]) {
        case IMAGETYPE_GIF:
            $infunc = 'ImageCreateFromGif';
            $outfunc = 'ImageGif';
            break;
 
        case IMAGETYPE_JPEG:
            $infunc = 'ImageCreateFromJpeg';
            $outfunc = 'ImageJpeg';
            break;
 
        case IMAGETYPE_PNG:
            $infunc = 'ImageCreateFromPng';
            $outfunc = 'ImagePng';
            break;
 
        default;
            throw new Exception('Invalid image type');
    }
 
and got it to work, anyone interested can let me know...
DNoe
Forum Newbie
Posts: 1
Joined: Fri Nov 07, 2008 2:57 pm

Re: GD library: imagecopyresampled() creating black images...

Post by DNoe »

You could have just done this instead:

Code: Select all

 
$system=explode(".",$name);
if (preg_match("/jpg|jpeg/",$system[[color=#BF0000]count($system) - 1[/color]])) $src_img=imagecreatefromjpeg($name);
 
However, I am still not sure how that relates to the black image problem. (I am getting all black thumbnails also)...
mickyh
Forum Newbie
Posts: 2
Joined: Wed Dec 03, 2008 12:57 pm

Re: GD library: imagecopyresampled() creating black images...

Post by mickyh »

I am getting the same issue with a GD 2.2.1 createthumb() function below.

This is because the function cannot get the path to the source image ($name) and so uses the imagecreatetruecolor(w,h) blank image identifier instead, I think.

However, I don't have a solution, sorry. It seems that the function works fine if the source image is in the same directory as the script. Move the source image and no amount of path tweaking, relative, absolute or doc root gets it to work!

Can anyone else help with this please.

Code: Select all

function createthumb($name,$filename,$new_w,$new_h) {
    $sys = explode(".",$name);
    
    // Get the size of the original image into an array
    $size = getimagesize( $name );
    
    // Set the new width of the image
    $thumb_w = $new_w;
    
    // Calculate the height of the new image to keep the aspect ratio
    $thumb_h = ( int )(( $thumb_w/$size[0] )*$size[1] );
    
    // Create a new true color image in the memory
    $dst_img = imagecreatetruecolor( $thumb_w, $thumb_h );
    
    // Create a new image from file 
    if (preg_match("/jpg|jpeg/i",$sys[1])) { $src_img = imagecreatefromjpeg($name); }
    if (preg_match("/png/i",$sys[1]))      { $src_img = imagecreatefrompng($name); }
    if (preg_match("/gif/i",$sys[1]))      { $src_img = imagecreatefromgif($name); }
    
    // Create the resized image
    imagecopyresampled( $dst_img, $src_img, 0,0,0,0, $thumb_w, $thumb_h, $size[0], $size[1] );
    
    // Save the image
    if (preg_match("/png/i",$sys[1]))
    {
        imagepng($dst_img,$filename,3); 
    } 
    elseif (preg_match("/gif/i",$sys[1]))
    {
        imagegif($dst_img,$filename); 
    } 
    else {
        imagejpeg($dst_img,$filename,85); 
    }
    
    // Clear the memory of the temporary image 
    imagedestroy($dst_img);
    imagedestroy($src_img);  
}
 
mickyh
Forum Newbie
Posts: 2
Joined: Wed Dec 03, 2008 12:57 pm

Re: GD library: imagecopyresampled() creating black images...

Post by mickyh »

Just thought I'd post my solution.

The black thumbs were due to the explode(".",$name) function - my paths contained more than one dot! Here was my solution:

Code: Select all

function createthumb($name,$filename,$new_w,$new_h) {
    // Parse $name to get extension
    $sys = explode(".",$name);
    $sys_size = sizeof($sys);
    
    // Get the size of the original image into an array
    $size = getimagesize( $name );
    
    // Set the new width of the image
    $thumb_w = $new_w;
    
    // Calculate the height of the new image to keep the aspect ratio
    $thumb_h = ( int )(( $thumb_w/$size[0] )*$size[1] );
    
    // Create a new true color image in the memory
    $dst_img = imagecreatetruecolor( $thumb_w, $thumb_h );
    
    // Create a new image from file 
    if (preg_match("/jpg|jpeg/i",$sys[$sys_size-1])) { $src_img = imagecreatefromjpeg($name); }
    if (preg_match("/png/i",$sys[$sys_size-1]))      { $src_img = imagecreatefrompng($name); }
    if (preg_match("/gif/i",$sys[$sys_size-1]))      { $src_img = imagecreatefromgif($name); }
    
    // Create the resized image
    imagecopyresampled( $dst_img, $src_img, 0,0,0,0, $thumb_w, $thumb_h, $size[0], $size[1] );
    
    // Save the image
    if (preg_match("/png/i",$sys[$sys_size-1]))
    {
        imagepng($dst_img,$filename,3); 
    } 
    elseif (preg_match("/gif/i",$sys[$sys_size-1]))
    {
        imagegif($dst_img,$filename); 
    } 
    else {
        imagejpeg($dst_img,$filename,85); 
    }
    
    // Clear the memory of the temporary image 
    imagedestroy($dst_img);
    imagedestroy($src_img);  
}
This function accepts the original path/filename - $name, the path/name of the new thumb - $filename and new width and height - although I don't think it needs the height as it works this out proportionally from the width.

Hope this helps.
tbrown944
Forum Newbie
Posts: 1
Joined: Wed Mar 04, 2009 3:02 pm

Re: GD library: imagecopyresampled() creating black images...

Post by tbrown944 »

Don't know if mickyh's solution fixed everyone's problems, but I too am having problems with black images using GD 2. Some images process fine, some do not.

After much testing I realized that any input image less than 96 dpi (all my digital camera photo's are 72 dpi) produces a black output image. 96 dpi and higher work OK. The output images that GD 2 makes are 96 dpi. Coincidence? I think not.

The original version of GD had default output of 72 dpi.

I am afraid I don't have a solution (nor will I likely find one I think) and can't find anything on the web. I would have thought if it was a GD 2 bug then there would be lots of opinion out there. I'm just posting this message to maybe save some other folks from a lot of head scratching.

Shame, I thought PHP and GD 2 was a good route to the automated web based photo gallery I was coding. Back to the drawing board I guess.....
Post Reply