我正在尝试缩小上传时用户上传的图片尺寸 这没问题,但我现在想要了解尺寸。
我正在寻找一些关于算法的建议,我正在努力制作任何形状的图像 - 任何宽度/高度的正方形或矩形并缩小尺寸。
此图像需要缩小到目标框尺寸(这会改变但存储在变量中) 因此,需要缩小图像尺寸,使宽度和高度都大于目标保持纵横比的宽度和高度。但只是.. .. 目标尺寸将用于裁剪图像,因此边缘周围没有空白等。
我正在寻找基于不同维度图像创建正确调整大小的算法 - 我可以处理裁剪,甚至在大多数情况下调整大小但是它会失败,所以我伸出手。
我并不是真的要求PHP代码更伪。两者都很好。
谢天谢地。
当前的代码..但我已经经历了这么多迭代,这可能根本不起作用..:P
$image = $image_orig->clone();
$wRatio = $imageprops['width'] / $dimensions[0]; // imageprops = original image dimens.
$hRatio = $imageprops['height'] / $dimensions[1]; // $dimensions[0] = new width
$maxRatio = max($wRatio,$hRatio); // $dimensions[1] = new height
var_dump('thumb');
$ratio = ($imageprops['width'] - $dimensions[0]) > ($imageprops['height'] - $dimensions[1]);
$shape = ($imageprops['width'] > $imageprops['height']);
$error = ($imageprops['width'] / $imageprops['height']);
if( $error < 0.95 || $error > 1.05 ) { // its NOT a square
if($shape){ // longer width
$scale = $imageprops['height'] / $dimensions[0];
var_dump('1');
$height = $imageprops['height'] / $scale;
$image->scaleImage(0, $height);
} else {
$scale = $imageprops['width'] / $dimensions[1];
var_dump('2');
$width = $imageprops['width'] / $scale;
$image->scaleImage($width, 0);
}
} elseif($ratio) { // is square
$scale = $imageprops['height'] / $dimensions[1];
$newWidth = $imageprops['width'] / $scale;
$extra = 0;
$height = $dimensions[1]+$extra;
$image->scaleImage(0, $height);
} else {
$scale = $imageprops['width'] / $dimensions[0];
$newHeight = $imageprops['height'] / $scale;
$extra = 0;
$width = $dimensions[0]+$extra;
$image->scaleImage($width, 0);
}
$image_size = $image->getImageGeometry();
$image->cropImage($dimensions[0], $dimensions[1],($image_size['width']-$dimensions[0])/2,($image_size['height']-$dimensions[1])/2);
答案 0 :(得分:10)
注意:我在原始海报编辑他的问题之前写了这个答案,其中包含了一些澄清点的内容,这些内容已经改变了我认为原始问题所要求的内容。
因此,有一些概念和想法可以用来尝试解决你想要实现的目标。 (重力裁剪,Content Aware Cropping,内容识别重新缩放等)
因为您总是减小原始图像的大小,所以您基本上只是想要“切掉”图像的一部分。非常喜欢这个:
但问题是,您经常需要确保选择图像的最佳区域,以便不裁剪图像的不相关区域。这称为内容感知图像裁剪,只需使用“内容感知图像裁剪”进行搜索,您就可以找到大量信息。
无论如何,继续前进,取决于您的确切用例,您可能会发现实际上您不想从图像中删除任何内容,而是想要“液体缩放并裁剪”图像,以便您做“内容感知调整大小”。与内容感知调整大小的区别在于,调整大小会忽略图像的所有宽高比,而是查看相邻边缘和颜色,以便以流畅的方式调整图像大小。
所以,幸运的是,Imagick
附带了它自己的[liquidRescaleImage][3]
函数。
您可以像
一样使用它 $im->liquidRescaleImage(480, 260, 3, 18);
使用Liquid Rescale可以很好地重新缩放。下面是一个不完美的示例,但我有目的地创建了一个不完美的示例,因此您可以实际看到liquidRescale更改图像的组成,而不是仅调整宽高比。
但是,如果您只想缩放图像并保持纵横比,则可能需要执行诸如Flickr之类的网站,其中它们使图像longestLength等于某个值。 (例如,Flickr有6个左右不同的尺寸)
我们将您的照片调整为更适合网络的尺寸。每张图片都有 75x75和150x150方形缩略图以及100,240,320,500-,640- 800 * - ,1024-,1600 * - 和2048 *像素版本(这是...的长度) 最长的一面),以及你原来的文件。
复制Flickr调整大小政策的基本类...
<?php
class Scale {
public function getImageScale($x, $y, $longestLength, $allowDistort = false) {
//Set the default NEW values to be the old, in case it doesn't even need scaling
list($nx, $ny) = array($x, $y);
if ($x > $y) {
if ($longestLength > $x && !$allowDistort) {
return array($x, $y);
}
$r = $x / $longestLength;
return array($longestLength, $y / $r);
} else {
if ($longestLength > $x && !$allowDistort) {
return array($x, $y);
}
$r = $y / $longestLength;
return array($x / $r, $longestLength);
}
return array($nx, $ny);
}
}
然后如果你传递像这样的图像尺寸:
$originalImageX = 480;
$originalImageY = 260;
$scale = new Scale();
var_dump($scale->getImageScale($originalImageX,$originalImageY,120 ) );
/* Outputs
array(2) {
[0]=>
int(120)
[1]=>
int(65)
} */
此外,在Git上有这个Content Aware Cropping类,我之前已经调整了基类/结构,以便在我自己的项目中使用,所以我知道它运行良好。我不确定这个课程的许可证,但是你可以很明显地看一下它,并像以前那样切出对你有用的东西。
https://gist.github.com/2468935#file_content_aware_image.php
(和PS。下次直接提供你问题中的所有信息......)
答案 1 :(得分:2)
Dunno如果这是你想要的,请从我的个人脚本库xD: 您只需要为缩略图指定所需的$ maxW $ maxH和相同的值,它将按比例缩小图像。
该脚本有两个几乎相同的部分,一个用于缩略图,一个用于实际图像。
list($w, $h) = getimagesize($file);
$maxW = 1024;
$maxH = 786;
$thumbMaxW = 138;
$thumbMaxH = 92;
$newW = $w;
$newH = $h;
if($w > $thumbMaxW OR $h > $thumbMaxH){
if($w>=$h){
$thumbW = $thumbMaxW;
$thumbRatio = $w/$thumbMaxW;
$thumbH = (int)($h/$thumbRatio);
} else {
$thumbH = $thumbMaxH;
$thumbRatio = $h/$thumbMaxH;
$thumbW = (int)($w/$thumbRatio);
}
} else {
$thumbW = $w;
$thumbH = $h;
}
--------------------------------------------
if($w > $maxW OR $h > $maxH){
if($w >= $h){
$newW = $maxW;
$reduction = $w/$newW;
$newH = (int) ($h/$reduction);
}
if($h > $w){
$newH = $maxH;
$reduction = $h/$newH;
$newW = (int)($w/$reduction);
}
} else {
$newW = $w;
$newH = $h;
}