【问题标题】:PHP - How do I convert a rectangle image to a square image?PHP - 如何将矩形图像转换为方形图像?
【发布时间】:2014-05-09 13:45:46
【问题描述】:

如何在php中将一个矩形的图片变成一个正方形的头像,这样无论上传图片的分辨率是多少,都可以调整为一个集中的42 x 42像素头像。这是我正在使用的 php 代码。任何人都可以提供建议。

<?php 
//Name you want to save your file as
$save = 'myfile1.jpg';

$file = 'original1.jpg'; 
echo "Creating file: $save"; 
$size = 0.45; 
header('Content-type: image/jpeg') ; 
list($width, $height) = getimagesize($file) ; 
$modwidth = $width * $size; 
$modheight = $height * $size; 
$tn = imagecreatetruecolor($modwidth, $modheight) ; 
$image = imagecreatefromjpeg($file) ; 
imagecopyresampled($tn, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height) ; 

// Here we are saving the .jpg, you can make this gif or png if you want
//the file name is set above, and the quality is set to 100%
imagejpeg($tn, $save, 100) ; 
?> 

【问题讨论】:

  • 你想限制图片的纵横比吗?
  • 使用圆半径转换器
  • @Dai 我相信 OP 想要裁剪矩形的中心正方形以获得最大大小的正方形(以获得最可用的像素数据),然后将其重新缩放为 42x42 ... ,或者我只是浪费了 10 分钟来写一个答案......

标签: php image image-processing type-conversion


【解决方案1】:

首先,您需要知道尺寸为 $x 和 $y 的矩形的中心正方形在哪里。

// horizontal rectangle
if ($x > $y) {
    $square = $y;              // $square: square side length
    $offsetX = ($x - $y) / 2;  // x offset based on the rectangle
    $offsetY = 0;              // y offset based on the rectangle
}
// vertical rectangle
elseif ($y > $x) {
    $square = $x;
    $offsetX = 0;
    $offsetY = ($y - $x) / 2;
}
// it's already a square
else {
    $square = $x;
    $offsetX = $offsetY = 0;
}

现在我们可以用它构建一个正方形,只需将其调整为 42x42。这样的事情应该可以工作:

list($x, $y) = getimagesize($file);

// code snippet from above goes here
// so we get the square side and the offsets

$endSize = 42;
$tn = imagecreatetruecolor($endSize, $endSize);
imagecopyresampled($tn, $image, 0, 0, $offsetX, $offsetY, $endSize, $endSize, $square, $square);

所以,如果我们有一个 100x80 的矩形图像,代码会计算出大正方形的大小为 80,x 偏移为 10,y 偏移为 0。大致如下所示:

    100
-----------
|         |
|         | 80
|         |
-----------

     |
     V

    80
 ---------               42
 |       |             -----
 |       | 80   --->   |   | 42
 |       |             -----
 ---------

从原始矩形裁剪大正方形后,我们将其缩小到最终大小,在您的情况下为 42。


刚刚测试过并且效果很好,如果您打算将图像输出到浏览器中(结合标题),请确保删除回显线。

【讨论】:

  • 不客气,我很高兴能帮上忙!你只需要指定 $x = $width 和 $y = $height 就可以了。
【解决方案2】:

我不知道是否有人在寻找这个,但我需要一个 600 x 600 平方的图像。

源可以是任何矩形图像,我需要保持原始图像的比例并将原始矩形图像居中放置在 600 x 600 平方的白色图像中。

