-
-
Save miguelfrmn/908143 to your computer and use it in GitHub Desktop.
<?php | |
/** | |
* File: SimpleImage.php | |
* Author: Simon Jarvis | |
* Modified by: Miguel Fermín | |
* Based in: http://www.white-hat-web-design.co.uk/articles/php-image-resizing.php | |
* | |
* This program is free software; you can redistribute it and/or | |
* modify it under the terms of the GNU General Public License | |
* as published by the Free Software Foundation; either version 2 | |
* of the License, or (at your option) any later version. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details: | |
* http://www.gnu.org/licenses/gpl.html | |
*/ | |
class SimpleImage { | |
public $image; | |
public $image_type; | |
public function __construct($filename = null){ | |
if (!empty($filename)) { | |
$this->load($filename); | |
} | |
} | |
public function load($filename) { | |
$image_info = getimagesize($filename); | |
$this->image_type = $image_info[2]; | |
if ($this->image_type == IMAGETYPE_JPEG) { | |
$this->image = imagecreatefromjpeg($filename); | |
} elseif ($this->image_type == IMAGETYPE_GIF) { | |
$this->image = imagecreatefromgif($filename); | |
} elseif ($this->image_type == IMAGETYPE_PNG) { | |
$this->image = imagecreatefrompng($filename); | |
} else { | |
throw new Exception("The file you're trying to open is not supported"); | |
} | |
} | |
public function save($filename, $image_type = IMAGETYPE_JPEG, $compression = 75, $permissions = null) { | |
if ($image_type == IMAGETYPE_JPEG) { | |
imagejpeg($this->image,$filename,$compression); | |
} elseif ($image_type == IMAGETYPE_GIF) { | |
imagegif($this->image,$filename); | |
} elseif ($image_type == IMAGETYPE_PNG) { | |
imagepng($this->image,$filename); | |
} | |
if ($permissions != null) { | |
chmod($filename,$permissions); | |
} | |
} | |
public function output($image_type=IMAGETYPE_JPEG, $quality = 80) { | |
if ($image_type == IMAGETYPE_JPEG) { | |
header("Content-type: image/jpeg"); | |
imagejpeg($this->image, null, $quality); | |
} elseif ($image_type == IMAGETYPE_GIF) { | |
header("Content-type: image/gif"); | |
imagegif($this->image); | |
} elseif ($image_type == IMAGETYPE_PNG) { | |
header("Content-type: image/png"); | |
imagepng($this->image); | |
} | |
} | |
public function getWidth() { | |
return imagesx($this->image); | |
} | |
public function getHeight() { | |
return imagesy($this->image); | |
} | |
public function resizeToHeight($height) { | |
$ratio = $height / $this->getHeight(); | |
$width = round($this->getWidth() * $ratio); | |
$this->resize($width,$height); | |
} | |
public function resizeToWidth($width) { | |
$ratio = $width / $this->getWidth(); | |
$height = round($this->getHeight() * $ratio); | |
$this->resize($width,$height); | |
} | |
public function square($size) { | |
$new_image = imagecreatetruecolor($size, $size); | |
if ($this->getWidth() > $this->getHeight()) { | |
$this->resizeToHeight($size); | |
imagecolortransparent($new_image, imagecolorallocate($new_image, 0, 0, 0)); | |
imagealphablending($new_image, false); | |
imagesavealpha($new_image, true); | |
imagecopy($new_image, $this->image, 0, 0, ($this->getWidth() - $size) / 2, 0, $size, $size); | |
} else { | |
$this->resizeToWidth($size); | |
imagecolortransparent($new_image, imagecolorallocate($new_image, 0, 0, 0)); | |
imagealphablending($new_image, false); | |
imagesavealpha($new_image, true); | |
imagecopy($new_image, $this->image, 0, 0, 0, ($this->getHeight() - $size) / 2, $size, $size); | |
} | |
$this->image = $new_image; | |
} | |
public function scale($scale) { | |
$width = $this->getWidth() * $scale/100; | |
$height = $this->getHeight() * $scale/100; | |
$this->resize($width,$height); | |
} | |
public function resize($width,$height) { | |
$new_image = imagecreatetruecolor($width, $height); | |
imagecolortransparent($new_image, imagecolorallocate($new_image, 0, 0, 0)); | |
imagealphablending($new_image, false); | |
imagesavealpha($new_image, true); | |
imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight()); | |
$this->image = $new_image; | |
} | |
public function cut($x, $y, $width, $height) { | |
$new_image = imagecreatetruecolor($width, $height); | |
imagecolortransparent($new_image, imagecolorallocate($new_image, 0, 0, 0)); | |
imagealphablending($new_image, false); | |
imagesavealpha($new_image, true); | |
imagecopy($new_image, $this->image, 0, 0, $x, $y, $width, $height); | |
$this->image = $new_image; | |
} | |
public function maxarea($width, $height = null) { | |
$height = $height ? $height : $width; | |
if ($this->getWidth() > $width) { | |
$this->resizeToWidth($width); | |
} | |
if ($this->getHeight() > $height) { | |
$this->resizeToheight($height); | |
} | |
} | |
public function minarea($width, $height = null) { | |
$height = $height ? $height : $width; | |
if ($this->getWidth() < $width) { | |
$this->resizeToWidth($width); | |
} | |
if ($this->getHeight() < $height) { | |
$this->resizeToheight($height); | |
} | |
} | |
public function cutFromCenter($width, $height) { | |
if ($width < $this->getWidth() && $width > $height) { | |
$this->resizeToWidth($width); | |
} | |
if ($height < $this->getHeight() && $width < $height) { | |
$this->resizeToHeight($height); | |
} | |
$x = ($this->getWidth() / 2) - ($width / 2); | |
$y = ($this->getHeight() / 2) - ($height / 2); | |
return $this->cut($x, $y, $width, $height); | |
} | |
public function maxareafill($width, $height, $red = 0, $green = 0, $blue = 0) { | |
$this->maxarea($width, $height); | |
$new_image = imagecreatetruecolor($width, $height); | |
$color_fill = imagecolorallocate($new_image, $red, $green, $blue); | |
imagefill($new_image, 0, 0, $color_fill); | |
imagecopyresampled( $new_image, | |
$this->image, | |
floor(($width - $this->getWidth())/2), | |
floor(($height-$this->getHeight())/2), | |
0, 0, | |
$this->getWidth(), | |
$this->getHeight(), | |
$this->getWidth(), | |
$this->getHeight() | |
); | |
$this->image = $new_image; | |
} | |
} | |
// Usage: | |
// Load the original image | |
$image = new SimpleImage('lemon.jpg'); | |
// Resize the image to 600px width and the proportional height | |
$image->resizeToWidth(600); | |
$image->save('lemon_resized.jpg'); | |
// Create a squared version of the image | |
$image->square(200); | |
$image->save('lemon_squared.jpg'); | |
// Scales the image to 75% | |
$image->scale(75); | |
$image->save('lemon_scaled.jpg'); | |
// Resize the image to specific width and height | |
$image->resize(80,60); | |
$image->save('lemon_resized2.jpg'); | |
// Resize the canvas and fill the empty space with a color of your choice | |
$image->maxareafill(600,400, 32, 39, 240); | |
$image->save('lemon_filled.jpg'); | |
// Output the image to the browser: | |
$image->output(); |
I'm just gonna throw this out there, since I found your class after someone got it confused with mine: https://github.com/claviska/SimpleImage
The reason I'm posting it is because mine supports quite a bit more of GD's built-in functionality, as well as method chaining which is handy. We could probably work together to incorporate additional functionality as needed :)
Found this earlier and started messing with it, you might want to add a round() function around the values for $width and $height in the alternate resizeTo... functions.
I have a small improvement for the resizeToHeight() and resizeToWidth() functions:
function resizeToHeight($height)
{
if ($height < $this -> getHeight())
{
$ratio = $height / $this -> getHeight();
$width = $this -> getWidth() * $ratio;
$this -> resize($width, $height);
}
}
function resizeToWidth($width)
{
if ($width < $this -> getWidth())
{
$ratio = $width / $this -> getWidth();
$height = $this -> getHeight() * $ratio;
$this -> resize($width, $height);
}
}
Great suggestion m477h3w1012, I just added a round() around the width and height.
OndrejSmisek, there may be times when I want to resize even if the image is smaller than the target size. The image will be pixelated of course.
I use your library in almost all my projects, I just wanted to leave this comment and say, thank you
Thanks for this great script!
I only got one question - Is it just me, or does resizing break png transparency?
Resizing png turns my images completely black.
Shouldn't you close the "" before "// Usage:" ?
Please add a watermarking function!
Just what i was looking for. thanks dude!
Hi there, here is the watermark function
function watermark ($right, $bottom, $watermark_url = 'watermark.png') {
$new_image = imagecreatetruecolor($this->getWidth(), $this->getHeight());
$watermark = imagecreatefrompng($watermark_url);
$x = imagesx($watermark);
$y = imagesy($watermark);
imagecopy ($this->image, $watermark,
imagesx($this->image) - $x - $right,
imagesy($this->image) - $y - $bottom,
0, 0,
imagesx($watermark),
imagesy($watermark)
);
}
but we must clear this - imagealphablending($new_image, false);
from function "cut" and it works
And i was added one more function
public function crop($width, $height) {
$ratio_source = $this->getWidth() / $this->getHeight();
$ratio_dest = $width / $height;
if ($ratio_dest < $ratio_source) {
$this->resizeToHeight($height);
} else {
$this->resizeToWidth($width);
}
$x = ($this->getWidth() / 2) - ($width / 2);
$y = ($this->getHeight() / 2) - ($height / 2);
return $this->cut($x, $y, $width, $height);
}
it crops symmetrically
And remove this - imagealphablending($new_image, false);
from resize function
When I upload png files, it replaces the transparant background with black background. Is there a way to fix this? Thank you
Never mind. I found it.
if ($ext == 'jpg' || $ext == 'jpeg' || $ext == 'JPG' || $ext == 'JPEG'){
$imagetype = 'IMAGETYPE_JPEG';
} else if($ext[1] == gif'){
$imagetype = 'IMAGETYPE_GIF';
} else if ($ext[1] == 'png'){
$imagetype = 'IMAGETYPE_PNG';
} else {
$imagetype = 'IMAGETYPE_JPEG';
}
$image->save($destination,$imagetype);
In order to save png and gif with white background you need to make the following changes in the save function:
if( $image_type == IMAGETYPE_JPEG ) {
imagejpeg($this->image,$filename,$compression);
} elseif( $image_type == IMAGETYPE_GIF ) {
$w = $this->getWidth();
$h = $this->getHeight();
$new = imagecreatetruecolor($w, $h );
imagecolortransparent($new, imagecolorallocatealpha($new, 0, 0, 0, 127));
imagealphablending($new, false);
imagesavealpha($new, true);
imagecopyresampled($new, $this->image, 0, 0, 0, 0, $w, $h, $w, $h );
imagegif($new,$filename);
} elseif( $image_type == IMAGETYPE_PNG ) {
$w = $this->getWidth();
$h = $this->getHeight();
$new = imagecreatetruecolor($w, $h );
imagecolortransparent($new, imagecolorallocatealpha($new, 0, 0, 0, 127));
imagealphablending($new, false);
imagesavealpha($new, true);
imagecopyresampled($new, $this->image, 0, 0, 0, 0, $w, $h, $w, $h );
imagepng($new,$filename);
}
if( $permissions != null) {
chmod($filename,$permissions);
}
}
and for the re size function accordingly:
function resize($width,$height) {
//EDIT
if( $this->image_type == IMAGETYPE_GIF || $this->image_type == IMAGETYPE_PNG) {
$w = $this->getWidth();
$h = $this->getHeight();
$new = imagecreatetruecolor($w, $h );
imagecolortransparent($new, imagecolorallocatealpha($new, 0, 0, 0, 127));
imagealphablending($new, false);
imagesavealpha($new, true);
imagecopyresampled($new, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
$this->image = $new_image;
}else{ //JPEG //original
$new_image = imagecreatetruecolor($width, $height);
imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
$this->image = $new_image;
}
}
Tested and worked fine ;)
Hi People ... This not have a crop solution? Very good Work.
Hello.
How can i compress gif image without losing animation, i try this code but gif animation lost.
$path = "../../imgs/user/$user_id-$iId.$ext";
if($ext=='gif'){
$tmpImg = new SimpleImage;
$tmpImg->load($path);
$tmpImg->save($path,IMAGETYPE_GIF);
}
How can i compress gif image without losing image animation.
I used this function to merge 2 images one by one below.. actually used to add a website name with a small bar below to uploaded picture.. Can we add this code with simpleimage.php ..
function merge($filename_x, $filename_y, $filename_result) {
// Get dimensions for specified images
list($width_x, $height_x, $type_x) = getimagesize($filename_x);
list($width_y, $height_y, $type_y) = getimagesize($filename_y);
// Create new image with desired dimensions
$image = imagecreatetruecolor($width_x , $height_x + $height_y);
// Load images and then copy to destination image
if( $type_x == IMAGETYPE_JPEG ) {
$image_x = imagecreatefromjpeg($filename_x);
} elseif( $type_x == IMAGETYPE_GIF ) {
$image_x = imagecreatefromgif($filename_x);
} elseif( $type_x == IMAGETYPE_PNG ) {
$image_x = imagecreatefrompng($filename_x);
}
if( $type_y == IMAGETYPE_JPEG ) {
$image_y = imagecreatefromjpeg($filename_y);
} elseif( $type_y == IMAGETYPE_GIF ) {
$image_y = imagecreatefromgif($filename_y);
} elseif( $type_y == IMAGETYPE_PNG ) {
$image_y = imagecreatefrompng($filename_y);
}
//$image_x = imagecreatefromjpeg($filename_x);
//$image_y = imagecreatefromgif($filename_y);
imagecopy($image, $image_x, 0, 0, 0, 0, $width_x, $height_x);
imagecopy($image, $image_y, $height_x, 0, 0, 0, $width_y, $height_y);
// Save the resulting image to disk (as JPEG)
imagejpeg($image, $filename_result);
// Clean up
imagedestroy($image);
imagedestroy($image_x);
imagedestroy($image_y);
}
Fix for cutfromcenter - no bars
public function cutFromCenter($width, $height)
{
$w = $this->getWidth(); //960
$h = $this->getHeight(); //310
$o = $w/$h;
if ($w < $h && $w > $width)
{
//(original height / original width) x new width = new height
$after_resize_h = floor(($h / $w) * $width);
if ($after_resize_h < $height)
$this->resizeToHeight($height);
else
$this->resizeToWidth($width);
}
elseif ($w > $h && $h > $height)
{
$after_resize_w = floor(($w / $h) * $height);
if($after_resize_w < $width)
$this->resizeToWidth($width);
else
$this->resizeToHeight($height);
}
$x = ($this->getWidth() / 2) - ($width / 2);
$y = ($this->getHeight() / 2) - ($height / 2);
return $this->cut($x, $y, $width, $height);
}
function __destruct() {
if (is_resource($this->image) && 'gd' == get_resource_type($image)) {
imagedestroy($this->image);
}
}
Hello,
Thank you for this script.
Can you help me please, I have this error:
Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /home/mywebsite/www/projectFolder/SimpleImage.php on line 22
Thank you
Hi,
When jpg file has exif information, sometimes, orientation is revert while resizing using this class.
In the load function, I've fixed it like this :
function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
if( $this->image_type == IMAGETYPE_JPEG ) {
$this->image = imagecreatefromjpeg($filename);
$exif = exif_read_data($filename);
if(!empty($exif['Orientation'])) {
switch($exif['Orientation']) {
case 8:
$this->image = imagerotate($this->image,90,0);
break;
case 3:
$this->image = imagerotate($this->image,180,0);
break;
case 6:
$this->image = imagerotate($this->image,-90,0);
break;
}
}
} elseif( $this->image_type == IMAGETYPE_GIF ) {
$this->image = imagecreatefromgif($filename);
} elseif( $this->image_type == IMAGETYPE_PNG ) {
$this->image = imagecreatefrompng($filename);
} elseif( $this->image_type == IMAGETYPE_BMP ) {
$this->image = imagecreatefrombmp($filename);
}
}
Hi guys.
I was using simpleimage to do some image formatting on my project. Currently I have a setup using resize()
which I intend to resize all image to 700x600 pixels. I have manage to setup everything and the project is LIVE'd already but during production, there was a case where the image would resize to 699x600 while the others are all 700x600 thus breaking the layout.
Was wondering if anyone faced this before?
Thanks
I offer a to screen output rather then using headers. Post kepts eating my img tags =( lol
public function output($image_type = IMAGETYPE_JPEG, $quality = 80) { if ($image_type == IMAGETYPE_JPEG) { //header("Content-type: image/jpeg"); // start buffering ob_start(); // output jpeg (or any other chosen) format & quality imagejpeg($this->image, NULL, 85); // capture output to string $contents = ob_get_contents(); // end capture ob_end_clean(); // be tidy; free up memory imagedestroy($this->image); $data = base64_encode($contents); echo '<img src="data:image/jpg;base64,'. $data .'" />'; } elseif ($image_type == IMAGETYPE_GIF) { //header("Content-type: image/gif"); // start buffering ob_start(); // output gif (or any other chosen) format & quality imagegif($this->image); // capture output to string $contents = ob_get_contents(); // end capture ob_end_clean(); // be tidy; free up memory imagedestroy($this->image); $data = base64_encode($contents); echo '<img src="data:image/gif;base64,'. $data .'" />'; } elseif ($image_type == IMAGETYPE_PNG) { //header("Content-type: image/png"); // start buffering ob_start(); // output png (or any other chosen) format & quality imagepng($this->image); // capture output to string $contents = ob_get_contents(); // end capture ob_end_clean(); // be tidy; free up memory imagedestroy($this->image); $data = base64_encode($contents); echo '<img src="data:image/png;base64,'. $data .'" />'; } }
Hello
I wanted to use this function for my image by downloading the images with file_get_contents
My code does not work
$url=ImageCreateFromString(file_get_contents('http://www.bicivendita.it/WebRoot/registerit3/Shops/990241304/509A/9674/BCB8/5136/52FE/C0A8/8007/4E62/BICICLETTE_DA_CITTA_LEGGERE_DA_UOMO_FUORISERIE.jpg'));
$image = new SimpleImage($url);
It's possible?
Regards
Great code. Thanks
Hi i added new function text watermark
`function watermark_text($waterMarkText, $font=4, $r=158, $g=158, $b=158) {
$width = imagefontwidth($font) * strlen($waterMarkText) ;
$height = imagefontheight($font) ;
$image=$this->image;
$x = $this->getWidth() - $width - 10;
$y = $this->getHeight() - $height - 10;
$backgroundColor = imagecolorallocate ($image, 255,255,255);
$textColor = imagecolorallocate ($image, $r,$g,$b);
imagestring ($image, $font, $x, $y, $waterMarkText, $textColor);
$this->image = $image;
}`
Use:
$img->watermark_text('For Example.com', 8, 215, 13, 213)
Miguel, gracias por la librería. Considera incluir la aportación de LeChatNoir69
LeChatNoir69
Perfect fix.
Tks!!!!
Do not know why we need these operations, but these definitely can cause unexpected behaviour like adding black paddings around the cutted image. These lines makes more sence for me: