PHP - Create thumbnail maintaining aspect ratio & remove blank portion? - php

I am using a function from this question
PHP - Create Thumbnail & maintaining aspect ratio
The code is as below,
define('THUMBNAIL_IMAGE_MAX_WIDTH', 150);
define('THUMBNAIL_IMAGE_MAX_HEIGHT', 150);
function generate_image_thumbnail($source_image_path, $thumbnail_image_path)
{
list($source_image_width, $source_image_height, $source_image_type) = getimagesize($source_image_path);
switch ($source_image_type) {
case IMAGETYPE_GIF:
$source_gd_image = imagecreatefromgif($source_image_path);
break;
case IMAGETYPE_JPEG:
$source_gd_image = imagecreatefromjpeg($source_image_path);
break;
case IMAGETYPE_PNG:
$source_gd_image = imagecreatefrompng($source_image_path);
break;
}
if ($source_gd_image === false) {
return false;
}
$source_aspect_ratio = $source_image_width / $source_image_height;
$thumbnail_aspect_ratio = THUMBNAIL_IMAGE_MAX_WIDTH / THUMBNAIL_IMAGE_MAX_HEIGHT;
if ($source_image_width <= THUMBNAIL_IMAGE_MAX_WIDTH && $source_image_height <= THUMBNAIL_IMAGE_MAX_HEIGHT) {
$thumbnail_image_width = $source_image_width;
$thumbnail_image_height = $source_image_height;
} elseif ($thumbnail_aspect_ratio > $source_aspect_ratio) {
$thumbnail_image_width = (int) (THUMBNAIL_IMAGE_MAX_HEIGHT * $source_aspect_ratio);
$thumbnail_image_height = THUMBNAIL_IMAGE_MAX_HEIGHT;
} else {
$thumbnail_image_width = THUMBNAIL_IMAGE_MAX_WIDTH;
$thumbnail_image_height = (int) (THUMBNAIL_IMAGE_MAX_WIDTH / $source_aspect_ratio);
}
$thumbnail_gd_image = imagecreatetruecolor($thumbnail_image_width, $thumbnail_image_height);
imagecopyresampled($thumbnail_gd_image, $source_gd_image, 0, 0, 0, 0, $thumbnail_image_width, $thumbnail_image_height, $source_image_width, $source_image_height);
$img_disp = imagecreatetruecolor(THUMBNAIL_IMAGE_MAX_WIDTH,THUMBNAIL_IMAGE_MAX_HEIGHT);
$backcolor = imagecolorallocate($img_disp,0,0,0);
imagefill($img_disp,0,0,$backcolor);
imagecopy($img_disp, $thumbnail_gd_image, (imagesx($img_disp)/2)-(imagesx($thumbnail_gd_image)/2), (imagesy($img_disp)/2)-(imagesy($thumbnail_gd_image)/2), 0, 0, imagesx($thumbnail_gd_image), imagesy($thumbnail_gd_image));
imagejpeg($img_disp, $thumbnail_image_path, 90);
imagedestroy($source_gd_image);
imagedestroy($thumbnail_gd_image);
imagedestroy($img_disp);
return true;
}
It works well and will create thumbnail like this
I notice that the function will fill unused portion with black color
imagefill($img_disp,0,0,$backcolor);
How could I remove the black portion instead? I don't need fix width or height.

Maybe the easiest way is to preserve the aspect ratio.
// RESIZE AN IMAGE PROPORTIONALLY AND CROP TO THE CENTER
function resize_and_crop($original_image_url, $thumb_image_url, $thumb_w, $thumb_h, $quality=75)
{
// ACQUIRE THE ORIGINAL IMAGE: http://php.net/manual/en/function.imagecreatefromjpeg.php
$original = imagecreatefromjpeg($original_image_url);
if (!$original) return FALSE;
// GET ORIGINAL IMAGE DIMENSIONS
list($original_w, $original_h) = getimagesize($original_image_url);
// RESIZE IMAGE AND PRESERVE PROPORTIONS
$thumb_w_resize = $thumb_w;
$thumb_h_resize = $thumb_h;
if ($original_w > $original_h)
{
$thumb_h_ratio = $thumb_h / $original_h;
$thumb_w_resize = (int)round($original_w * $thumb_h_ratio);
}
else
{
$thumb_w_ratio = $thumb_w / $original_w;
$thumb_h_resize = (int)round($original_h * $thumb_w_ratio);
}
if ($thumb_w_resize < $thumb_w)
{
$thumb_h_ratio = $thumb_w / $thumb_w_resize;
$thumb_h_resize = (int)round($thumb_h * $thumb_h_ratio);
$thumb_w_resize = $thumb_w;
}
// CREATE THE PROPORTIONAL IMAGE RESOURCE
$thumb = imagecreatetruecolor($thumb_w_resize, $thumb_h_resize);
if (!imagecopyresampled($thumb, $original, 0,0,0,0, $thumb_w_resize, $thumb_h_resize, $original_w, $original_h)) return FALSE;
// ACTIVATE THIS TO STORE THE INTERMEDIATE IMAGE
// imagejpeg($thumb, 'thumbs/temp_' . $thumb_w_resize . 'x' . $thumb_h_resize . '.jpg', 100);
// CREATE THE CENTERED CROPPED IMAGE TO THE SPECIFIED DIMENSIONS
$final = imagecreatetruecolor($thumb_w, $thumb_h);
$thumb_w_offset = 0;
$thumb_h_offset = 0;
if ($thumb_w < $thumb_w_resize)
{
$thumb_w_offset = (int)round(($thumb_w_resize - $thumb_w) / 2);
}
else
{
$thumb_h_offset = (int)round(($thumb_h_resize - $thumb_h) / 2);
}
if (!imagecopy($final, $thumb, 0,0, $thumb_w_offset, $thumb_h_offset, $thumb_w_resize, $thumb_h_resize)) return FALSE;
// STORE THE FINAL IMAGE - WILL OVERWRITE $thumb_image_url
if (!imagejpeg($final, $thumb_image_url, $quality)) return FALSE;
return TRUE;
}
// USE CASE
echo '<a target="_blank" href="images/image_600x374.jpg">Original 600x374</a><br/>';
resize_and_crop('images/image_600x374.jpg', 'thumbs/temp_100x100.jpg', 100, 100);
echo '<a target="_blank" href="thumbs/temp_100x100.jpg">100x100</a><br/>';
resize_and_crop('images/image_600x374.jpg', 'thumbs/temp_200x100.jpg', 200, 100);
echo '<a target="_blank" href="thumbs/temp_200x100.jpg">200x100</a><br/>';
resize_and_crop('images/image_600x374.jpg', 'thumbs/temp_200x300.jpg', 200, 300);
echo '<a target="_blank" href="thumbs/temp_200x300.jpg">200x300</a><br/>';

