Dynadot โ€” .com Registration $8.99

Phase 2: Resizing Images on Server

Spaceship Spaceship
Watch
Impact
111
Hey all,

Thanks for the great help with the uploading; I've just gone and revised *everything*. So now, they upload. Yay.

AND they resize, too! :tu:

...but they're black boxes.

Here's my code:

PHP:
// Resample
		$image_resized = imagecreatetruecolor($new_width, $new_height);
		$image = imagecreatefromjpeg($uploadfile2);
		if ($image === false) { die ('Unable to open image'); }
		if (!imagecopyresampled($image_resized, $image, 0, 0, 0, 0, $new_width, $new_height, $imgsize[0], $imgsize[1]))
		{
			die("Error");
		}
		else
		{
			imagejpeg($image_resized, $uploadfile2, 100);
		}

Now, I know it has something to do with imagecreatetruecolor because PHP.net says it makes a black image with those dimensions, then you "draw" over it (I assume) by doing imagecreatefromjpeg after that, then resample with the imagecopyresampled function at the end.

These come more directly from PHP.net than my last code snippets; so it's more accurate... yet I still get black boxes once resized.

ANY help appreciated. I promise. :)

-Matt
 
0
•••
The views expressed on this page by users and staff are their own, not those of NamePros.
GoDaddyGoDaddy
Before you call imagecopyresampled(), you need to actually get the size (code below uses your current variable names, so just cut and paste):

PHP:
	$imgsize = getimagesize($uploadfile2);

Also, if you want to have some fun, you can replace the black background with a completely transparent background by calling

PHP:
$transparent = imagecolorallocatealpha($image_resized, 255, 255, 255, 127);
imagefill($image_resized,0,0,$transparent);

right after imagecreatetruecolor().
 
0
•••
K, but earlier in my script I *do* get the image sizes already (hence it DOES resize images) and I don't really want a transparent image: I want an image with the picture I uploaded on it :)
 
0
•••
Ah. since you didn't post the getimagesize call I thought it was missing and defaulting to "0" for the new size, hence nothing appearing.

I'll assume you've also set $new_width and $new_height as well.

Sorry to keep asking basics, but there's nothing else to go on here. Have you verified that those values are valid?

Also, where do you want the output to end up? As your call to imagejpeg stands now, it's trying to write out a file to disk -- specifically, trying to overwrite your original $uploadfile2 file. This might be the problem; you might need a different filename and location where you have write access, and/or php might consider $uploadfile2 unwriteable because it's locked open for reading.

Can't think of anything else, because your code looks almost exactly like the code I use successfully in many scripts without problem.

I was only having fun with the transparent background, since it won't work on images that are ultimately output as jpg anyhow.
 
1
•••
Maybe I'm not being clear, but ...

1. It's resizing the images fine.
2. The images are the right size (hence it resizes properly) but they are black.
3. It's not a situation where "nothing is appearing" - it's just that the images are black.

Everything else (write access, permissions, etc) seem to be fine.... :(

Thanks for your help, though ^_^

Anything else I'm missing?
 
Last edited:
0
•••
... still need help folks :) You are all being real saints through this, which I greatly appreciate. Again, that $ reward is still in place if you can get it to work with me.
 
0
•••
Something I used:

PHP:
$imageurl = "http://blah.com/image.gif";
$imagetype = "gif";
// by [email protected]
//
// proportional on-the-fly thumb generator from JPG images
//
// usage example:
// <img src= "thumb.php?src=pic.jpg&wmax=150&hmax=100&quality=90&bgcol=FF0000"> </img>
//
// parameters:  src = source image
//              wmax = max width
//              hmax = max height
//              quality = JPG quality of generated thumb - optional.
//                        if not specified, quality=90
//              bgcol = if specified, allways generates exact wmax x hmax sized thumb,
//                      with bacground color bgcol and centered source image
//
// note: if source image is smaller than desired thumbnail, it will not be resized!

$src = $imageurl;
$wmax = 110;
$hmax = 110;
$quality = 80;
$bgcol = "FFFFFF";

