我正在使用jQuery的imgAreaSelect插件来裁剪图像并保存缩略图,以便在比例发生变化的情况下使用。不幸的是,结果远非我所期望的,我无法做到正确。图像整体调整大小而不是被裁剪。
以下是测试示例:
<?php
/***
*
* $_GET returned values
*
* x1 = 0
* x2 = 400
* y1 = 66
* y2 = 258
* w = 400
* h = 192
* folder = widethumb
* filename = IMG_4591.jpg
* scale = 48
*
* Original image properties
*
* width = 600px
* height = 900px
*
***/
define('DOCROOT', realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR);
extract($_GET);
$fn = $filename;
$filename = DOCROOT.$filename;
list($width, $height) = getimagesize($filename);
$src = imagecreatefromjpeg($filename);
$dst = imagecreatetruecolor($w, $h);
imagecopyresampled($dst, $src, 0, 0, (int) $x1, (int) $y1, (int) $w, (int) $h, $width, $height);
header('Content-Type: image/jpeg');
imagejpeg($dst);
我在这里做什么?
干杯!
答案 0 :(得分:5)
来自PHP文档:
bool 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()将一个图像的矩形部分复制到另一个图像,平滑地插入像素值,这样,特别是减小图像的大小仍然保持很大的清晰度。
换句话说,imagecopyresampled()将从宽度为src_w的src_image和高度为src_h的位置(src_x,src_y)取一个矩形区域,并将其放置在dst_image的宽度为dst_w且高度为dst_h的矩形区域中(dst_x, dst_y)。
因此,要获得您正在寻找的结果,您需要避免缩放。为此用途:
imagecopy($dst, $src, 0, 0, $x1, $y1, $w, $h);
// this can also be done but is less efficient (over 10 times slower)
imagecopyresampled($dst, $src, 0, 0, (int) $x1, (int) $y1, $w, $h, $w, $h);
在这里,我们从源头采取相同大小的矩形,因为我们将它放入目标图像 我刚刚测试过,它运行得很好。
<强>更新强> 我刚刚在我的测试服务器上再次尝试,它运行正常。我正在使用以下代码:
$filename = "test.jpg";
extract($_GET);
$src = imagecreatefromjpeg($filename);
$dst = imagecreatetruecolor($w, $h);
imagecopy($dst, $src, 0, 0, $x1, $y1, $w, $h);
// this is over 10 times slower, as we are only cropping we should use imagecopy
//imagecopyresampled($dst, $src, 0, 0, $x1, $y1, $w, $h, $w, $h);
header('Content-Type: image/jpeg');
imagejpeg($dst);
我这样称呼它:
http://localserver/test/gd_crop.php?x1=906&y1=267&w=501&h=355
效果更新
由于我们没有调整大小,我们可以简单地使用imagecopy
。我测量的3个函数的性能如下所示。
imagecopyresampled 69ms
imagecopyresized 5.5ms
imagecopy 4.5ms
因此重采样和其他两个功能之间存在10个速度差的顺序。
我终于想出了以下代替imagecopyresampled
函数的行,尝试一下,我还更新了上面的代码清单:
imagecopy($dst, $src, 0, 0, $x1, $y1, $w, $h);
答案 1 :(得分:1)
请改用WideImage
库。
这是我自己的裁剪功能:
function createThumbnail($file, $cropX, $cropY, $cropWidth, $cropHeight, $desiredWidth, $desiredHeight, $shrink = false)
{
if(file_exists(MPS_ROOT_PATH . "$file") && $cropWidth && $cropHeight)
{
$source_path = MPS_ROOT_PATH . $file;
list( $source_width, $source_height, $source_type ) = getimagesize( $source_path );
switch ( $source_type )
{
case IMAGETYPE_GIF:
$source_gdim = imagecreatefromgif( $source_path );
break;
case IMAGETYPE_JPEG:
$source_gdim = imagecreatefromjpeg( $source_path );
break;
case IMAGETYPE_PNG:
$source_gdim = imagecreatefrompng( $source_path );
break;
default:
return false;
}
if(!$desiredWidth)
{
// Desired width not set, computing new width based on original
// image's aspect ratio...
$desiredWidth = $cropWidth * ($desiredHeight / $cropHeight);
}
if(!$desiredHeight)
{
// Desired height not set, computing new height based on original
// image's aspect ratio
$desiredHeight = $cropHeight * ($desiredWidth / $cropWidth);
}
if(!$desiredWidth || !$desiredHeight)
{
// Desired height or width not set.
// Halting image processing and returning file
return $file;
}
$source_aspect_ratio = $cropWidth / $cropHeight;
$desired_aspect_ratio = $desiredWidth / $desiredHeight;
if($shrink)
{
// Shrink to fit flag set. Inverting computations to make image fit
// within the desired dimensions...
if($source_aspect_ratio > $desired_aspect_ratio)
{
// Source image is wider than desired aspect ratio,
// setting thumbnail width to the desired width and the height
// will be computed based on the original image's aspect ratio
$temp_width = $desiredWidth;
$temp_height = (int) ($desiredWidth / $source_aspect_ratio);
}
else
{
// Source image is taller than desired aspect ratio,
// setting thumbnail height to the desired height and the width
// will be computed based on the original image's aspect ratio
$temp_height = $desiredHeight;
$temp_width = (int) ($desiredHeight * $source_aspect_ratio);
}
}
// shrink to fit not set
else
{
if($source_aspect_ratio > $desired_aspect_ratio)
{
// Source image is wider than desired aspect ratio,
// setting thumbnail height to the desired height to fill the
// desired aspect ratio and the width will be computed based on
// the original image's aspect ratio
$temp_height = $desiredHeight;
$temp_width = (int) ($desiredHeight * $source_aspect_ratio);
}
else
{
// Source image is taller than desired aspect ratio,
// setting thumbnail width to the desired width to fill the
// desired aspect ratio and the width will be computed based on
// the original image's aspect ratio");
$temp_width = $desiredWidth;
$temp_height = (int) ($desiredWidth / $source_aspect_ratio);
}
}
$temp_gdim = imagecreatetruecolor($temp_width, $temp_height);
// Copying a $cropWidth x $cropHeight image from the source
// file at ($cropX, $cropY) and resampling it to fit the temporary
// $temp_width x $temp_height thumbnail at (0, 0)
imagecopyresampled(
$temp_gdim,
$source_gdim,
0, 0,
$cropX, $cropY,
$temp_width, $temp_height,
$cropWidth, $cropHeight
);
$x0 = ($desiredWidth - $temp_width) / 2;
$y0 = ($desiredHeight - $temp_height) / 2;
// Positioning the temporary $temp_width x $temp_height thumbnail in
// the center of the final $desiredWidth x $desiredHeight thumbnail...
// Creating final thumbnail canvas at $desiredWidth x $desiredHeight
$desired_gdim = imagecreatetruecolor($desiredWidth, $desiredHeight);
$white = imagecolorallocate($desired_gdim, 255, 255, 255);
imagefill($desired_gdim, 0, 0, $white);
// Filling final thumbnail canvas with white
// Copying a $temp_width x $temp_height image from the temporary
// thumbnail at (0, 0) and placing it in the final
// thumbnail at ($x0, $y0)
imagecopy(
$desired_gdim,
$temp_gdim,
$x0, $y0,
0, 0,
$temp_width, $temp_height
);
$pathInfo = pathinfo($file);
$thumbFile = "images/thumbs/thumb_" . basename($pathInfo["filename"]) . ".jpg";
if(imagejpeg($desired_gdim, MPS_ROOT_PATH . $thumbFile, 80))
{
return $thumbFile;
}
else
{
return 1;
}
}
else
{
echo "Image File Does not exist or Invalid crop parameters!";
return false;
}
}
答案 2 :(得分:0)
你为什么不考虑使用imagemagick;它非常适合图像处理和裁剪只是使用裁剪图像的简单情况($ width,$ height,$ x,$ y);
答案 3 :(得分:0)
这是一个功能,您可以将目标尺寸传递到中心并从中心进行缩放和裁剪,保持纵横比,并且可以向上扩展。使用响应式设计的图像元素很容易实现。如果您更改目标尺寸,只需删除输出的文件,这将在他们不在时重新创建图像。
<?php
function scaleCrop($src, $dest, $destW, $destH, $anchor){
if(!file_exists($dest) && is_file($src) && is_readable($src)){
$srcSize = getimagesize($src);
$srcW = $srcSize[0];
$srcH = $srcSize[1];
$srcRatio = $srcW / $srcH;
$destRatio = $destW / $destH;
$img = (imagecreatefromjpeg($src));
$imgNew = imagecreatetruecolor($destW, $destH);
if ($srcRatio < $destRatio){
$scale = $srcW / $destW;
}
elseif($srcRatio >= $destRatio){
$scale = $srcH / $destH;
}
$srcX = ($srcW - ($destW * $scale)) / 2;
if($anchor = 'middle'){
$srcY = ($srcH - ($destH * $scale)) / 2;
}
elseif($anchor = 'top'){
$srcY = 0;
}
elseif($anchor = 'bottom'){
$srcY = $srcH - ($destH * $scale);
}
if($srcX < 0){$srcX = 0;};
if($srcY < 0){$srcY = 0;};
imagecopyresampled($imgNew, $img, 0, 0, $srcX, $srcY, $destW, $destH, $destW * $scale, $destH * $scale);
imagejpeg($imgNew, $dest, 70);
imagedestroy($img);
imagedestroy($imgNew);
}
return $dest;
}
?>
<img src="<?php echo scaleCrop('srcfolder/srcfile.jpg', 'destfolder/destfile.jpg', 320, 240, 'top'); ?>">