Related

Optimal image scaling

I would like to ask for help in optimizing the image. I made a class where I call the function, working perfectly, just when I upload my profile picture I want to cut it into a square (800x800) and make it as optimal as possible from the center of the original picture. I don't want to use extra scripts, rather upload an optimally cropped image.
Imagecopyresampled proper parameter drop is the key :), I googled and watched videos but couldn't fix it properly or it either shifted the image or it wasn't in or distorted. I probably miscalculated the coordinates of the image.
function createthumb($name, $filename, $new_w, $new_h) {
try{
$system = explode(".", $name);
$tipus = $system[count($system)-1];
$tipus = strtolower($tipus);
$vizjel_fajl = "assets/img/watermark.png";
$vizjel_kep = imagecreatefrompng($vizjel_fajl);
if (($tipus == 'jpg') || ($tipus == 'jpeg')){
$src_img = imagecreatefromjpeg($name);
}
if ($tipus == 'gif'){
$src_img = imagecreatefromgif($name);
}
if ($tipus == 'png'){
$src_img = imagecreatefrompng($name);
}
$old_x = imageSX($src_img);
$old_y = imageSY($src_img);
$vizjel_szelesseg = imagesx($vizjel_kep);
$vizjel_magassag = imagesy($vizjel_kep);
$szelesseg_szorzo = $old_x / $vizjel_szelesseg;
$magassag_szorzo = $old_y / $vizjel_magassag;
if (($szelesseg_szorzo) >= ($magassag_szorzo)){
$aktual_szorzo = $magassag_szorzo;
} else {
$aktual_szorzo = $szelesseg_szorzo;
}
$vizjel_x = intval(($old_x - ($aktual_szorzo * $vizjel_szelesseg)) / 3);
$vizjel_y = intval(($old_y - ($aktual_szorzo * $vizjel_magassag)) / 1);
$vizjel_w = intval($aktual_szorzo * $vizjel_szelesseg);
$vizjel_h = intval($aktual_szorzo * $vizjel_magassag);
if($old_x > $old_y && $this->type != 'user'){
$thumb_w = $new_w;
$thumb_h = $old_y * ($new_h / $old_x);
}
if($old_x < $old_y && $this->type != 'user') {
$thumb_w = $old_x * ($new_w / $old_y);
$thumb_h = $new_h;
}
if($old_x == $old_y){
$thumb_w = $new_w;
$thumb_h = $new_h;
}
if($this->type == 'user'){
$thumb_w = 800;
$thumb_h = 800;
}
$dst_img = ImageCreateTrueColor($thumb_w, $thumb_h);
imagealphablending($dst_img, false);
imagesavealpha($dst_img, true);
$transparent = imagecolorallocatealpha($dst_img, 0, 0, 0, 127);
imagefilledrectangle($dst_img, 0, 0, $thumb_w, $thumb_h, $transparent);
imagecopyresampled($src_img, $vizjel_kep, $vizjel_x, $vizjel_y, 0, 0, $vizjel_w, $vizjel_h, $vizjel_szelesseg, $vizjel_magassag);
imagecopyresampled( $dst_img, $src_img, 0, 0, 0, 0, $thumb_w, $thumb_h, $old_x, $old_y );
if ((preg_match( "/png/", $system[1])) || (preg_match("/gif/", $system[1]))){
imagepng($dst_img, $filename, 1);
}else{
imagejpeg($dst_img, $filename);
}
imagedestroy($dst_img);
if (!unlink($this->target_dir.$this->name)) {
throw new userException('','Hiba a törlés során ->'. $this->name,451);
}
}
catch (userException $e){
$e->handleException();
}
}
Welcome LGB,
your function is not clear, I see some variables that not defined, please next time attach all of the codes.
this code returns exactly the center of the original image 800x800
<?php
//image path
$im = imagecreatefromjpeg('Images/baby.jpg');
// find the size of image
$size = min(imagesx($im), imagesy($im));
//calculate X position
if(imagesx($im) < 800){$xPos = 0;}
else{$xPos = floor((imagesx($im) - 800) / 2);}
//calculate Y position
if(imagesy($im) < 800){$yPos = 0;}
else{$yPos = floor((imagesy($im) - 800) / 2);}
//set the crop image size
$im2 = imagecrop($im, ['x' => $xPos, 'y' => $yPos, 'width' => 800, 'height' => 800]);
if ($im2 !== FALSE) {
header("Content-type: image/jpg");
imagejpeg($im2);
imagedestroy($im2);
}
imagedestroy($im);
?>
I'm guessing that your point is in this part:
//calculate X position
if(imagesx($im) < 800){$xPos = 0;}
else{$xPos = floor((imagesx($im) - 800) / 2);}
//calculate Y position
if(imagesy($im) < 800){$yPos = 0;}
else{$yPos = floor((imagesy($im) - 800) / 2);}

GD library upload image rotation