header("Content-type: image/" . $imagetype . "");
if ($imagetype == "jpeg")
{
    $source = imagecreatefromjpeg($src);
}
elseif ($imagetype == "png")
{
    $source = imagecreatefrompng($src);
}
elseif ($imagetype == "gif")
{
    $source = imagecreatefromgif($src);
}
else
{
    $source = imagecreatefromgd2($src);
}
$orig_w = imagesx($source);
$orig_h = imagesy($source);

if ($orig_w > $wmax || $orig_h > $hmax)
{
    $thumb_w = $wmax;
    $thumb_h = $hmax;
    if ($thumb_w / $orig_w * $orig_h > $thumb_h)
        $thumb_w = round($thumb_h * $orig_w / $orig_h);
    else
        $thumb_h = round($thumb_w * $orig_h / $orig_w);
}
else
{
    $thumb_w = $orig_w;
    $thumb_h = $orig_h;
}
if (!@$bgcol)
{
    $thumb = imagecreatetruecolor($thumb_w, $thumb_h);
    imagecopyresampled($thumb, $source, 0, 0, 0, 0, $thumb_w, $thumb_h, $orig_w, $orig_h);
}
else
{
    $thumb = imagecreatetruecolor($wmax, $hmax);
    imagefilledrectangle($thumb, 0, 0, $wmax - 1, $hmax - 1, intval($bgcol, 16));
    imagecopyresampled($thumb, $source, round(($wmax - $thumb_w) / 2), round(($hmax -
        $thumb_h) / 2), 0, 0, $thumb_w, $thumb_h, $orig_w, $orig_h);
}
if (!@$quality)
    $quality = 90;

if ($imagetype == "jpeg")
{
    imagejpeg($thumb, "", $quality);
}
elseif ($imagetype == "bmp")
{
    imagewbmp($thumb, "", $quality);
}
elseif ($imagetype == "gif")
{
    imagegif($thumb, "", $quality);
}
elseif ($imagetype == "png")
{
    imagepng($thumb, "", $quality);
}
imagedestroy($thumb);

Works like a charm. Forgotten where it came from though.
 
0
•••
$imageInfo = getimagesize($newfile);
$memoryNeeded = round(($imageInfo[0] * $imageInfo[1] * $imageInfo['bits'] * $imageInfo['channels'] / 8 + Pow(2, 16)) * 1.65);
echo "<br> Memory Needed: ".$memoryNeeded."<br>";
if ($memoryNeeded > 6000000) { ini_set( 'memory_limit' , ($memoryNeeded + 2000000)); }

/// after resizing is complete, put memory limit back.
ini_restore ( 'memory_limit' );
 
0
•••
tm: Thanks for the excerpt; I'll see if there's anything I can take from it or change... but I'd rather not redo the entire thing again... rep + though

ihatebeans: Thanks, Rep +, but I still can't get it to work right.

Still need help :( Don't forget $ reward.
 
0
•••
Well, we could try a basic test to see if the problem lies with the imagecopyresampled line.

Replace
PHP:
imagecopyresampled($image_resized, $image, 0, 0, 0, 0, $new_width, $new_height, $imgsize[0], $imgsize[1])

with

PHP:
imagefill($image_resized,0,0,imagecollorallocate($image_resized,0,255,0))

This will fill the image stored in the file $uploadfile2 with bright green, indicating that at least some form of image manipulation works.
 
0
•••
It's bright green! ^_^ That seems to work okay. Now what?
 
0
•••
Well, it means there's something wrong with the information going into the resample call.

My guess is that the original dimensions are invalid (and hence 0) which means that nothing is being copied from the original image, so you get the default black-filled rectangle.

I copied your code unaltered and it worked perfectly. I've pasted what I used below. Note that the ONLY THING DIFFERENT is that I first added code to get the original image size, and then arbitrarily set the new size to be 1/2 of that.

Can you post the code you use to actually get and and set the old/new image sizes?

PHP:
<?
	// hardcoded image name; yours will have been uploaded
	$uploadfile2 = 'header_20.jpg';

	// get and set the old and new image sizes; you haven't shown us this code
	// I arbitrarily set the new size to be half the old size
	$imgsize=getimagesize($uploadfile2);
	$new_width = $imgsize[0]/2;
	$new_height = $imgsize[1]/2;

	//--------------------------------
	// BELOW IS YOUR CODE UNALTERED
	//--------------------------------

        $image_resized = imagecreatetruecolor($new_width, $new_height);
        $image = imagecreatefromjpeg($uploadfile2);
        if ($image === false) { die ('Unable to open image'); }
        if (!imagecopyresampled($image_resized, $image, 0, 0, 0, 0, $new_width, $new_height, $imgsize[0], $imgsize[1]))
        {
            die("Error");
        }
        else
        {
            imagejpeg($image_resized, $uploadfile2, 100);
        }  
?>
 
0
•••
Wow! :) That's a lot of work it seems for you to help me solve this. Thanks.

