Say I've got some square images which I want to resize to rectangle images with the ratio 16:9. What is the best way to do it using PHP?
you could use imagecopyresampled ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )
more at http://us2.php.net/imagecopyresampled
Try this... Not Using GD but i think it will work for u.
<?php
function Image($image, $crop = null, $size = null) {
$image = ImageCreateFromString(file_get_contents($image));
if (is_resource($image) === true) {
$x = 0;
$y = 0;
$width = imagesx($image);
$height = imagesy($image);
/*
CROP (Aspect Ratio) Section
*/
if (is_null($crop) === true) {
$crop = array($width, $height);
} else {
$crop = array_filter(explode(':', $crop));
if (empty($crop) === true) {
$crop = array($width, $height);
} else {
if ((empty($crop[0]) === true) || (is_numeric($crop[0]) === false)) {
$crop[0] = $crop[1];
} else if ((empty($crop[1]) === true) || (is_numeric($crop[1]) === false)) {
$crop[1] = $crop[0];
}
}
$ratio = array(0 => $width / $height, 1 => $crop[0] / $crop[1]);
if ($ratio[0] > $ratio[1]) {
$width = $height * $ratio[1];
$x = (imagesx($image) - $width) / 2;
}
else if ($ratio[0] < $ratio[1]) {
$height = $width / $ratio[1];
$y = (imagesy($image) - $height) / 2;
}
}
/*
Resize Section
*/
if (is_null($size) === true) {
$size = array($width, $height);
}
else {
$size = array_filter(explode('x', $size));
if (empty($size) === true) {
$size = array(imagesx($image), imagesy($image));
} else {
if ((empty($size[0]) === true) || (is_numeric($size[0]) === false)) {
$size[0] = round($size[1] * $width / $height);
} else if ((empty($size[1]) === true) || (is_numeric($size[1]) === false)) {
$size[1] = round($size[0] * $height / $width);
}
}
}
$result = ImageCreateTrueColor($size[0], $size[1]);
if (is_resource($result) === true) {
ImageSaveAlpha($result, true);
ImageAlphaBlending($result, true);
ImageFill($result, 0, 0, ImageColorAllocate($result, 255, 255, 255));
ImageCopyResampled($result, $image, 0, 0, $x, $y, $size[0], $size[1], $width, $height);
ImageInterlace($result, true);
ImageJPEG($result, null, 90);
}
}
return false;
}
header('Content-Type: image/jpeg');
Image('image.jpg', '2:1', '1200x');
?>
Related
I have image uploaded on the server in jpg format, everytime browser request a image if image not exist in webp i resize and conver image into webp format.
Since here everything work fine but new converted image (webp) is missing metadata like author, copyright, comment .... from original image.
Is there any way to add medatata from original image to converted (webp) image during resizing or converting ?
this is my code
$image = new Image(DIR_IMAGE . $old_image);
$image->resize($width, $height);
$image->save_webp(DIR_IMAGE . $new_image_webp, $quality);
public function resize($width = 0, $height = 0, $default = '') {
if (!$this->info['width'] || !$this->info['height']) {
return;
}
$xpos = 0;
$ypos = 0;
$scale = 1;
$scale_w = $width / $this->info['width'];
$scale_h = $height / $this->info['height'];
if ($default == 'w') {
$scale = $scale_w;
} elseif ($default == 'h') {
$scale = $scale_h;
} else {
$scale = min($scale_w, $scale_h);
}
if ($scale == 1 && $scale_h == $scale_w && $this->info['mime'] != 'image/png') {
return;
}
$new_width = (int)($this->info['width'] * $scale);
$new_height = (int)($this->info['height'] * $scale);
$xpos = (int)(($width - $new_width) / 2);
$ypos = (int)(($height - $new_height) / 2);
$image_old = $this->image;
$this->image = imagecreatetruecolor($width, $height);
if (isset($this->info['mime']) && $this->info['mime'] == 'image/png') {
imagealphablending($this->image, false);
imagesavealpha($this->image, true);
$background = imagecolorallocatealpha($this->image, 255, 255, 255, 127);
imagecolortransparent($this->image, $background);
} else {
$background = imagecolorallocate($this->image, 255, 255, 255);
}
imagefilledrectangle($this->image, 0, 0, $width, $height, $background);
imagecopyresampled($this->image, $image_old, $xpos, $ypos, 0, 0, $new_width, $new_height, $this->info['width'], $this->info['height']);
imagedestroy($image_old);
$this->info['width'] = $width;
$this->info['height'] = $height;
}
public function save_webp($file, $quality = 40) {
if (is_resource($this->image)) {
imagewebp($this->image, $file, $quality);
imagedestroy($this->image);
}
}
There is a system that reshapes images with php. I set the width value. I want it to get the height value automatically. In its current form, there is white space on the right side of some images. how can i lose this space. I want the height value to be scaled automatically.
public function resize(int $width = 0, int $height = 0, $default = '') {
if (!$this->width || !$this->height) {
return;
}
$xpos = 0;
$ypos = 0;
$scale = 1;
$scale_w = $width / $this->width;
$scale_h = 1;
if ($default == 'w') {
$scale = $scale_w;
} elseif ($default == 'h') {
$scale = $scale_h;
} else {
$scale = min($scale_w, $scale_h);
}
if ($scale == 1 && $scale_h == $scale_w && ($this->mime != 'image/png' && $this->mime != 'image/webp')) {
return;
}
$new_width = (int)($this->width * $scale);
$new_height = (int)($this->height * $scale);
$xpos = 0;
$ypos = 0;
$image_old = $this->image;
$this->image = imagecreatetruecolor($width, $new_height);
if ($this->mime == 'image/png') {
imagealphablending($this->image, false);
imagesavealpha($this->image, true);
$background = imagecolorallocatealpha($this->image, 255, 255, 255, 127);
imagecolortransparent($this->image, $background);
} else if ($this->mime == 'image/webp') {
imagealphablending($this->image, false);
imagesavealpha($this->image, true);
$background = imagecolorallocatealpha($this->image, 255, 255, 255, 127);
imagecolortransparent($this->image, $background);
} else {
$background = imagecolorallocate($this->image, 255, 255, 255);
}
imagefilledrectangle($this->image, 0, 0, $width, $new_height, $background);
imagecopyresampled($this->image, $image_old, $xpos, $ypos, 0, 0, $new_width, $new_height, $this->width, $this->height);
imagedestroy($image_old);
$this->width = $width;
$this->height = $new_height;
}
You are most likely missing the $default parameter, it should be 'w'.
As an example:
Let's say you have an image 128 x 128 and want to resize it to 256 (width), it should be scaled up to 256 x 256. The call looks like:
See how the resize scale is calculated:
$scale_w = $width / $this->width; // 256 / 128 = 2
$scale_h = 1;
if ($default == 'w') {
$scale = $scale_w; // = 2
} elseif ($default == 'h') {
$scale = $scale_h; // = 1
} else {
$scale = min($scale_w, $scale_h); // = 1
}
Without 'w' flag $scale becomes 1 and with 'w' flag it becomes 2 - the expected value.
Later on the algorithm uses $width several times instead of $new_width so the new image will be 256w x 128h instead of 128 x 128 due this line:
$this->image = imagecreatetruecolor($width, $new_height);
But imagecopyresampled uses $new_width so you end up with an 256w x 128h image, containing the original 128 x 128 image.
I am currently resizing an image to a custom with keeping aspect ratio:
class ImgResizer {
var $originalFile = '$newName';
function ImgResizer($originalFile = '$newName') {
$this -> originalFile = $originalFile;
}
function resize($newWidth, $targetFile) {
if (empty($newWidth) || empty($targetFile)) {
return false;
}
$src = imagecreatefromjpeg($this -> originalFile);
list($width, $height) = getimagesize($this -> originalFile);
$newHeight = ($height / $width) * $newWidth;
$tmp = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
if (file_exists($targetFile)) {
unlink($targetFile);
}
imagejpeg($tmp, $targetFile, 95);
}
}
Usage:
$work = new ImgResizer($path);
$work -> resize(200, $path);
But i would like to get a 200x200px version o the image. And it should be vertically amd horizontally centered ( basically get the main 200px of the image)
is that possible?
-EDIT-
function resize($newWidth, $targetFile) {
if (empty($newWidth) || empty($targetFile)) {
return false;
}
$src = imagecreatefromjpeg($this -> originalFile);
list($width, $height) = getimagesize($this -> originalFile);
$newHeight = $newWidth;
if ($width > $newWidth){
$srcx = $width/2 - $newWidth/2;
$destx = 0;
}
else{
$srcx = 0;
$destx = $newWidth/2 - $width/2;
}
if ($height > $newHeight){
$srcy = $height/2 - $newHeight/2;
$desty = 0;
}
else{
$srcy = 0;
$desty = $newHeight/2 - $height/2;
}
$tmp = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($tmp, $src, $destx, $desty, $srcx, $srcy, $newWidth, $newHeight, $width, $height);
if (file_exists($targetFile)) {
unlink($targetFile);
}
imagejpeg($tmp, $targetFile, 95);
}
Would create something unexpected: HTTP://209.51.221.243/integracion/files/uploads/1_050.JPG
Try
if ($width > $newWidth){
$srcx = $width/2 - $newWidth/2;
$destx = 0;
$w = $newWidth;
}
else{
$srcx = 0;
$destx = $newWidth/2 - $width/2;
$w = $width;
}
if ($height > $newHeight){
$srcy = $height/2 - $newHeight/2;
$desty = 0;
$h = $newHeight;
}
else{
$srcy = 0;
$desty = $newHeight/2 - $height/2;
$h = $keight;
}
imagecopyresampled($tmp, $src, $destx, $desty, $srcx, $srcy, $w, $h, $w, $h);
This question already has answers here:
Resize image in PHP
(13 answers)
Closed 6 years ago.
function resize($originalImage){
list($width, $height) = getimagesize($originalImage);
$newName=basename($originalImage);
$imageResized = imagecreatetruecolor(128, 128);
$imageTmp = imagecreatefromjpeg ($originalImage);
imagecopyresampled($imageResized, $imageTmp, 0, 0, 0, 0, 128, 128, $width, $height);
imagejpeg($imageResized, "resizedImg/$newName",100);
imageDestroy($imageResized);
}
The script returns the image with the correct name but it's just black? Any ideas?
If you have trouble with image resizing use this code for it. Do the modifications as you need it.
function resizeImage($file){
define ('MAX_WIDTH', 1500);//max image width
define ('MAX_HEIGHT', 1500);//max image height
define ('MAX_FILE_SIZE', 10485760);
//iamge save path
$path = 'storeResize/';
//size of the resize image
$new_width = 128;
$new_height = 128;
//name of the new image
$nameOfFile = 'resize_'.$new_width.'x'.$new_height.'_'.basename($file['name']);
$image_type = $file['type'];
$image_size = $file['size'];
$image_error = $file['error'];
$image_file = $file['tmp_name'];
$image_name = $file['name'];
$image_info = getimagesize($image_file);
//check image type
if ($image_info['mime'] == 'image/jpeg' or $image_info['mime'] == 'image/jpg'){
}
else if ($image_info['mime'] == 'image/png'){
}
else if ($image_info['mime'] == 'image/gif'){
}
else{
//set error invalid file type
}
if ($image_error){
//set error image upload error
}
if ( $image_size > MAX_FILE_SIZE ){
//set error image size invalid
}
switch ($image_info['mime']) {
case 'image/jpg': //This isn't a valid mime type so we should probably remove it
case 'image/jpeg':
$image = imagecreatefromjpeg ($image_file);
break;
case 'image/png':
$image = imagecreatefrompng ($image_file);
break;
case 'image/gif':
$image = imagecreatefromgif ($image_file);
break;
}
if ($new_width == 0 && $new_height == 0) {
$new_width = 100;
$new_height = 100;
}
// ensure size limits can not be abused
$new_width = min ($new_width, MAX_WIDTH);
$new_height = min ($new_height, MAX_HEIGHT);
//get original image h/w
$width = imagesx ($image);
$height = imagesy ($image);
//$align = 'b';
$zoom_crop = 1;
$origin_x = 0;
$origin_y = 0;
//TODO setting Memory
// generate new w/h if not provided
if ($new_width && !$new_height) {
$new_height = floor ($height * ($new_width / $width));
} else if ($new_height && !$new_width) {
$new_width = floor ($width * ($new_height / $height));
}
// scale down and add borders
if ($zoom_crop == 3) {
$final_height = $height * ($new_width / $width);
if ($final_height > $new_height) {
$new_width = $width * ($new_height / $height);
} else {
$new_height = $final_height;
}
}
// create a new true color image
$canvas = imagecreatetruecolor ($new_width, $new_height);
imagealphablending ($canvas, false);
if (strlen ($canvas_color) < 6) {
$canvas_color = 'ffffff';
}
$canvas_color_R = hexdec (substr ($canvas_color, 0, 2));
$canvas_color_G = hexdec (substr ($canvas_color, 2, 2));
$canvas_color_B = hexdec (substr ($canvas_color, 2, 2));
// Create a new transparent color for image
$color = imagecolorallocatealpha ($canvas, $canvas_color_R, $canvas_color_G, $canvas_color_B, 127);
// Completely fill the background of the new image with allocated color.
imagefill ($canvas, 0, 0, $color);
// scale down and add borders
if ($zoom_crop == 2) {
$final_height = $height * ($new_width / $width);
if ($final_height > $new_height) {
$origin_x = $new_width / 2;
$new_width = $width * ($new_height / $height);
$origin_x = round ($origin_x - ($new_width / 2));
} else {
$origin_y = $new_height / 2;
$new_height = $final_height;
$origin_y = round ($origin_y - ($new_height / 2));
}
}
// Restore transparency blending
imagesavealpha ($canvas, true);
if ($zoom_crop > 0) {
$src_x = $src_y = 0;
$src_w = $width;
$src_h = $height;
$cmp_x = $width / $new_width;
$cmp_y = $height / $new_height;
// calculate x or y coordinate and width or height of source
if ($cmp_x > $cmp_y) {
$src_w = round ($width / $cmp_x * $cmp_y);
$src_x = round (($width - ($width / $cmp_x * $cmp_y)) / 2);
} else if ($cmp_y > $cmp_x) {
$src_h = round ($height / $cmp_y * $cmp_x);
$src_y = round (($height - ($height / $cmp_y * $cmp_x)) / 2);
}
// positional cropping!
if ($align) {
if (strpos ($align, 't') !== false) {
$src_y = 0;
}
if (strpos ($align, 'b') !== false) {
$src_y = $height - $src_h;
}
if (strpos ($align, 'l') !== false) {
$src_x = 0;
}
if (strpos ($align, 'r') !== false) {
$src_x = $width - $src_w;
}
}
// positional cropping!
imagecopyresampled ($canvas, $image, $origin_x, $origin_y, $src_x, $src_y, $new_width, $new_height, $src_w, $src_h);
} else {
imagecopyresampled ($canvas, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
}
//Straight from Wordpress core code. Reduces filesize by up to 70% for PNG's
if ( (IMAGETYPE_PNG == $image_info[2] || IMAGETYPE_GIF == $image_info[2]) && function_exists('imageistruecolor') && !imageistruecolor( $image ) && imagecolortransparent( $image ) > 0 ){
imagetruecolortopalette( $canvas, false, imagecolorstotal( $image ) );
}
$quality = 100;
$nameOfFile = 'resize_'.$new_width.'x'.$new_height.'_'.basename($file['name']);
if (preg_match('/^image\/(?:jpg|jpeg)$/i', $image_info['mime'])){
imagejpeg($canvas, $path.$nameOfFile, $quality);
} else if (preg_match('/^image\/png$/i', $image_info['mime'])){
imagepng($canvas, $path.$nameOfFile, floor($quality * 0.09));
} else if (preg_match('/^image\/gif$/i', $image_info['mime'])){
imagegif($canvas, $path.$nameOfFile);
}
}
I've coded a function that crops an image to a given aspect ratio and finally then resizes it and outputs it as JPG:
<?php
function Image($image, $crop = null, $size = null)
{
$image = ImageCreateFromString(file_get_contents($image));
if (is_resource($image) === true)
{
$x = 0;
$y = 0;
$width = imagesx($image);
$height = imagesy($image);
/*
CROP (Aspect Ratio) Section
*/
if (is_null($crop) === true)
{
$crop = array($width, $height);
}
else
{
$crop = array_filter(explode(':', $crop));
if (empty($crop) === true)
{
$crop = array($width, $height);
}
else
{
if ((empty($crop[0]) === true) || (is_numeric($crop[0]) === false))
{
$crop[0] = $crop[1];
}
else if ((empty($crop[1]) === true) || (is_numeric($crop[1]) === false))
{
$crop[1] = $crop[0];
}
}
$ratio = array
(
0 => $width / $height,
1 => $crop[0] / $crop[1],
);
if ($ratio[0] > $ratio[1])
{
$width = $height * $ratio[1];
$x = (imagesx($image) - $width) / 2;
}
else if ($ratio[0] < $ratio[1])
{
$height = $width / $ratio[1];
$y = (imagesy($image) - $height) / 2;
}
/*
How can I skip (join) this operation
with the one in the Resize Section?
*/
$result = ImageCreateTrueColor($width, $height);
if (is_resource($result) === true)
{
ImageSaveAlpha($result, true);
ImageAlphaBlending($result, false);
ImageFill($result, 0, 0, ImageColorAllocateAlpha($result, 255, 255, 255, 127));
ImageCopyResampled($result, $image, 0, 0, $x, $y, $width, $height, $width, $height);
$image = $result;
}
}
/*
Resize Section
*/
if (is_null($size) === true)
{
$size = array(imagesx($image), imagesy($image));
}
else
{
$size = array_filter(explode('x', $size));
if (empty($size) === true)
{
$size = array(imagesx($image), imagesy($image));
}
else
{
if ((empty($size[0]) === true) || (is_numeric($size[0]) === false))
{
$size[0] = round($size[1] * imagesx($image) / imagesy($image));
}
else if ((empty($size[1]) === true) || (is_numeric($size[1]) === false))
{
$size[1] = round($size[0] * imagesy($image) / imagesx($image));
}
}
}
$result = ImageCreateTrueColor($size[0], $size[1]);
if (is_resource($result) === true)
{
ImageSaveAlpha($result, true);
ImageAlphaBlending($result, true);
ImageFill($result, 0, 0, ImageColorAllocate($result, 255, 255, 255));
ImageCopyResampled($result, $image, 0, 0, 0, 0, $size[0], $size[1], imagesx($image), imagesy($image));
header('Content-Type: image/jpeg');
ImageInterlace($result, true);
ImageJPEG($result, null, 90);
}
}
return false;
}
?>
The function works as expected but I'm creating a non-required GD image resource, how can I fix it? I've tried joining both calls but I must be doing some miscalculations.
<?php
/*
Usage Examples
*/
Image('http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png', '1:1', '600x');
Image('http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png', '2:1', '600x');
Image('http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png', '2:', '250x300');
?>
Any help is greatly appreciated, thanks.
You will have to modify your resizing code not to be based on the cropped image to start with. Since you want to do the cropping and resizing in one go you need to calculate it independently.
<?php
function Image($image, $crop = ':', $size = null) {
$image = ImageCreateFromString(file_get_contents($image));
if (is_resource($image)) {
$x = 0;
$y = 0;
$width = imagesx($image);
$height = imagesy($image);
// CROP (Aspect Ratio) Section
$crop = array_filter(explode(':', $crop));
if (empty($crop)) {
$crop = [$width, $height];
} else {
$crop[0] = $crop[0] ?: $crop[1];
$crop[1] = $crop[1] ?: $crop[0];
}
$ratio = [$width / $height, $crop[0] / $crop[1]];
if ($ratio[0] > $ratio[1]) {
$width = $height * $ratio[1];
$x = (imagesx($image) - $width) / 2;
} else {
$height = $width / $ratio[1];
$y = (imagesy($image) - $height) / 2;
}
// Resize Section
if (is_null($size)) {
$size = [$width, $height];
} else {
$size = array_filter(explode('x', $size));
if (empty($size)) {
$size = [imagesx($image), imagesy($image)];
} else {
$size[0] = $size[0] ?: round($size[1] * $width / $height);
$size[1] = $size[1] ?: round($size[0] * $height / $width);
}
}
$result = ImageCreateTrueColor($size[0], $size[1]);
if (is_resource($result)) {
ImageSaveAlpha($result, true);
ImageAlphaBlending($result, true);
ImageFill($result, 0, 0, ImageColorAllocate($result, 255, 255, 255));
ImageCopyResampled($result, $image, 0, 0, $x, $y, $size[0], $size[1], $width, $height);
ImageInterlace($result, true);
ImageJPEG($result, null, 90);
}
}
return false;
}
header('Content-Type: image/jpeg');
Image('http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png', '1:1', '600x');
?>