I use GD library to upload / process photos, but when uploading a photo via Android or some mobile phone, photos are not uploaded correctly as an orientation. I have a site where users can upload photos from mobile, but all the photos that are uploaded from mobiles, show 90 degrees to the left when upload.
I now the problem is the exeif but i tried using a plugin but is not working. Any help is recommended.
Share my script code is:
CImageHandler.php
/**
* Image handler
* #author Yaroslav Pelesh aka Tokolist http://tokolist.com
* #link https://github.com/tokolist/yii-components
* #version 1.2
* #license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
ini_set('memory_limit', '8192M');
class CImageHandler extends CApplicationComponent
{
private $originalImage = null;
private $image = null;
private $format = 0;
private $width = 0;
private $height = 0;
private $mimeType = '';
private $fileName = '';
public $transparencyColor = [0, 0, 0];
const IMG_GIF = 1;
const IMG_JPEG = 2;
const IMG_PNG = 3;
const CORNER_LEFT_TOP = 1;
const CORNER_RIGHT_TOP = 2;
const CORNER_LEFT_BOTTOM = 3;
const CORNER_RIGHT_BOTTOM = 4;
const CORNER_CENTER = 5;
const CORNER_CENTER_TOP = 6;
const CORNER_CENTER_BOTTOM = 7;
const CORNER_LEFT_CENTER = 8;
const CORNER_RIGHT_CENTER = 9;
const FLIP_HORIZONTAL = 1;
const FLIP_VERTICAL = 2;
const FLIP_BOTH = 3;
public function getImage()
{
return $this->image;
}
public function getFormat()
{
return $this->format;
}
public function getWidth()
{
return $this->width;
}
public function getHeight()
{
return $this->height;
}
public function getMimeType()
{
return $this->mimeType;
}
public function __destruct()
{
$this->freeImage();
}
private function freeImage()
{
if (is_resource($this->image)) {
imagedestroy($this->image);
}
if ($this->originalImage !== null) {
if (is_resource($this->originalImage['image'])) {
imagedestroy($this->originalImage['image']);
}
$this->originalImage = null;
}
}
private function checkLoaded()
{
if (!is_resource($this->image)) {
throw new Exception('Load image first');
}
}
private function loadImage($file)
{
$result = [];
if ($imageInfo = #getimagesize($file)) {
$result['width'] = $imageInfo[0];
$result['height'] = $imageInfo[1];
$result['mimeType'] = $imageInfo['mime'];
switch ($result['format'] = $imageInfo[2]) {
case self::IMG_GIF:
if(file_exists($file)) {
$gd = #imagecreatefromstring(file_get_contents($file));
if ($gd === false) {
throw new Exception ('Invalid image gif format');
} else {
if ($result['image'] = imagecreatefromgif($file)) {
return $result;
} else {
throw new Exception('Invalid image gif format');
}
}
} else {
throw new Exception('Invalid image gif format');
}
break;
case self::IMG_JPEG:
if(file_exists($file)) {
$gd = #imagecreatefromstring(file_get_contents($file));
if ($gd === false) {
throw new Exception ('Invalid image jpeg format');
} else {
/*
//Read the JPEG image Exif data to get the Orientation value
if (function_exists('exif_read_data')) {
$exif = exif_read_data($file);
$orientation = #$exif['IFD0']['Orientation'];
if (!$orientation) {
$orientation = #$exif['Orientation'];
}
if(!$orientation) return;
$source = #imagecreatefromjpeg($file);
if(!$source) return;
switch ($orientation) {
case 1: // nothing
break;
case 2: // horizontal flip
imageflip($source, IMG_FLIP_HORIZONTAL);
break;
case 3: // 180 rotate left
$modifiedImage = imagerotate($source, 180, 0);
imagejpeg($modifiedImage, $file, 90); //save output to file system at full quality
break;
case 4: // vertical flip
imageflip($source, IMG_FLIP_VERTICAL);
break;
case 5: // vertical flip + 90 rotate right
imageflip($source, IMG_FLIP_VERTICAL);
$modifiedImage = imagerotate($source, -90, 0);
imagejpeg($modifiedImage, $file, 90); //save output to file system at full quality
break;
case 6: // 90 rotate right
$modifiedImage = imagerotate($source, -90, 0);
imagejpeg($modifiedImage, $file, 90); //save output to file system at full quality
break;
case 7: // horizontal flip + 90 rotate right
imageflip($source, IMG_FLIP_HORIZONTAL);
$modifiedImage = imagerotate($source, -90, 0);
imagejpeg($modifiedImage, $file, 90); //save output to file system at full quality
break;
case 8: // 90 rotate left
$modifiedImage = imagerotate($source, 90, 0);
imagejpeg($modifiedImage, $file, 90); //save output to file system at full quality
break;
}
}
//Read the JPEG image Exif data to get the Orientation value
*/
if ($result['image'] = #imagecreatefromjpeg($file)) {
return $result;
} else {
throw new Exception('Invalid image jpeg format');
}
}
} else {
throw new Exception('Invalid image jpeg format');
}
break;
case self::IMG_PNG:
if(file_exists($file)) {
$gd = #imagecreatefromstring(file_get_contents($file));
if ($gd === false) {
throw new Exception ('Invalid image png format');
} else {
if ($result['image'] = imagecreatefrompng($file)) {
return $result;
} else {
throw new Exception('Invalid image png format');
}
}
} else {
throw new Exception('Invalid image png format');
}
break;
default:
throw new Exception('Not supported image format');
}
} else {
throw new Exception('Invalid image file');
}
}
protected function initImage($image = false)
{
if ($image === false) {
$image = $this->originalImage;
}
$this->width = $image['width'];
$this->height = $image['height'];
$this->mimeType = $image['mimeType'];
$this->format = $image['format'];
//Image
if (is_resource($this->image))
imagedestroy($this->image);
//10-08-2018
$this->image = imagecreatetruecolor($this->width, $this->height);
$this->preserveTransparency($this->image);
imagecopy($this->image, $image['image'], 0, 0, 0, 0, $this->width, $this->height);
}
/**
* #param $file
*
* #return CImageHandler
* #throws Exception
*/
public function load($file)
{
$this->freeImage();
if (($this->originalImage = $this->loadImage($file))) {
$this->initImage();
$this->fileName = $file;
return $this;
} else {
return false;
}
}
public function reload()
{
$this->checkLoaded();
$this->initImage();
return $this;
}
private function preserveTransparency($newImage)
{
switch ($this->format) {
case self::IMG_GIF:
$color = imagecolorallocate(
$newImage,
$this->transparencyColor[0],
$this->transparencyColor[1],
$this->transparencyColor[2]
);
imagecolortransparent($newImage, $color);
imagetruecolortopalette($newImage, false, 256);
break;
case self::IMG_PNG:
imagealphablending($newImage, false);
$color = imagecolorallocatealpha(
$newImage,
$this->transparencyColor[0],
$this->transparencyColor[1],
$this->transparencyColor[2],
0
);
imagefill($newImage, 0, 0, $color);
imagesavealpha($newImage, true);
break;
}
}
public function resize($toWidth, $toHeight, $proportional = true)
{
$this->checkLoaded();
$toWidth = $toWidth !== false ? $toWidth : $this->width;
$toHeight = $toHeight !== false ? $toHeight : $this->height;
if ($proportional) {
$newHeight = $toHeight;
$newWidth = round($newHeight / $this->height * $this->width);
if ($newWidth > $toWidth) {
$newWidth = $toWidth;
$newHeight = round($newWidth / $this->width * $this->height);
}
} else {
$newWidth = $toWidth;
$newHeight = $toHeight;
}
$newImage = imagecreatetruecolor($newWidth, $newHeight);
$this->preserveTransparency($newImage);
imagecopyresampled($newImage, $this->image, 0, 0, 0, 0, $newWidth, $newHeight, $this->width, $this->height);
imagedestroy($this->image);
$this->image = $newImage;
$this->width = $newWidth;
$this->height = $newHeight;
return $this;
}
public function thumb($toWidth, $toHeight, $proportional = true)
{
$this->checkLoaded();
if ($toWidth !== false)
$toWidth = min($toWidth, $this->width);
if ($toHeight !== false)
$toHeight = min($toHeight, $this->height);
$this->resize($toWidth, $toHeight, $proportional);
return $this;
}
public function watermark($watermarkFile, $offsetX, $offsetY, $corner = self::CORNER_RIGHT_BOTTOM, $zoom = false)
{
$this->checkLoaded();
if ($wImg = $this->loadImage($watermarkFile)) {
$posX = 0;
$posY = 0;
$watermarkWidth = $wImg['width'];
$watermarkHeight = $wImg['height'];
if ($zoom !== false) {
$dimension = round(max($this->width, $this->height) * $zoom);
$watermarkHeight = $dimension;
$watermarkWidth = round($watermarkHeight / $wImg['height'] * $wImg['width']);
if ($watermarkWidth > $dimension) {
$watermarkWidth = $dimension;
$watermarkHeight = round($watermarkWidth / $wImg['width'] * $wImg['height']);
}
}
switch ($corner) {
case self::CORNER_LEFT_TOP:
$posX = $offsetX;
$posY = $offsetY;
break;
case self::CORNER_RIGHT_TOP:
$posX = $this->width - $watermarkWidth - $offsetX;
$posY = $offsetY;
break;
case self::CORNER_LEFT_BOTTOM:
$posX = $offsetX;
$posY = $this->height - $watermarkHeight - $offsetY;
break;
case self::CORNER_RIGHT_BOTTOM:
$posX = $this->width - $watermarkWidth - $offsetX;
$posY = $this->height - $watermarkHeight - $offsetY;
break;
case self::CORNER_CENTER:
$posX = floor(($this->width - $watermarkWidth) / 2);
$posY = floor(($this->height - $watermarkHeight) / 2);
break;
case self::CORNER_CENTER_TOP:
$posX = floor(($this->width - $watermarkWidth) / 2);
$posY = $offsetY;
break;
case self::CORNER_CENTER_BOTTOM:
$posX = floor(($this->width - $watermarkWidth) / 2);
$posY = $this->height - $watermarkHeight - $offsetY;
break;
case self::CORNER_LEFT_CENTER:
$posX = $offsetX;
$posY = floor(($this->height - $watermarkHeight) / 2);
break;
case self::CORNER_RIGHT_CENTER:
$posX = $this->width - $watermarkWidth - $offsetX;
$posY = floor(($this->height - $watermarkHeight) / 2);
break;
default:
throw new Exception('Invalid $corner value');
}
imagecopyresampled(
$this->image,
$wImg['image'],
$posX,
$posY,
0,
0,
$watermarkWidth,
$watermarkHeight,
$wImg['width'],
$wImg['height']
);
imagedestroy($wImg['image']);
return $this;
} else {
return false;
}
}
public function flip($mode)
{
$this->checkLoaded();
$srcX = 0;
$srcY = 0;
$srcWidth = $this->width;
$srcHeight = $this->height;
switch ($mode) {
case self::FLIP_HORIZONTAL:
$srcX = $this->width - 1;
$srcWidth = -$this->width;
break;
case self::FLIP_VERTICAL:
$srcY = $this->height - 1;
$srcHeight = -$this->height;
break;
case self::FLIP_BOTH:
$srcX = $this->width - 1;
$srcY = $this->height - 1;
$srcWidth = -$this->width;
$srcHeight = -$this->height;
break;
default:
throw new Exception('Invalid $mode value');
}
$newImage = imagecreatetruecolor($this->width, $this->height);
$this->preserveTransparency($newImage);
imagecopyresampled($newImage, $this->image, 0, 0, $srcX, $srcY, $this->width, $this->height, $srcWidth, $srcHeight);
imagedestroy($this->image);
$this->image = $newImage;
//dimensions not changed
return $this;
}
public function rotate($degrees)
{
$this->checkLoaded();
$degrees = (int)$degrees;
$this->image = imagerotate($this->image, $degrees, 0);
$this->width = imagesx($this->image);
$this->height = imagesy($this->image);
return $this;
}
public function crop($width, $height, $startX = false, $startY = false)
{
$this->checkLoaded();
$width = (int)$width;
$height = (int)$height;
//Centered crop
$startX = $startX === false ? floor(($this->width - $width) / 2) : intval($startX);
$startY = $startY === false ? floor(($this->height - $height) / 2) : intval($startY);
//Check dimensions
$startX = max(0, min($this->width, $startX));
$startY = max(0, min($this->height, $startY));
$width = min($width, $this->width - $startX);
$height = min($height, $this->height - $startY);
$newImage = imagecreatetruecolor($width, $height);
$this->preserveTransparency($newImage);
imagecopyresampled($newImage, $this->image, 0, 0, $startX, $startY, $width, $height, $width, $height);
imagedestroy($this->image);
$this->image = $newImage;
$this->width = $width;
$this->height = $height;
return $this;
}
public function text($text, $fontFile, $size = 12, $color = [0, 0, 0],
$corner = self::CORNER_LEFT_TOP, $offsetX = 0, $offsetY = 0, $angle = 0, $alpha = 0)
{
$this->checkLoaded();
$bBox = imagettfbbox($size, $angle, $fontFile, $text);
$textHeight = $bBox[1] - $bBox[7];
$textWidth = $bBox[2] - $bBox[0];
switch ($corner) {
case self::CORNER_LEFT_TOP:
$posX = $offsetX;
$posY = $offsetY;
break;
case self::CORNER_RIGHT_TOP:
$posX = $this->width - $textWidth - $offsetX;
$posY = $offsetY;
break;
case self::CORNER_LEFT_BOTTOM:
$posX = $offsetX;
$posY = $this->height - $textHeight - $offsetY;
break;
case self::CORNER_RIGHT_BOTTOM:
$posX = $this->width - $textWidth - $offsetX;
$posY = $this->height - $textHeight - $offsetY;
break;
case self::CORNER_CENTER:
$posX = floor(($this->width - $textWidth) / 2);
$posY = floor(($this->height - $textHeight) / 2);
break;
case self::CORNER_CENTER_TOP:
$posX = floor(($this->width - $textWidth) / 2);
$posY = $offsetY;
break;
case self::CORNER_CENTER_BOTTOM:
$posX = floor(($this->width - $textWidth) / 2);
$posY = $this->height - $textHeight - $offsetY;
break;
case self::CORNER_LEFT_CENTER:
$posX = $offsetX;
$posY = floor(($this->height - $textHeight) / 2);
break;
case self::CORNER_RIGHT_CENTER:
$posX = $this->width - $textWidth - $offsetX;
$posY = floor(($this->height - $textHeight) / 2);
break;
default:
throw new Exception('Invalid $corner value');
}
if ($alpha > 0) {
$color = imagecolorallocatealpha($this->image, $color[0], $color[1], $color[2], $alpha);
} else {
$color = imagecolorallocate($this->image, $color[0], $color[1], $color[2]);
}
imagettftext($this->image, $size, $angle, $posX, $posY + $textHeight, $color, $fontFile, $text);
return $this;
}
public function adaptiveThumb($width, $height)
{
$this->checkLoaded();
$width = intval($width);
$height = intval($height);
$widthProportion = $width / $this->width;
$heightProportion = $height / $this->height;
if ($widthProportion > $heightProportion) {
$newWidth = $width;
$newHeight = round($newWidth / $this->width * $this->height);
} else {
$newHeight = $height;
$newWidth = round($newHeight / $this->height * $this->width);
}
$this->resize($newWidth, $newHeight);
$this->crop($width, $height);
return $this;
}
public function resizeCanvas($toWidth, $toHeight, $backgroundColor = [255, 255, 255])
{
$this->checkLoaded();
$newWidth = min($toWidth, $this->width);
$newHeight = min($toHeight, $this->height);
$widthProportion = $newWidth / $this->width;
$heightProportion = $newHeight / $this->height;
if ($widthProportion < $heightProportion) {
$newHeight = round($widthProportion * $this->height);
} else {
$newWidth = round($heightProportion * $this->width);
}
$posX = floor(($toWidth - $newWidth) / 2);
$posY = floor(($toHeight - $newHeight) / 2);
$newImage = imagecreatetruecolor($toWidth, $toHeight);
$backgroundColor = imagecolorallocate($newImage, $backgroundColor[0], $backgroundColor[1], $backgroundColor[2]);
imagefill($newImage, 0, 0, $backgroundColor);
imagecopyresampled($newImage, $this->image, $posX, $posY, 0, 0, $newWidth, $newHeight, $this->width, $this->height);
imagedestroy($this->image);
$this->image = $newImage;
$this->width = $toWidth;
$this->height = $toHeight;
return $this;
}
public function grayscale()
{
$newImage = imagecreatetruecolor($this->width, $this->height);
imagecopy($newImage, $this->image, 0, 0, 0, 0, $this->width, $this->height);
imagecopymergegray($newImage, $newImage, 0, 0, 0, 0, $this->width, $this->height, 0);
imagedestroy($this->image);
$this->image = $newImage;
return $this;
}
public function show($inFormat = false, $jpegQuality = 75)
{
$this->checkLoaded();
if (!$inFormat) {
$inFormat = $this->format;
}
switch ($inFormat) {
case self::IMG_GIF:
header('Content-type: image/gif');
imagegif($this->image);
break;
case self::IMG_JPEG:
header('Content-type: image/jpeg');
imagejpeg($this->image, null, $jpegQuality);
break;
case self::IMG_PNG:
header('Content-type: image/png');
imagepng($this->image);
break;
default:
throw new Exception('Invalid image format for putput');
}
return $this;
}
public function save($file = false, $toFormat = false, $jpegQuality = 75, $touch = false)
{
if (empty($file)) {
$file = $this->fileName;
}
$this->checkLoaded();
if (!$toFormat) {
$toFormat = $this->format;
}
switch ($toFormat) {
case self::IMG_GIF:
if (!imagegif($this->image, $file)) {
throw new Exception('Can\'t save gif file');
}
break;
case self::IMG_JPEG:
if (!imagejpeg($this->image, $file, $jpegQuality)) {
throw new Exception('Can\'t save jpeg file');
}
break;
case self::IMG_PNG:
if (!imagepng($this->image, $file)) {
throw new Exception('Can\'t save png file');
}
break;
default:
throw new Exception('Invalid image format for save');
}
if ($touch && $file != $this->fileName) {
touch($file, filemtime($this->fileName));
}
return $this;
}
}
Thank you #Yanik Lupien your simple code is very nice work :)
if (function_exists('exif_read_data')) {
$buffer = imagecreatefromjpeg($file);
$exif = #exif_read_data($file);
if ($exif && !empty($exif['Orientation']))
{
switch($exif['Orientation']) {
case 8:
$buffer = imagerotate($buffer, 90, 0);
break;
case 3:
$buffer = imagerotate($buffer, 180, 0);
break;
case 6:
$buffer = imagerotate($buffer, -90, 0);
break;
case 5: // vertical flip + 90 rotate right
$buffer = imagerotate($buffer, -90, 0);
break;
case 7: // horizontal flip + 90 rotate right
$buffer = imagerotate($buffer, -90, 0);
break;
}
}
imagejpeg($buffer, $file, 90);
}
Here is a small snippet to fix rotation.
$imagePathName = 'file.jpg';
$buffer = ImageCreateFromJPEG($imagePathName);
$exif = #exif_read_data($imagePathName);
if ($exif && !empty($exif['Orientation']))
{
switch($exif['Orientation']) {
case 8:
$buffer = imagerotate($buffer, 90, 0);
break;
case 3:
$buffer = imagerotate($buffer, 180, 0);
break;
case 6:
$buffer = imagerotate($buffer, -90, 0);
break;
}
}
imagejpeg($buffer, $imagePathName, 90);