Here's my image-size-finding code.... I was hesitant to share this earlier... but now I'm desperate:

PHP:
$imgsize2 = GetImageSize($newfile2);

    /*== check size  0=width, 1=height ==*/
    if (($imgsize2[0] > 180) || ($imgsize2[1] > 180))
    {
		// Set a new width, and calculate new height
		if ($imgsize2[1] >= $imgsize2[0])
		{
			$new_width = 180;
			$new_height = $imgsize2[1] * ($new_width/$imgsize2[0]);
		}
		else
		{
			// Or, vice versa
			$new_height = 180;
			$new_width = $imgsize2[0] * ($new_height/$imgsize2[1]);
		}

Let me check something... I'll be right back with an update.

UPDATE: I tried echoing the values of the 4 size variables (newwidth,newheight,and imgsize[0] and [1]) and I got this:

imgsize[0]: 1024
imgsize[1]: 684
newwidth: 269
newheight: 180

'Course, I put a round() function in the newwidth and newheight variables to make them nice round numbers.


And... I still get a black box -_-
 
Last edited:
0
•••
chulium said:
Wow! :) That's a lot of work it seems for you to help me solve this. Thanks.

Ah, no problem. It only took a couple of minutes

chulium said:
Here's my image-size-finding code.... I was hesitant to share this earlier... but now I'm desperate:

Doesn't seem like anything too secret there -- scaling code for non-square images with a constraint; I used something similar on a favicon project once.

chulium said:
Let me check something... I'll be right back with an update.

UPDATE: I tried echoing the values of the 4 size variables (newwidth,newheight,and imgsize[0] and [1]) and I got this:

imgsize[0]: 1024
imgsize[1]: 684
newwidth: 269
newheight: 180

'Course, I put a round() function in the newwidth and newheight variables to make them nice round numbers.


And... I still get a black box -_-

So there's only one option left -- the original image resource. We're back to an issue with either $image or $uploadfile2.

Obviously the upload is working because, as you say, you can get the image size. Maybe it's a memory issue? Maybe some php setting?

Before going there, can you just make *sure* that the uploaded image actually contains valid data? Can you comment out the sizing code, just run the upload code, ftp $uploadfile2 back down to your local machine, take a look at it and make sure it actually does contains the original image?

It's all I can think to look at at this point before diving into php.ini
 
0
•••
cef said:
Ah, no problem. It only took a couple of minutes



Doesn't seem like anything too secret there -- scaling code for non-square images with a constraint; I used something similar on a favicon project once.



So there's only one option left -- the original image resource. We're back to an issue with either $image or $uploadfile2.

Obviously the upload is working because, as you say, you can get the image size. Maybe it's a memory issue? Maybe some php setting?

Before going there, can you just make *sure* that the uploaded image actually contains valid data? Can you comment out the sizing code, just run the upload code, ftp $uploadfile2 back down to your local machine, take a look at it and make sure it actually does contains the original image?

It's all I can think to look at at this point before diving into php.ini
Alright; I've commented out the resizing portion of the script and downloaded via FTP the uploaded one. Yes, it is the right image.

So uploading it *is* working... is this the time to move to ini settings? :-/
 
0
•••
Yep, time to get creative ;)

In php.ini change

memory_limit = 8M

to

memory_limit = 32M

Not an ideal solution if it works, but it's a start. If 32M works, try setting to 16M. In the past, I've had php scripts run out of memory when working with large images when the default 8M setting was used.

