简体   繁体   English

如何调整图像大小保持约束PHP

[英]How to resize image keeping constraints php

I have made two GIFs to explain what I am trying to do. 我做了两个GIF来解释我要做什么。 Where the grey border is the dimensions I am after (700*525). 灰色边框是我要的尺寸(700 * 525)。 They are at the bottom of this question. 他们是这个问题的根本。

I want for all images that are larger than the given width and height to scale down to the border (from the centre) and then crop off the edges. 我希望所有大于给定宽度和高度的图像都缩小到边框(从中心),然后裁剪边缘。 Here is some code I have put together to attempt this: 这是我整理的一些代码来尝试这种操作:

if ($heightofimage => 700 && $widthofimage => 525){
    if ($heightofimage > $widthofimage){

        $widthofimage = 525;
        $heightofimage = //scaled height.

        //crop height to 700.

    }

    if ($heightofimage < $widthofimage){

        $widthofimage = //scaled width.
        $heightofimage = 700;

        //crop width to 525.

    }
}else{
    echo "image too small";
}

Here are some GIFs that visually explain what I am trying to achieve: 以下是一些GIF,可以直观地解释我要实现的目标:

GIF 1: Here the image proportions are too much in the x direction GIF 1:此处x方向的图像比例太大

在此处输入图片说明

GIF 2: Here the image proportions are too much in the y direction GIF 2:此处的图像比例在y方向上太大

在此处输入图片说明


image quality comparison for @timclutton @timclutton的图像质量比较

so I have used your method with PHP (click here to do your own test with the php) and then compared it to the original photo as you can see there is a big difference!: 因此,我已将您的方法与PHP结合使用(单击此处以对php进行自己的测试) ,然后将其与原始照片进行比较,您会发现它们之间有很大的不同!:

Your PHP method: 您的PHP方法:

在此处输入图片说明
(source: tragicclothing.co.uk ) (来源: tragicclothing.co.uk

The actual file: 实际文件:

在此处输入图片说明


The below code should do what you want. 下面的代码应做您想要的。 I've not tested it extensively but it seems to work on the few test images I made. 我没有对其进行广泛的测试,但是它似乎可以在我制作的一些测试图像上使用。 There's a niggling doubt at the back of mind that somewhere my math is wrong, but it's late and I can't see anything obvious. 在我心中有一个小小的疑问,我的数学错误在某处,但是已经晚了,我看不到任何明显的东西。

Edit : It niggled enough I went through again and found the bug, which was that the crop wasn't in the middle of the image. 编辑 :它足够让我再次经过,发现该错误,那就是该作物不在图像的中间。 Code replaced with working version. 代码已替换为工作版本。

In short: treat this as a starting point, not production-ready code! 简而言之:将其作为起点,而不是可用于生产的代码!

<?php

// set image size constraints.
$target_w = 525;
$target_h = 700;

// get image.
$in = imagecreatefrompng('<path to your>.png');

// get image dimensions.
$w = imagesx($in);
$h = imagesy($in);

if ($w >= $target_w && $h >= $target_h) {
    // get scales.
    $x_scale = ($w / $target_w);
    $y_scale = ($h / $target_h);

    // create new image.
    $out = imagecreatetruecolor($target_w, $target_h);

    $new_w = $target_w;
    $new_h = $target_h;
    $src_x = 0;
    $src_y = 0;

    // compare scales to ensure we crop whichever is smaller: top/bottom or
    // left/right.
    if ($x_scale > $y_scale) {
        $new_w = $w / $y_scale;

        // see description of $src_y, below.
        $src_x = (($new_w - $target_w) / 2) * $y_scale;
    } else {
        $new_h = $h / $x_scale;

        // a bit tricky. crop is done by specifying coordinates to copy from in
        // source image. so calculate how much to remove from new image and
        // then scale that up to original. result is out by ~1px but good enough.
        $src_y = (($new_h - $target_h) / 2) * $x_scale;
    }

    // given the right inputs, this takes care of crop and resize and gives
    // back the new image. note that imagecopyresized() is possibly quicker, but
    // imagecopyresampled() gives better quality.
    imagecopyresampled($out, $in, 0, 0, $src_x, $src_y, $new_w, $new_h, $w, $h);

    // output to browser.
    header('Content-Type: image/png');
    imagepng($out);
    exit;

} else {
    echo 'image too small';
}

?>

Using Imagick : 使用Imagick

define('PHOTO_WIDTH_THUMB', 700);
define('PHOTO_HEIGHT_THUMB', 525);

$image = new Imagick();
$image->readImage($file_source);
$width = $image->getImageWidth();
$height = $image->getImageHeight();

if($width > $height){
  $image->thumbnailImage(0, PHOTO_HEIGHT_THUMB);
}else{
  $image->thumbnailImage(PHOTO_WIDTH_THUMB, 0);
}

$thumb_width = $image->getImageWidth();
$thumb_height = $image->getImageHeight();
$x = ($thumb_width - PHOTO_WIDTH_THUMB)/2;
$y = ($thumb_height - PHOTO_HEIGHT_THUMB)/2;
$image->cropImage(PHOTO_THUMB_WIDTH, PHOTO_THUMB_HEIGHT, $x, $y);
$image->writeImage($thumb_destination);

$image->clear();
$image->destroy();
unlink($file_source);

I have used GD library to accomplish the resize. 我已经使用GD库来完成调整大小。 Basically what I did is, I calculated the image dimension and then resized the image to dimension 700x525 from the center. 基本上我所做的是,我计算了图像尺寸,然后将图像调整为从中心到尺寸700x525。

<?php
/*
 * PHP GD
 * resize an image using GD library
 */

//the image has 700X525 px ie 4:3 ratio
$src = 'demo_files/bobo.jpg';

// Get new sizes
list($width, $height) = getimagesize($src);

$x = 0;
$y = 0;
if($width < $height){
    $newwidth = $width;
    $newheight = 3/4 * $width;
    $x = 0;
    $y = $height/2 - $newheight/2;
}else{
    $newheight = $height;
    $newwidth = 4/3 * $height;
    $x=$width/2 - $newwidth/2;
    $y=0;

}

$targ_w = 700; //width of the image to be resized to
$targ_h = 525; ////height of the image to be resized to
$jpeg_quality = 90;

$img_r = imagecreatefromjpeg($src);
$dst_r = ImageCreateTrueColor( $targ_w, $targ_h );

imagecopyresampled($dst_r,$img_r,0,0,$x,$y,$targ_w,$targ_h,$newwidth,$newheight);

header('Content-type: image/jpeg');
imagejpeg($dst_r,null,$jpeg_quality);

exit;

?>

i used http://phpthumb.sourceforge.net to have a beutiful solution also with transparent curved edges. 我使用http://phpthumb.sourceforge.net也有一个漂亮的解决方案,它也具有透明的弯曲边缘。

this is an alternative route to solution, might suit someone's need with little configuration. 这是解决方案的另一种方法,可能只需很少的配置即可满足某人的需求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM