resize/裁剪/填充图片到一个固定的大小

我需要将图片大小调整为固定大小。 但它必须保持宽度和高度之间的因素。

假设我想将238 (w) X 182 (h)的图片大小调整为238 (w) X 182 (h)

我现在所做的是:

 Original width / target width = 1.333333 Original Height / target Height = 1.213333 

现在我采取最小的因素。

现在我总是有正确的宽度238 / 1.333333 = 210 。 但身高仍然是160

如何在不损坏图片的情况下将高度降至160

我需要裁剪吗? 如果这样怎么样?

这个解决scheme基本上和Can BerkGüder的解决scheme一样,但是花了一些时间写作和评论之后,我感觉就像张贴了。

这个函数会创build一个缩略图,其大小与您所input的大小完全相同。 图像被resize以适合缩略图的大小。 如果它不完全适合两个方向,它集中在thumnail。 广泛的评论解释了这些事情。

 function thumbnail_box($img, $box_w, $box_h) { //create the image, of the required size $new = imagecreatetruecolor($box_w, $box_h); if($new === false) { //creation failed -- probably not enough memory return null; } //Fill the image with a light grey color //(this will be visible in the padding around the image, //if the aspect ratios of the image and the thumbnail do not match) //Replace this with any color you want, or comment it out for black. //I used grey for testing =) $fill = imagecolorallocate($new, 200, 200, 205); imagefill($new, 0, 0, $fill); //compute resize ratio $hratio = $box_h / imagesy($img); $wratio = $box_w / imagesx($img); $ratio = min($hratio, $wratio); //if the source is smaller than the thumbnail size, //don't resize -- add a margin instead //(that is, dont magnify images) if($ratio > 1.0) $ratio = 1.0; //compute sizes $sy = floor(imagesy($img) * $ratio); $sx = floor(imagesx($img) * $ratio); //compute margins //Using these margins centers the image in the thumbnail. //If you always want the image to the top left, //set both of these to 0 $m_y = floor(($box_h - $sy) / 2); $m_x = floor(($box_w - $sx) / 2); //Copy the image data, and resample // //If you want a fast and ugly thumbnail, //replace imagecopyresampled with imagecopyresized if(!imagecopyresampled($new, $img, $m_x, $m_y, //dest x, y (margins) 0, 0, //src x, y (0,0 means top left) $sx, $sy,//dest w, h (resample to this size (computed above) imagesx($img), imagesy($img)) //src w, h (the full size of the original) ) { //copy failed imagedestroy($new); return null; } //copy successful return $new; } 

用法示例:

 $i = imagecreatefromjpeg("img.jpg"); $thumb = thumbnail_box($i, 210, 150); imagedestroy($i); if(is_null($thumb)) { /* image creation or copying failed */ header('HTTP/1.1 500 Internal Server Error'); exit(); } header('Content-Type: image/jpeg'); imagejpeg($thumb); 

这不会裁剪图片,但如果有必要的话,会在新图片周围留下空间,在创build缩略图时我认为这是一种更好的方法(而不是剪裁)。

 $w = 210; $h = 150; $orig_w = imagesx($original); $orig_h = imagesy($original); $w_ratio = $orig_w / $w; $h_ratio = $orig_h / $h; $ratio = $w_ratio > $h_ratio ? $w_ratio : $h_ratio; $dst_w = $orig_w / $ratio; $dst_h = $orig_h / $ratio; $dst_x = ($w - $dst_w) / 2; $dst_y = ($h - $dst_h) / 2; $thumbnail = imagecreatetruecolor($w, $h); imagecopyresampled($thumbnail, $original, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $orig_w, $orig_h); 

你有Imagick ? 如果是这样,你可以加载图像,并做一些像thumbnailimage()

在那里,你可以跳过任何一个参数(高度或宽度),它会正确resize。

也许看看PHPThumb (它适用于GD和ImageMagick)

只是一个提示高质量快速缩略图生成大图像:( 从php.net网站 )

如果你在两个阶段做缩略图生成:

  1. 从原始到中间图像的两倍最终尺寸,使用快速resize
  2. 使用高质量的重采样从中间图像到最终缩略图

那么这可以更快; 步骤1中的resize对于其大小来说质量相对较差,但是具有足够的额外分辨率,在步骤2中质量很好,并且中间图像足够小以至于高质量重新采样(其在2:1大小上很好地工作)收益非常快。

我宁愿resize,以便图像包含在您的限制内,然后填写空白部分。 所以在上面的例子中,你将resize,使高度是正确的,然后用背景颜色填充(每个末端7像素,我认为)左侧和右侧。

调整来自PHP源网页内的图像大小可能会有问题。 较大的映像(在磁盘上接近2 + MB)可能非常大,以至于需要超过32MB的内存才能处理。

出于这个原因,我倾向于使用基于CLI的脚本,可用的内存高达128MB,或者使用标准命令行,也可以根据需要使用。

 # where to put the original file/image. It gets resized back # it was originally found (current directory) SAFE=/home/website/PHOTOS/originals # no more than 640x640 when finished, and always proportional MAXSIZE=640 # the larger image is in /home/website/PHOTOS/, moved to .../originals # and the resized image back to the parent dir. cd $SAFE/.. && mv "$1" "$SAFE/$1" && \ convert "$SAFE/$1" -resize $MAXSIZE\x$MAXSIZE\> "$1" 

“convert”是ImageMagick命令行工具的一部分。

这些缩略图是什么? 如果是的话,种植不是一个大问题。 我们一直这样做。 如果它看起来不错,我甚至不会回避将任意比例裁剪成为残缺的二次缩略图,完全搞乱图像(是的,我是那个硬核 )。 这是一个devise师对技术问题的回答,但依然如此。 不要害怕庄稼!

我觉得有一点困惑..如果你只是想调整它,保持原来的比例,正确的操作是:

 $ratio = $originalWidth / $originalHeight; if(//you start from the width, and want to find the height){ $newWidth = $x; $newHeight = $x / $ratio; }else if(//you start from the height, and want to find the width){ $newHeight = $x; $newWidth = $x * $ratio; } 

否则,如果前缀newWidth和newHeight不能被改变,并且拇指比率与原始比率不同,唯一的方法是裁剪或添加边界到拇指。

如果你要采取切入的方式,这个function可以帮助你(我几年前写了5分钟,也许需要一些改进..它只适用于JPG,例如;):

  function thumb_cut($nomeimage, $source_path, $destination_path, $new_width, $new_height){ list($width, $height, $type, $attr) = getimagesize($source_path.$nomeimage); if($type == 2){ if($width > $new_width){ $new_width = $width; $new_height = $height; } $compression = 100; $destimg = imagecreatetruecolor($new_width,$new_height) or die("Problems creating the image"); $srcimg = ImageCreateFromJPEG($source_path.$nomeimage) or die("problem opening the image"); $w = ImageSX($srcimg); $h = ImageSY($srcimg); $ro = $new_width/$new_height; $ri = $w/$h; if($ro<$ri){ $par = "h"; }else{ $par = "w"; } if($par == "h"){ $ih = $h; $conv = $new_width/$new_height; $iw = $conv*$ih; $cw = ($w/2)-($iw/2); $ch = ($h/2)-($ih/2); }else if($par == "w"){ $iw = $w; $conv = $new_height/$new_width; $ih = $conv*$iw; $cw = ($w/2)-($iw/2); $ch = ($h/2)-($ih/2); } ImageCopyResampled($destimg,$srcimg,0,0,$cw,$ch,$new_width,$new_height,$iw,$ih) or die("problems with resize"); ImageJPEG($destimg,$destination_path.$nomeimage,$compression) or die("problems with storing new image"); } } 

技术是:

  1. 调整图像的大小,使一个尺寸匹配,而另一个超过所需的尺寸
  2. 从resize的图像中心取出想要的大小的图像。

最后,如果您对如何进行resizemath感到困惑,请记住,如果源图像和目标图像的比例相同,则此关系为:

 SourceWidth / SourceHeight = DestinationWidth / DestinationHeight 

如果你知道三个参数,你可以轻松地计算出第四个参数。

我写了一篇关于这个的文章:
裁剪 – 适合使用ASP / PHP的图像

你必须从顶部和底部裁剪5 px才能达到你的目标尺寸,但这可能会毁了图片。

真的你应该有一个目标的宽度或高度,然后调整其他维度相同的比例。