PHP调整图像大小并使用imagemagick裁剪

mr1*_*086 1 php algorithm crop imagemagick pseudocode

我正在尝试缩小用户在上传时上传的图片.
这没问题,但我现在想要了解尺寸.

我正在寻找一些关于算法的建议,我正在努力制作任何形状的图像 - 任何宽度/高度的正方形或矩形并缩小尺寸.

此图像需要缩小到目标框大小(这会改变但存储在变量中).
因此需要缩小图像尺寸,使宽度和高度都大于目标保持宽高比的宽度和高度.但只是..
目标尺寸将用于裁剪图像,因此边缘周围没有空白等.

我正在寻找基于不同维度图像创建正确调整大小的算法 - 我可以处理裁剪,甚至在大多数情况下调整大小但是它会失败,所以我伸出手.

我并不是真的要求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);
Run Code Online (Sandbox Code Playgroud)

Lay*_*yke 10

注意:我在原始海报编辑他的问题之前写了这个答案,其中包括澄清点的内容,这些内容已经改变了我认为原始问题所要求的内容.


因此,您可以使用一些概念和想法来尝试解决您打算实现的目标.(重力裁剪,内容意识裁剪,内容意识重新缩放等)

因为您总是减小原始图像的大小,所以您基本上只是想要"切掉"图像的一部分.非常喜欢这样:

在此输入图像描述

但问题是,您经常需要确保选择图像的最佳区域,以便不裁剪图像的不相关区域.这称为内容感知图像裁剪,只需使用"内容感知图像裁剪"进行搜索,您就可以找到大量信息.

无论如何,继续前进,取决于您的确切用例,您可能会发现实际上您不想从图像中删除任何内容,而是您想要"液体缩放并裁剪"图像,以便您执行"内容"意识到调整大小".与内容感知调整大小的区别在于,调整大小会忽略图像的所有宽高比,而是查看相邻边缘和颜色,以便以流畅的方式调整图像大小.

所以,幸运的是,Imagick它带有它自己的[liquidRescaleImage][3]功能.

你可以像使用它一样

$im->liquidRescaleImage(480, 260, 3, 18);

使用Liquid Rescale可以很好地重新缩放.下面是一个不完美的示例,但我有目的地创建了一个不完美的示例,因此您可以实际看到liquidRescale更改图像的组成,而不是仅调整宽高比.

原版的

原版的

Content Aware Liquid Rescale(450x350)

重新调整

但是,如果您只想缩放图像并保持纵横比,则可能需要执行诸如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);
    }       
}
Run Code Online (Sandbox Code Playgroud)

然后,如果你像这样传递Image Dimensions:

$originalImageX = 480;
$originalImageY = 260;    
$scale = new Scale();
var_dump($scale->getImageScale($originalImageX,$originalImageY,120 ) );    

/* Outputs
   array(2) {
  [0]=>
  int(120)
  [1]=>
  int(65)
} */
Run Code Online (Sandbox Code Playgroud)

此外,Git上有这个Content Aware Cropping类,我之前已经调整了基类/结构,以便在我自己的项目中使用,所以我知道它工作得很好.我不确定这个课程的许可证,但是你可以很明显地看一下它并切出对你有用的东西,就像我之前做的那样.

https://gist.github.com/2468935#file_content_aware_image.php

(和PS.下次直接提供你问题中的所有信息......)