Next, is the image from a digital camera? If so, it probably has embedded exif information, including a thumbnail. This can sometimes cause problems for parts of the gd library, so if you can, strip out the exif information (including the thumbnail) and try again. NOTE don't use the PHP functions to strip the data, because they sometimes have problems with it too. Use an external 3rd party tool, something nice and simple.

We'll get this yet!
 
0
•••
cef said:
Yep, time to get creative ;)

In php.ini change

memory_limit = 8M

to

memory_limit = 32M

Not an ideal solution if it works, but it's a start. If 32M works, try setting to 16M. In the past, I've had php scripts run out of memory when working with large images when the default 8M setting was used.

Next, is the image from a digital camera? If so, it probably has embedded exif information, including a thumbnail. This can sometimes cause problems for parts of the gd library, so if you can, strip out the exif information (including the thumbnail) and try again. NOTE don't use the PHP functions to strip the data, because they sometimes have problems with it too. Use an external 3rd party tool, something nice and simple.

We'll get this yet!
Hey cef,

As for stripping EXIF data, that doesn't seem to solve the problem.

Also, I cannot edit my .ini file; it's my host's responsibility.

...this is getting bad :( Still offering the $$ reward for any way to fix it.
 
0
•••
Are you using a GIF? because imagecreatetruecolor does not work with GIF or a GD libary older than 2.0.1
Check those two things.. You are using the best method to resize, but keep in mind that you will need to do something different to a GIF image.

It is black because there is the absense of colour. Meaning that the part of your code ment to transfer the colour from the orginal image, to the resized one is not working.

Here is a class I found that might be able to help you.

PHP:
function resizeImage($img, $imgPath, $suffix, $by, $quality)
{
    // Open the original image.
    $original = imagecreatefromjpeg("$imgPath/$img") or die("Error Opening original (<i>$imgPath/$img</i>)");
    list($width, $height, $type, $attr) = getimagesize("$imgPath/$img");

    // Determine new width and height.
    $newWidth = ($width/$by);
    $newHeight = ($height/$by);
   
    // Resample the image.
    $tempImg = imagecreatetruecolor($newWidth, $newHeight) or die("Cant create temp image");
    imagecopyresized($tempImg, $original, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height) or die("Cant resize copy");
   
    // Create the new file name.
    $newNameE = explode(".", $img);
    $newName = โ€. $newNameE[0] .โ€. $suffix .โ€˜.โ€™. $newNameE[1] .โ€;
   
    // Save the image.
    imagejpeg($tempImg, "$imgPath/$newName", $quality) or die("Cant save image");
   
    // Clean up.
    imagedestroy($original);
    imagedestroy($tempImg);
    return true;
}

I would suggest adding the or die to the end of each function and see if there is a problem. Also take the functions out of the IF statement and use or die.. it runs faster than a if statement.

- Steve
 
Last edited:
0
•••
chulium said:
Hey cef,

As for stripping EXIF data, that doesn't seem to solve the problem.

Also, I cannot edit my .ini file; it's my host's responsibility.

...this is getting bad :( Still offering the $$ reward for any way to fix it.

Alas, all I can recommend is trying to get your host to change the memory_limit size for you. The 8M setting did indeed cause the script to die for me when I tested this with a large image. When I bumped the setting to 32M, it worked fine.

But if you can SSH into your account you can try and test this from the command line: upload the image using FTP, and then comment out your upload code and hardcode the name in the script (as I did in the previously-posted example). Then cd to the script directory and run the script from the command line:

php <scriptname>

If there's any problem, you'll see an error message.
 
0
•••
http://www.finerpixels.com/imgstore/314_950_thumb_IMGP7079.jpg

:)

iNod: Thanks! That function seems to be working. But, the quality seems to be low (or is it just me?) Regardless, I'll send your winnings. PM me your PP info.

cef: I'll send some compensation winnings to your PP account too ;) Thanks for all the help.

iNod: So, any idea why it looks aliased? I set the quality to 100.
 
0
•••
Dynadot โ€” .com Registration $8.99Dynadot โ€” .com Registration $8.99
Appraise.net
Unstoppable Domains
Domain Recover
DomainEasy โ€” Zero Commission
  • The sidebar remains visible by scrolling at a speed relative to the pageโ€™s height.
Back