在这里

  • src_file: 源图片的 URL
  • destination_file:目标文件的保存路径。
  • square_dimensions(像素)。我需要 600,但可以是任何值。
  • jpeg_quality: 质量 (0, 100) 。我使用默认的 90

    function square_thumbnail_with_proportion($src_file,$destination_file,$square_dimensions,$jpeg_quality=90)
    {
        // Step one: Rezise with proportion the src_file *** I found this in many places.
    
        $src_img=imagecreatefromjpeg($src_file);
    
        $old_x=imageSX($src_img);
        $old_y=imageSY($src_img);
    
        $ratio1=$old_x/$square_dimensions;
        $ratio2=$old_y/$square_dimensions;
    
        if($ratio1>$ratio2)
        {
            $thumb_w=$square_dimensions;
            $thumb_h=$old_y/$ratio1;
        }
        else    
        {
            $thumb_h=$square_dimensions;
            $thumb_w=$old_x/$ratio2;
        }
    
        // we create a new image with the new dimmensions
        $smaller_image_with_proportions=ImageCreateTrueColor($thumb_w,$thumb_h);
    
        // resize the big image to the new created one
        imagecopyresampled($smaller_image_with_proportions,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y); 
    
        // *** End of Step one ***
    
        // Step Two (this is new): "Copy and Paste" the $smaller_image_with_proportions in the center of a white image of the desired square dimensions
    
        // Create image of $square_dimensions x $square_dimensions in white color (white background)
        $final_image = imagecreatetruecolor($square_dimensions, $square_dimensions);
        $bg = imagecolorallocate ( $final_image, 255, 255, 255 );
        imagefilledrectangle($final_image,0,0,$square_dimensions,$square_dimensions,$bg);
    
        // need to center the small image in the squared new white image
        if($thumb_w>$thumb_h)
        {
            // more width than height we have to center height
            $dst_x=0;
            $dst_y=($square_dimensions-$thumb_h)/2;
        }
        elseif($thumb_h>$thumb_w)
        {
            // more height than width we have to center width
            $dst_x=($square_dimensions-$thumb_w)/2;
            $dst_y=0;
    
        }
        else
        {
            $dst_x=0;
            $dst_y=0;
        }
    
        $src_x=0; // we copy the src image complete
        $src_y=0; // we copy the src image complete
    
        $src_w=$thumb_w; // we copy the src image complete
        $src_h=$thumb_h; // we copy the src image complete
    
        $pct=100; // 100% over the white color ... here you can use transparency. 100 is no transparency.
    
        imagecopymerge($final_image,$smaller_image_with_proportions,$dst_x,$dst_y,$src_x,$src_y,$src_w,$src_h,$pct);
    
        imagejpeg($final_image,$destination_file,$jpeg_quality);
    
        // destroy aux images (free memory)
        imagedestroy($src_img); 
        imagedestroy($smaller_image_with_proportions);
        imagedestroy($final_image);
    }
    

【讨论】:

  • 很好,但我如何使它透明而不是白色填充?
  • @Jameel 你绝对不能使用 jpeg 图像,因为它们不支持透明度。尝试调整代码以使用 png 图像文件。
  • 对于复制粘贴:此脚本将图像放入带有白边的正方形,它不会从图像中剪切正方形。
【解决方案3】:

这是我的动物收养项目中的 sn-p,它切割图像的中间(水平或垂直)并使其成为正方形,而不向目标图像添加白色区域:

/**
 * Cuts a square image from the middle of rectangular image
 * Requires: mbstring, exif, gd built-in extensions uncommented in php.ini
 * Resamples rect img to square img and converts jpeg to wepp image
 *
 */
function squarify($src_file,$dst_file,$square_side=600,$quality=90) {

    // Deals only with jpeg
    if(exif_imagetype($src_file) != IMAGETYPE_JPEG) { return 'src_not_jpeg'; }
    
    // Convert old file into img
    $src_img=imagecreatefromjpeg($src_file);
    $src_side_x=imageSX($src_img);
    $src_side_y=imageSY($src_img);
    
    // Do not magnify image if its sides less than desired square side,
    // issue false if image size is too small
    // Remove, if you want src image be magnified
    // if($src_side_x < $square_side || $src_side_y < $square_side) { 
    //    return 'src_too_small'; 
    // }
    
    // Create new image
    $dst_image=imagecreatetruecolor($square_side,$square_side);
    
    // The image is square, just issue 
    // resampled image with adjusted square sides and image quality
    if($src_side_x==$src_side_y) {
        
        imagecopyresampled(
           $dst_image,
           $src_img,
           0,
           0,
           0,
           0,
           $square_side,
           $square_side,
           $src_side_x,
           $src_side_x
        );

    // The image is vertical, use x side as initial square side
    } elseif($src_side_x<$src_side_y) {
        
        $x1=0;
        $y1=round(($src_side_y-$src_side_x)/2);
        
         
        imagecopyresampled(
           $dst_image,
           $src_img,
           0,
           0,
           $x1,
           $y1,
           $square_side,
           $square_side,
           $src_side_x,
           $src_side_x
       );

    // The image is horizontal, use y side as initial square side
    } else {

        $x1=round(($src_side_x-$src_side_y)/2);
        $y1=0;
        
        imagecopyresampled(
           $dst_image,
           $src_img,
           0,
           0,
           $x1,
           $y1,
           $square_side,
           $square_side,
           $src_side_y,
           $src_side_y
        );
        
    }
    
    // Save it to the filesystem
    // imagewebp($dst_image,$dst_file,$quality);
    
    // Or show it in the browser, 
    // dont forget about header('Content-type: image/webp')
    imagewebp($dst_image,$dst_file,$quality);

}

您可以在现有图像上调用此函数:

if(!extension_loaded('mbstring')) { die('Err: mbstring extension not loaded.'); }
if(!extension_loaded('exif')) { die('Err: exif extension not loaded.'); }
if(!extension_loaded('gd')) { die('Err: gd extension not loaded.'); }

header('Content-type: image/webp');
squarify('images/src.jpg','images/res.webp',300,80);

【讨论】:

    猜你喜欢
    • 2017-10-08
    • 2011-07-10
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多