|
|
 |
imagecopyresampled (PHP 4 >= 4.0.6, PHP 5) imagecopyresampled -- Copy and resize part of an image with resampling Descriptionbool imagecopyresampled ( resource dst_image, resource src_image, int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h )
imagecopyresampled() copies a rectangular
portion of one image to another image, smoothly interpolating pixel
values so that, in particular, reducing the size of an image still
retains a great deal of clarity.
Returns TRUE on success or FALSE on failure.
dst_image is the destination image,
src_image is the source image identifier. If
the source and destination coordinates and width and heights
differ, appropriate stretching or shrinking of the image fragment
will be performed. The coordinates refer to the upper left
corner. This function can be used to copy regions within the
same image (if dst_image is the same as
src_image) but if the regions overlap the
results will be unpredictable.
Note:
There is a problem due to palette image limitations (255+1 colors).
Resampling or filtering an image commonly needs more colors than 255, a
kind of approximation is used to calculate the new resampled pixel and its
color. With a palette image we try to allocate a new color, if that
failed, we choose the closest (in theory) computed color. This is
not always the closest visual color. That may produce a weird result, like
blank (or visually blank) images. To skip this problem, please use a
truecolor image as a destination image, such as one created by
imagecreatetruecolor().
Note: This function requires GD 2.0.1 or later.
Examples
Example 1. Simple example
This example will resample an image to half its original size.
|
<?php
$filename = 'test.jpg';
$percent = 0.5;
header('Content-type: image/jpeg');
list($width, $height) = getimagesize($filename);
$new_width = $width * $percent;
$new_height = $height * $percent;
$image_p = imagecreatetruecolor($new_width, $new_height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
imagejpeg($image_p, null, 100);
?>
|
|
Example 2. Resampling an image proportionally
This example will display an image with the maximum width,
or height, of 200 pixels.
|
<?php
$filename = 'test.jpg';
$width = 200;
$height = 200;
header('Content-type: image/jpeg');
list($width_orig, $height_orig) = getimagesize($filename);
if ($width && ($width_orig < $height_orig)) {
$width = ($height / $height_orig) * $width_orig;
} else {
$height = ($width / $width_orig) * $height_orig;
}
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
imagejpeg($image_p, null, 100);
?>
|
|
User Contributed Notes
imagecopyresampled
carnivorous_winds_fr AT yahoo DOT fr
19-May-2005 12:47
I tried this code from a previous post.
<?
...
$t_im = imageCreateTrueColor($t_wd,$t_ht);
imageAntiAlias($t_im,true);
imagealphablending($t_im, false);
imagesavealpha($t_im,true);
$transparent = imagecolorallocatealpha($t_im, 255, 255, 255, 0);
for($x=0;$x<$t_wd;$x++) {
for($y=0;$y<$t_ht;$y++) {
imageSetPixel( $t_im, $x, $y, $transparent );
}
}
imageCopyResampled($t_im, $o_im, 0, 0, 0, 0, $t_wd, $t_ht, $o_wd, $o_ht);
imagePNG($t_im, $image_name);
...
?>
It seems that it is not working correctly. In my test the source picture in ImageCopyResampled() is smaller than the destination picture $t_im, the remaining part is white !
I changed transparent alpha channel to 127, and I tried to replace loops with imagefilledrectangle().
It works fine and these resource greedy loops are removed.
Here is the code with my change.
<?
...
$t_im = imageCreateTrueColor($t_wd,$t_ht);
imageAntiAlias($t_im,true);
imagealphablending($t_im, false);
imagesavealpha($t_im,true);
$transparent = imagecolorallocatealpha($t_im, 255, 255, 255, 127);
imagefilledrectangle($t_img, 0, 0, $t_wd, $t_ht, $transparent);
imageCopyResampled($t_im, $o_im, 0, 0, 0, 0, $t_wd, $t_ht, $o_wd, $o_ht);
imagePNG($t_im, $image_name);
...
?>
del at kartoon dot net
05-May-2005 03:38
This snippet allows you to grab a thumbnail from the center of a large image. This was used for a client photo gallery for art to give a teaser of the image to come (only a small portion). You could get dynamic with this value. I also put in a scaling factor in case you want to scale down first before chopping.
<?php
$filename = 'moon.jpg';
$percent = 1.0; $imagethumbsize = 200; header('Content-type: image/jpeg');
list($width, $height) = getimagesize($filename);
$new_width = $width * $percent;
$new_height = $height * $percent;
$image_p = imagecreatetruecolor($imagethumbsize , $imagethumbsize); $image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, -($new_width/2) + ($imagethumbsize/2), -($new_height/2) + ($imagethumbsize/2), 0, 0, $new_width , $new_width , $width, $height);
imagejpeg($image_p, null, 100);
?>
djneoform at gmail dot com
04-Mar-2005 08:21
Here's a function i made that will force a given set of constraints on an image (usrfull if you want to make thumbnails that are all the same size) while keeping aspect ratio.
It resizes, then crops the extra off the top or bottom.
function forceConstraints($srcFile, $srcType, $dstType, $dstWidth, $dstHeight, $dstPath)
{
if ($srcType == "image/jpeg")
$handle = @imagecreatefromjpeg($srcFile);
else if ($srcType == "image/png")
$handle = @imagecreatefrompng($srcFile);
else if ($srcType == "image/gif")
$handle = @imagecreatefromgif($srcFile);
else
return false;
if (!$handle)
return false;
$srcWidth = @imagesx($handle);
$srcHeight = @imagesy($handle);
if ($srcWidth >= $dstWidth && $srcHeight >= $dstHeight)
{
$newHandle = @imagecreatetruecolor($dstWidth, $dstHeight);
if (!$newHandle)
return false;
if($srcHeight < $srcWidth)
{
$ratio = (double)($srcHeight / $dstHeight);
$cpyWidth = round($dstWidth * $ratio);
if ($cpyWidth > $srcWidth)
{
$ratio = (double)($srcWidth / $dstWidth);
$cpyWidth = $srcWidth;
$cpyHeight = round($dstHeight * $ratio);
$xOffset = 0;
$yOffset = round(($srcHeight - $cpyHeight) / 2);
} else {
$cpyHeight = $srcHeight;
$xOffset = round(($srcWidth - $cpyWidth) / 2);
$yOffset = 0;
}
} else {
$ratio = (double)($srcWidth / $dstWidth);
$cpyHeight = round($dstHeight * $ratio);
if ($cpyHeight > $srcHeight)
{
$ratio = (double)($srcHeight / $dstHeight);
$cpyHeight = $srcHeight;
$cpyWidth = round($dstWidth * $ratio);
$xOffset = round(($srcWidth - $cpyWidth) / 2);
$yOffset = 0;
} else {
$cpyWidth = $srcWidth;
$xOffset = 0;
$yOffset = round(($srcHeight - $cpyHeight) / 2);
}
}
if (!@imagecopyresampled($newHandle, $handle, 0, 0, $xOffset, $yOffset, $dstWidth, $dstHeight, $cpyWidth, $cpyHeight))
return false;
@imagedestroy($handle);
if ($dstType == "png")
@imagepng($newHandle, $dstPath.".png");
else if ($dstType == "jpg")
@imagejpeg($newHandle, $dstPath.".jpg", 90);
else if ($dstType == "gif")
@imagegif($newHandle, $dstPath.".gif");
else
return false;
@imagedestroy($newHandle);
return true;
} else {
return "Sorry, that image is too small. The image must be at least ".$dstWidth."x".$dstHeight." pixels in size.";
}
}
afrowuk at tiscali dot co dot uk
02-Jan-2005 09:17
This simple function resizes a JPG image file giving just a maximum width, and resizes keeping the aspect ratio. This is useful if you have to resize a JPG image that must fit the width of i.e. a div element, but doesn't have to have a maximum height.
<?
function resizeJPG($jpgFile, $width) {
list($width_orig, $height_orig) = getimagesize($jpgFile);
$height = (int) (($width / $width_orig) * $height_orig);
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($jpgFile);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
imagejpeg($image_p, $jpgFile, 100);
}
?>
-Stu
stemplar444 at yahoo dot com
12-Aug-2004 12:57
Two comments regarding imageCopyResampleBicubic() published here.
Quality:
More grainy than imagecopyresampled(). Not very good for bigger destination images, I think.
Speed:
In my tests, it was only faster if destination size was smaller than ~200x200 pixel. The function becomes slower and slower the bigger the destination image gets. In contrast, imagecopyresampled() finished at the same speed, no matter how big the destination was. My source image resoloution ~ 1500x2000 pixel.
ron at korving dot demon dot nl
07-Aug-2004 04:25
This Bicubic resample algorithm is based on the one Scott posted earlier, only this one is about 50% faster for truecolor images and about 10% faster for palette images.
<?
function imageCopyResampleBicubic($dst_img, $src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h)
{
$scaleX = ($src_w - 1) / $dst_w;
$scaleY = ($src_h - 1) / $dst_h;
$scaleX2 = $scaleX / 2.0;
$scaleY2 = $scaleY / 2.0;
$tc = imageistruecolor($src_img);
for ($y = $src_y; $y < $src_y + $dst_h; $y++)
{
$sY = $y * $scaleY;
$siY = (int) $sY;
$siY2 = (int) $sY + $scaleY2;
for ($x = $src_x; $x < $src_x + $dst_w; $x++)
{
$sX = $x * $scaleX;
$siX = (int) $sX;
$siX2 = (int) $sX + $scaleX2;
if ($tc)
{
$c1 = imagecolorat($src_img, $siX, $siY2);
$c2 = imagecolorat($src_img, $siX, $siY);
$c3 = imagecolorat($src_img, $siX2, $siY2);
$c4 = imagecolorat($src_img, $siX2, $siY);
$r = (($c1 + $c2 + $c3 + $c4) >> 2) & 0xFF0000;
$g = ((($c1 & 0xFF00) + ($c2 & 0xFF00) + ($c3 & 0xFF00) + ($c4 & 0xFF00)) >> 2) & 0xFF00;
$b = ((($c1 & 0xFF) + ($c2 & 0xFF) + ($c3 & 0xFF) + ($c4 & 0xFF)) >> 2);
imagesetpixel($dst_img, $dst_x + $x - $src_x, $dst_y + $y - $src_y, $r+$g+$b);
}
else
{
$c1 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX, $siY2));
$c2 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX, $siY));
$c3 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX2, $siY2));
$c4 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX2, $siY));
$r = ($c1['red'] + $c2['red'] + $c3['red'] + $c4['red'] ) << 14;
$g = ($c1['green'] + $c2['green'] + $c3['green'] + $c4['green']) << 6;
$b = ($c1['blue'] + $c2['blue'] + $c3['blue'] + $c4['blue'] ) >> 2;
imagesetpixel($dst_img, $dst_x + $x - $src_x, $dst_y + $y - $src_y, $r+$g+$b);
}
}
}
}
?>
15-Jul-2004 07:09
In add to all the posts that describes how to create thumbnails:
If you are trying to resample a png image with its transparency you need to do this workaround:
<?
...
$t_im = imageCreateTrueColor($t_wd,$t_ht);
imageAntiAlias($t_im,true);
imagealphablending($t_im, false);
imagesavealpha($t_im,true);
$transparent = imagecolorallocatealpha($t_im, 255, 255, 255, 0);
for($x=0;$x<$t_wd;$x++) {
for($y=0;$y<$t_ht;$y++) {
imageSetPixel( $t_im, $x, $y, $transparent );
}
}
imageCopyResampled($t_im, $o_im, 0, 0, 0, 0, $t_wd, $t_ht, $o_wd, $o_ht);
imagePNG($t_im, $image_name);
...
?>
The alphablending must be off so the imagesavealpha can be true.
The double FORs is need to fix the problem with imagefill function that not support colors with alpha setted.
It is TO SLOWLIER than imagefill, but do a nice work with static images.
Take a look and enjoy the nice result.
(this workaround needs the gd2 library)
[s]
Pigmeu
m.kumar [at] gmx.at
30-Aug-2001 11:10
For those who think that resampling loads the server too badly, have a look at this fine article over at zend:
http://www.zend.com/zend/art/scriptcaching.php
it describes how to create static html from scripts, however, this technique is pretty easily applicable to images.
I've written a short script to outline how to adapt my above mentioned article for caching of thumbnails. see:
http://tzu.nme.at/php/cache.phps
| |