Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - How do I convert a rectangle image to a square image?

How do I change a rectangular image to a square-shaped avatar in php, such that no matter what is the resolution of the uploaded image, it is able to resize to a centralized 42 x 42 pixel avatar. This is the php code I am using. Anyone can advise.

<?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) ; 
?> 
like image 869
user2192094 Avatar asked Mar 30 '14 06:03

user2192094


People also ask

How do you change a picture to square?

The most common way to make a photo square is either to resize or crop the picture in a photo editing tool. However, when you resize a picture, you may distort the image and if you crop it, you may lose details in the photo. So, to deal with that you can simply resize the canvas.


2 Answers

First you need to be tell where is the central square in a rectangle with dimensions $x and $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;
}

Now we can build a square from it, just need to resize it to 42x42. Something like this should work:

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);

So, if we have a rectangular image 100x80, the code will figure out that the big square size is 80, x offset is 10, y offset is 0. Roughly, it looks like this:

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

     |
     V

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

After we crop the big square from the original rectangle, we just shrink it to the end size, which is 42 in your case.


Just tested and works perfectly, make sure you remove the echo line if you plan to output the image into the browser (combined with the header).

like image 122
Shomz Avatar answered Sep 27 '22 20:09

Shomz


I don't know if someone was looking for this, but I needed to have a 600 x 600 squared image.

The source could be any rectangular image and I needed to mantain proportion of the original image and center the original rectangular image in a 600 x 600 squared white image.

Here it is

  • src_file: URL of Source Image
  • destination_file: Path where the destination file will be saved.
  • square_dimensions (pixels). I needed 600, but could be any value.
  • jpeg_quality: Quality (0, 100) . I used default 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);
    }
    
like image 43
Edu Avatar answered Sep 27 '22 21:09

Edu