Create square 1:1 thumbnail in PHP

How can I set this code to return images in 1:1 (square)?
The purpose is to create a square (non stretched) thumbnail.
I've tried making changes in the 'if section'. I get a square image but stretched. I want it to be cropped.
define('THUMBNAIL_IMAGE_MAX_WIDTH', 150);
define('THUMBNAIL_IMAGE_MAX_HEIGHT', 150);
$source_image_path = {here the source filename};
$thumbnail_image_path = {here de thumb filename};
list($source_image_width, $source_image_height, $source_image_type) = getimagesize($source_image_path);
switch ($source_image_type) {
case IMAGETYPE_GIF:
$source_gd_image = imagecreatefromgif($source_image_path);
break;
case IMAGETYPE_JPEG:
$source_gd_image = imagecreatefromjpeg($source_image_path);
break;
case IMAGETYPE_PNG:
$source_gd_image = imagecreatefrompng($source_image_path);
break;
}
$source_aspect_ratio = $source_image_width / $source_image_height;
$thumbnail_aspect_ratio = THUMBNAIL_IMAGE_MAX_WIDTH / THUMBNAIL_IMAGE_MAX_HEIGHT;
if ($source_image_width <= THUMBNAIL_IMAGE_MAX_WIDTH && $source_image_height <= THUMBNAIL_IMAGE_MAX_HEIGHT) {
$thumbnail_image_width = $source_image_width;
$thumbnail_image_height = $source_image_height;
} elseif ($thumbnail_aspect_ratio > $source_aspect_ratio) {
$thumbnail_image_width = (int) (THUMBNAIL_IMAGE_MAX_HEIGHT * $source_aspect_ratio);
$thumbnail_image_height = THUMBNAIL_IMAGE_MAX_HEIGHT;
} else {
$thumbnail_image_width = THUMBNAIL_IMAGE_MAX_WIDTH;
$thumbnail_image_height = (int) (THUMBNAIL_IMAGE_MAX_WIDTH / $source_aspect_ratio);
}
$thumbnail_gd_image = imagecreatetruecolor($thumbnail_image_width, $thumbnail_image_height);
imagecopyresampled($thumbnail_gd_image, $source_gd_image, 0, 0, 0, 0, $thumbnail_image_width, $thumbnail_image_height, $source_image_width, $source_image_height);
imagejpeg($thumbnail_gd_image, $thumbnail_image_path, 90);
PS. It's not a duplicate, I've read several questions of this topic, but I'm unable to integrate it whit my code.
This function did the trick
function crop_img($imgSrc){
//getting the image dimensions
list($width, $height) = getimagesize($imgSrc);
//saving the image into memory (for manipulation with GD Library)
$myImage = imagecreatefromjpeg($imgSrc);
// calculating the part of the image to use for thumbnail
if ($width > $height) {
$y = 0;
$x = ($width - $height) / 2;
$smallestSide = $height;
} else {
$x = 0;
$y = ($height - $width) / 2;
$smallestSide = $width;
}
// copying the part into thumbnail
$thumbSize = min($width,$height);
$thumb = imagecreatetruecolor($thumbSize, $thumbSize);
imagecopyresampled($thumb, $myImage, 0, 0, $x, $y, $thumbSize, $thumbSize, $smallestSide, $smallestSide);
unlink($imgSrc);
imagejpeg($thumb,$imgSrc);
#imagedestroy($myImage);
#imagedestroy($thumb);
}
Found in: PHP crop image to fix width and height without losing dimension ratio
Use this code this code uploads image to folder and renames the file and thumb will be created with same name
HTML
<INPUT NAME="userfile[]" TYPE="file">
image directory "upimg/"
thumb directory thimg
php processing
$rename = md5(rand() * time());
$add = "upimg/" . $rename . $_FILES['userfile']['name'];
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $add)) {
echo "Successfully uploaded the image";
chmod("$add", 0777);
} else {
exit;
}
$n_width = 200;
$n_height = 200;
$tsrc = "thimg/" . $rename . $_FILES['userfile']['name'];
if (!($_FILES['userfile']['type'] == "image/jpeg" OR $_FILES['userfile']['type'] == "image/gif")) {
exit;
}
if ($_FILES['userfile']['type'] == "image/gif") {
$im = ImageCreateFromGIF($add);
$width = ImageSx($im);
$height = ImageSy($im);
$newimage = imagecreatetruecolor($n_width, $n_height);
imageCopyResized($newimage, $im, 0, 0, 0, 0, $n_width, $n_height, $width, $height);
if (function_exists("imagegif")) {
Header("Content-type: image/gif");
ImageGIF($newimage, $tsrc);
} elseif (function_exists("imagejpeg")) {
Header("Content-type: image/jpeg");
ImageJPEG($newimage, $tsrc);
}
chmod("$tsrc", 0777);
}
if ($_FILES['userfile']['type'] == "image/jpeg") {
$im = ImageCreateFromJPEG($add);
$width = ImageSx($im);
$height = ImageSy($im);
$newimage = imagecreatetruecolor($n_width, $n_height);
imageCopyResized($newimage, $im, 0, 0, 0, 0, $n_width, $n_height, $width, $height);
ImageJpeg($newimage, $tsrc);
chmod("$tsrc", 0777);
}

Resizing images and padding short edges

Code below resizes the images but I have a new requirement to it.
Requirement: I want to add padding to short edge with any colour. So when it is scaled down to 100(w)X150(h), it should be saved as 150X150 afted being padded.
For the padding option I've seen these two posts but failed to implement. Please help me to modify my code.
Resize/crop/pad a picture to a fixed size
Resize an image and fill gaps of proportions with a color
Thanks in advance
$this->defaults['width'] = 100;
$this->defaults['height'] = 150;
private function createThumbnail($sourceImage, $targetImage)
{
list($sourceWidth, $sourceHeight, $sourceType) = getimagesize($sourceImage);
switch ($sourceType)
{
case IMAGETYPE_GIF:
$sourceGdImage = imagecreatefromgif($sourceImage);
break;
case IMAGETYPE_JPEG:
$sourceGdImage = imagecreatefromjpeg($sourceImage);
break;
case IMAGETYPE_PNG:
$sourceGdImage = imagecreatefrompng($sourceImage);
break;
}
if ($sourceGdImage === false)
{
return false;
}
$sourceAspectRatio = ($sourceWidth / $sourceHeight);
$thumbnailAspectRatio = ($this->defaults['width'] / $this->defaults['height']);
if ($sourceWidth <= $this->defaults['width'] && $sourceHeight <= $this->defaults['height'])
{
$thumbnailWidth = $sourceWidth;
$thumbnailHeight = $sourceHeight;
}
elseif ($thumbnailAspectRatio > $sourceAspectRatio)
{
$thumbnailWidth = (int) ($this->defaults['height'] * $sourceAspectRatio);
$thumbnailHeight = $this->defaults['height'];
}
else
{
$thumbnailWidth = $this->defaults['width'];
$thumbnailHeight = (int) ($this->defaults['width'] / $sourceAspectRatio);
}
$thumbnailGdImage = imagecreatetruecolor($thumbnailWidth, $thumbnailHeight);
imagecopyresampled($thumbnailGdImage, $sourceGdImage, 0, 0, 0, 0, $thumbnailWidth, $thumbnailHeight, $sourceWidth, $sourceHeight);
switch ($sourceType)
{
case IMAGETYPE_GIF:
imagegif($thumbnailGdImage, $targetImage, 90);
break;
case IMAGETYPE_JPEG:
imagejpeg($thumbnailGdImage, $targetImage, 90);
break;
case IMAGETYPE_PNG:
imagepng($thumbnailGdImage, $targetImage, 9);
break;
}
imagedestroy($sourceGdImage);
imagedestroy($thumbnailGdImage);
return true;
}
SOLUTION:
thumbnailDefaults:
height: 200
width: 200
red: 200
green: 0
blue: 0
private function createThumbnailWithPadding($sourceImage, $targetImage)
{
list($sourceWidth, $sourceHeight, $sourceType) = getimagesize($sourceImage);
$sourceGdImage = imagecreatefromstring(file_get_contents($sourceImage));
//Determine scale based on the longest edge
if ($sourceHeight > $sourceWidth)
{
$scale = ($this->thumbnailDefaults['height'] / $sourceHeight);
}
else
{
$scale = ($this->thumbnailDefaults['width'] / $sourceWidth);
}
//Calculate new image dimensions
$thumbnailWidth = ($sourceWidth * $scale);
$thumbnailHeight = ($sourceHeight * $scale);
//Determine offset coordinates so that new image is centered
$offsetX = (($this->thumbnailDefaults['width'] - $thumbnailWidth) / 2);
$offsetY = (($this->thumbnailDefaults['height'] - $thumbnailHeight) / 2);
//Create new image and fill with background colour
$thumbnailGdImage = imagecreatetruecolor($this->thumbnailDefaults['width'], $this->thumbnailDefaults['height']);
//Set background colour
$bgColor = imagecolorallocate(
$thumbnailGdImage,
$this->thumbnailDefaults['red'],
$this->thumbnailDefaults['green'],
$this->thumbnailDefaults['blue']
);
//Fill background colour
imagefill($thumbnailGdImage, 0, 0, $bgColor);
//Copy and resize original image into center of new image
imagecopyresampled($thumbnailGdImage, $sourceGdImage, $offsetX, $offsetY, 0, 0, $thumbnailWidth, $thumbnailHeight, $sourceWidth, $sourceHeight);
//clearstatcache();
switch ($sourceType)
{
case IMAGETYPE_GIF:
imagegif($thumbnailGdImage, $targetImage, 90);
break;
case IMAGETYPE_JPEG:
imagejpeg($thumbnailGdImage, $targetImage, 90);
break;
case IMAGETYPE_PNG:
imagepng($thumbnailGdImage, $targetImage, 9);
break;
}
imagedestroy($sourceGdImage);
imagedestroy($thumbnailGdImage);
return true;
}

PHP - Create Thumbnail & maintaining aspect ratio

EDIT: This can be easily done in CSS, I didn't know CSS much at the time of writing this
I have created a thumbnail creator using PHP. The thumbnails generated should be of the same size. But the problem is the use of uploads images having different aspect ratio like landscape or portrait the thumbnail becomes ugly. So I created the picture above for clarification. Whatever be the uploaded image, it will be put into a rectangle image. So the aspect ratio doesn't change and thumbnails will be of the same size. Can anyone pls help me or tell some ideas?
define('THUMBNAIL_IMAGE_MAX_WIDTH', 150);
define('THUMBNAIL_IMAGE_MAX_HEIGHT', 150);
function generate_image_thumbnail($source_image_path, $thumbnail_image_path)
{
list($source_image_width, $source_image_height, $source_image_type) = getimagesize($source_image_path);
switch ($source_image_type) {
case IMAGETYPE_GIF:
$source_gd_image = imagecreatefromgif($source_image_path);
break;
case IMAGETYPE_JPEG:
$source_gd_image = imagecreatefromjpeg($source_image_path);
break;
case IMAGETYPE_PNG:
$source_gd_image = imagecreatefrompng($source_image_path);
break;
}
if ($source_gd_image === false) {
return false;
}
$source_aspect_ratio = $source_image_width / $source_image_height;
$thumbnail_aspect_ratio = THUMBNAIL_IMAGE_MAX_WIDTH / THUMBNAIL_IMAGE_MAX_HEIGHT;
if ($source_image_width <= THUMBNAIL_IMAGE_MAX_WIDTH && $source_image_height <= THUMBNAIL_IMAGE_MAX_HEIGHT) {
$thumbnail_image_width = $source_image_width;
$thumbnail_image_height = $source_image_height;
} elseif ($thumbnail_aspect_ratio > $source_aspect_ratio) {
$thumbnail_image_width = (int) (THUMBNAIL_IMAGE_MAX_HEIGHT * $source_aspect_ratio);
$thumbnail_image_height = THUMBNAIL_IMAGE_MAX_HEIGHT;
} else {
$thumbnail_image_width = THUMBNAIL_IMAGE_MAX_WIDTH;
$thumbnail_image_height = (int) (THUMBNAIL_IMAGE_MAX_WIDTH / $source_aspect_ratio);
}
$thumbnail_gd_image = imagecreatetruecolor($thumbnail_image_width, $thumbnail_image_height);
imagecopyresampled($thumbnail_gd_image, $source_gd_image, 0, 0, 0, 0, $thumbnail_image_width, $thumbnail_image_height, $source_image_width, $source_image_height);
$img_disp = imagecreatetruecolor(THUMBNAIL_IMAGE_MAX_WIDTH,THUMBNAIL_IMAGE_MAX_WIDTH);
$backcolor = imagecolorallocate($img_disp,0,0,0);
imagefill($img_disp,0,0,$backcolor);
imagecopy($img_disp, $thumbnail_gd_image, (imagesx($img_disp)/2)-(imagesx($thumbnail_gd_image)/2), (imagesy($img_disp)/2)-(imagesy($thumbnail_gd_image)/2), 0, 0, imagesx($thumbnail_gd_image), imagesy($thumbnail_gd_image));
imagejpeg($img_disp, $thumbnail_image_path, 90);
imagedestroy($source_gd_image);
imagedestroy($thumbnail_gd_image);
imagedestroy($img_disp);
return true;
}
generate_image_thumbnail('original_image.jpg', 'thumb_image.jpg'); //call the function
with that code, you will get something similar to
Look at the source code of my Mr Thumb Image Resizing. :)
public function proportion($max_width, $max_height) {
if (!( $this->halt )) {
if ($this->image['extension'] == 'gif') {
$this->image['ratio'] = ( $this->image['width'] > $this->image['height'] ) ? $max_width / $this->image['width'] : $max_height / $this->image['height'];
if ($this->image['width'] > $max_width || $this->image['height'] > $max_height) {
$new_width = $this->image['width'] * $this->image['ratio'];
$new_height = $this->image['height'] * $this->image['ratio'];
} else {
$new_width = $this->image['width'];
$new_height = $this->image['height'];
}
$this->image['composite'] = imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($this->image['composite'], $this->image['render'], 0, 0, 0, 0, $new_width, $new_height, $this->image['width'], $this->image['height']);
$this->image['colorcount'] = imagecolorstotal($this->image['render']);
imagetruecolortopalette($this->image['composite'], true, $this->image['colorcount']);
imagepalettecopy($this->image['composite'], $this->image['render']);
$this->image['transparentcolor'] = imagecolortransparent($this->image['render']);
imagefill($this->image['composite'], 0, 0, $this->image['transparentcolor']);
imagecolortransparent($this->image['composite'], $this->image['transparentcolor']);
} else {
$this->image['ratio'] = ( $this->image['width'] > $this->image['height'] ) ? $max_width / $this->image['width'] : $max_height / $this->image['height'];
if ($this->image['width'] > $max_width || $this->image['height'] > $max_height) {
$new_width = $this->image['width'] * $this->image['ratio'];
$new_height = $this->image['height'] * $this->image['ratio'];
} else {
$new_width = $this->image['width'];
$new_height = $this->image['height'];
}
$this->image['composite'] = imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($this->image['composite'], $this->image['render'], 0, 0, 0, 0, $new_width, $new_height, $this->image['width'], $this->image['height']);
}
} else {
echo 'Execution halted!';
}
}
Here's a function that might help you out. You tell it the width you want to maintain, and it will preserve the aspect ratio while also producing a thumbnail.
public static function makeThumb($src, $dest, $desired_width, $format = 'image/jpeg')
{
/* read the source image */
$source_image = null;
if($format == 'image/jpeg')
{
$source_image = imagecreatefromjpeg($src);
}
else if($format == 'image/png')
{
$source_image = imagecreatefrompng($src);
}
$width = imagesx($source_image);
$height = imagesy($source_image);
/* find the "desired height" of this thumbnail, relative to the desired width */
$desired_height = floor($height * ($desired_width / $width));
/* create a new, "virtual" image */
$virtual_image = imagecreatetruecolor($desired_width, $desired_height);
imageAlphaBlending($virtual_image, false);
imageSaveAlpha($virtual_image, true);
/* copy source image at a resized size */
imagecopyresampled($virtual_image, $source_image, 0, 0, 0, 0, $desired_width, $desired_height, $width, $height);
/* create the physical thumbnail image to its destination */
if($format == 'image/jpeg')
{
imagejpeg($virtual_image, $dest);
}
else if($format == 'image/png')
{
imagepng($virtual_image, $dest);
}
}
Use ImageMagick API .Check out this
define('THUMB_WIDTH', 60);
define('THUMB_HEIGHT', 80);
define('MAGICK_PATH','/usr/local/bin/');
function makeThumbnail($in, $out) {
$width = THUMB_WIDTH;
$height = THUMB_HEIGHT;
list($w,$h) = getimagesize($in);
$thumbRatio = $width/$height;
$inRatio = $w/$h;
$isLandscape = $inRatio > $thumbRatio;
$size = ($isLandscape ? '1000x'.$height : $width.'x1000');
$xoff = ($isLandscape ? floor((($inRatio*$height)-$width)/2) : 0);
$command = MAGICK_PATH."convert $in -resize $size -crop {$width}x{$height}+{$xoff}+0 ".
"-colorspace RGB -strip -quality 90 $out";
exec($command);
}
Refer to this link - http://coffeeshopped.com/2009/01/creating-image-thumbnails-using-php-and-imagemagick or http://in1.php.net/manual/en/class.imagick.php

Categories