class in php for thumbs - php

I make this code for a thumbs images.
I have MAMP with php 5.4.4 on local and this code works, but up in the server with php 5.3.19 doesn't work.
It work like
class_ethumb.php?image=demo.png&size=250
<?php
$thumb = new Thumb;
$image = $_GET['image'];
$size = $_GET['size'];
$thumb->createThumb($image,$size);
class Thumb {
public function Thumb($image)
{
//Define the Default Size
$this->defaultSize = 100;
}
// type of image example: "jpg","png" or "gif"
public function setType($image)
{
$ext = explode(".",$image);
$num = count($ext)-1;
$type = $ext[$num];
$this->type = $type;
}
// get the size of source image
public function getSize($image)
{
switch($this->type) {
case 'jpg':
$this->source = #imagecreatefromjpeg($image);
break;
case 'png':
$this->source = #imagecreatefrompng($image);
break;
case 'gif':
$this->source = #imagecreatefromgif($image);
break;
default:
die("Invalid file type");
}
$this->imgWidth = imagesx($this->source);
$this->imgHeight = imagesy($this->source);
}
public function createThumb($image,$size)
{
if(file_exists($image) === TRUE)
{
// set the type of image
$this->setType($image);
// get the original size
$this->getSize($image);
// if $size exist
if(!$size)
{
$width = $this->defaultSize;
$height = ($this->defaultSize * $this->imgHeight) / $this->imgWidth;
}
else // if not, let set defaultSize
{
$width = $size;
$height = ($size * $this->imgHeight) / $this->imgWidth;
}
// create a image from a true color
$img = imagecreatetruecolor($width,$height);
//thumb creation
ImageCopyResized($img,$this->source,0,0,0,0,$width,$height,$this->imgWidth,$this->imgHeight);
// let's print the thumb
switch($this->type) {
case 'jpg':
Header("Content-type: image/jpeg");
imageJpeg($img);
break;
case 'png':
Header("Content-type: image/png");
imagePng($img);
break;
case 'gif':
Header("Content-type: image/gif");
imageGif($img);
break;
}
}
else
{
die("File doesn't exist");
}
}
}
?>
Any help? Thanks

You should change your code so you use __construct instead of that style. You seem to be missing an argument for the constructor too. Also, you shouldn't need the ?> at the end of the file
<?php
$thumb = new Thumb();
$image = $_GET['image'];
$size = $_GET['size'];
$thumb->createThumb($image,$size);
class Thumb {
public function __construct( )
{
//Define the Default Size
$this->defaultSize = 100;
}
// ... Rest of your file
}
You could also just get rid of the constructor, and have a class variable set for defaultSize
<?php
class Thumb {
private $defaultSize = 100;
// ... Rest of file
}

Related

Why does this PHP image conversion method create completely transparent images?

I am using the below method to batch convert images to the .webp format (borrowed from here):
public function convertToWebp($file, $compression_quality = 80) {
// check if file exists
if (!file_exists($file)) {
return false;
}
// If output file already exists return path
$output_file = $file . '.webp';
if (file_exists($output_file)) {
return $output_file;
}
$file_type = strtolower(pathinfo($file, PATHINFO_EXTENSION));
if (function_exists('imagewebp')) {
switch ($file_type) {
case 'jpeg':
case 'jpg':
$image = imagecreatefromjpeg($file);
break;
case 'png':
$image = imagecreatefrompng($file);
imagepalettetotruecolor($image);
imagealphablending($image, true);
imagesavealpha($image, true);
break;
case 'gif':
$image = imagecreatefromgif($file);
break;
default:
return false;
}
// Save the image
$result = imagewebp($image, $output_file, $compression_quality);
if (false === $result) {
return false;
}
// Free up memory
imagedestroy($image);
return $output_file;
} elseif (class_exists('Imagick')) {
$image = new Imagick();
$image->readImage($file);
if ($file_type === 'png') {
$image->setImageFormat('webp');
$image->setImageCompressionQuality($compression_quality);
$image->setOption('webp:lossless', 'true');
}
$image->writeImage($output_file);
return $output_file;
}
return false;
}
In the view file:
foreach ($images as $image) {
<img class="img-responsive" src="<?= convertToWebp($image);?>"/>
}
The problem
While most of the images are converted successfully, some are completely transparent.
What is missing?
If the Imagick library does not have support for .webp what's a good workaround?

Can't upload image with 100% quality

I'm trying to upload image via PHP, but I'm unable to upload an image with 100% quality.
The code I'm actually using
class imaging
{
// Variables
private $img_input;
private $img_output;
private $img_src;
private $format;
private $quality = 100;
private $x_input;
private $y_input;
private $x_output;
private $y_output;
private $resize;
// Set image
public function upload($orig, $name, $path)
{
move_uploaded_file($orig, __DIR__ . "/../uploads/" . $path . 'orig_' . $name);
}
public function set_img($img)
{
//$img = __DIR__ . '/../uploads/' . $img;
$img = '../uploads/' . $img;
// Find format
$ext = strtoupper(pathinfo($img, PATHINFO_EXTENSION));
// JPEG image
if(is_file($img) && ($ext == "JPG" OR $ext == "JPEG"))
{
$this->format = $ext;
$this->img_input = ImageCreateFromJPEG($img);
$this->img_src = $img;
}
// PNG image
elseif(is_file($img) && $ext == "PNG")
{
$this->format = $ext;
$this->img_input = ImageCreateFromPNG($img);
$this->img_src = $img;
}
// GIF image
elseif(is_file($img) && $ext == "GIF")
{
$this->format = $ext;
$this->img_input = ImageCreateFromGIF($img);
$this->img_src = $img;
}
// Get dimensions
$this->x_input = imagesx($this->img_input);
$this->y_input = imagesy($this->img_input);
}
// Set maximum image size (pixels)
public function set_size($size = 100)
{
// Wide
if($this->x_input >= $this->y_input && $this->x_input > $size)
{
$this->x_output = $size;
$this->y_output = ($this->x_output / $this->x_input) * $this->y_input;
$this->resize = TRUE;
}
// Tall
elseif($this->y_input > $this->x_input && $this->y_input > $size)
{
$this->y_output = $size;
$this->x_output = ($this->y_output / $this->y_input) * $this->x_input;
$this->resize = TRUE;
}
// Don't resize
else { $this->resize = FALSE; }
}
// Set image quality (JPEG only)
public function set_quality($quality)
{
if(is_int($quality))
{
$this->quality = $quality;
}
}
// Save image
public function save_img($path)
{
// Resize
if($this->resize)
{
$this->img_output = ImageCreateTrueColor($this->x_output, $this->y_output);
ImageCopyResampled($this->img_output, $this->img_input, 0, 0, 0, 0, $this->x_output, $this->y_output, $this->x_input, $this->y_input);
}
// Save JPEG
if($this->format == "JPG" OR $this->format == "JPEG")
{
if($this->resize) { imageJPEG($this->img_output, __DIR__ . "/../uploads/" . $path, $this->quality); }
else { copy($this->img_src, __DIR__ . "/../uploads/" . $path); }
}
// Save PNG
elseif($this->format == "PNG")
{
if($this->resize) { imagePNG($this->img_output, __DIR__ . "/../uploads/" . $path, 9); }
else { copy($this->img_src, __DIR__ . "/../uploads/" . $path); }
}
// Save GIF
elseif($this->format == "GIF")
{
if($this->resize) { imageGIF($this->img_output, __DIR__ . "/../uploads/" . $path); }
else { copy($this->img_src, __DIR__ . "/../uploads/" . $path); }
}
}
// Get width
public function get_width()
{
return $this->x_input;
}
// Get height
public function get_height()
{
return $this->y_input;
}
// Clear image cache
public function clear_cache()
{
#ImageDestroy($this->img_input);
#ImageDestroy($this->img_output);
}
}
And calling upload
$img = new imaging;
$img->upload($src['tmp_name'], $name, $dir);
$img->set_img($dir . 'orig_' . $name); // upload original file
$img->set_quality(100);
// Small thumbnail
$img->set_size(700); // upload thumbnail
$img->save_img($dir . $name);
// Finalize
$img->clear_cache();
Result isn't very good, instead of setting quality=100. Original file (width cca 1100px) is uploaded correctly (no resize on server), when I open it in Photoshop, resize to 700px width and compare with 700px thumb resized in PHP, there is very big difference in quality.
See both images, original resized in Photoshop (top) and resize image via PHP (bottom) - texts, images, etc. are blurred, colors aren't bright.
Orig size
200% zoom in Photoshop
Any ideas? Thanks for your replies :-)
I'm gonna answer here because I don't have enough reputation to make a comment.
To resize the image, i think it's better to use the command imagescale. It's better that use ImageCreateTrueColor + ImageCopyResampled.
So I'd do it
// Resize
if($this->resize)
{
$this->img_output = imagescale($this->img_input, $this->x_output, $this->y_output);
}
But there are some other things that you also may change:
I created the method create_thumbnail() and you'll pass it the path to the image, the path where save the new image and optionally the size (Default 100).
To have the width and the height, you don't need to create the image. You can do it with the method getimagesize and like this, you'll save a lot of resources.
When you call the method to resize, it will resize the image if it needed.
And when you are going to save the image, you can know if the image has been resized or not and so you'll copy it or not.
Also, I've tried to not repeat any code and optimising the resources.
EDIT: Also you can clear the cache and the end of the process.
class imaging
{
// Variables
private $img_input;
private $img_output;
private $img_src;
private $format;
private $quality = 100;
private $x_input;
private $y_input;
private $x_output;
private $y_output;
private $resize;
// Set image
public function upload($orig, $name, $path)
{
move_uploaded_file($orig, __DIR__ . "/../uploads/" . $path . 'orig_' . $name);
}
// Set image quality (JPEG only)
public function set_quality($quality)
{
if(is_int($quality))
{
$this->quality = $quality;
}
}
// Set maximum image size (pixels)
private function resize($size = 100)
{
$resize = FALSE;
// Wide
if($this->x_input >= $this->y_input && $this->x_input > $size)
{
$this->x_output = $size;
$this->y_output = ($this->x_output / $this->x_input) * $this->y_input;
$resize = TRUE;
}
// Tall
elseif($this->y_input > $this->x_input && $this->y_input > $size)
{
$this->y_output = $size;
$this->x_output = ($this->y_output / $this->y_input) * $this->x_input;
$resize = TRUE;
}
if($resize){
switch ($this->format) {
case 'JPEG':
case 'JPG':
$this->img_input = ImageCreateFromJPEG($img);
break;
case 'PNG':
$this->img_input = ImageCreateFromPNG($img);
break;
case 'GIF':
$this->img_input = ImageCreateFromGIF($img);
break;
default:
throw new Exception("This extension " . $ext . " it's not compatible.");
break;
}
}
}
// Save image
public function save_img($path)
{
// We have resized the image
if($this->img_input){
switch ($this->format) {
case 'JPEG':
case 'JPG':
imageJPEG($this->img_output, __DIR__ . "/../uploads/" . $path, $this->quality);
break;
case 'PNG':
imagePNG( $this->img_output, __DIR__ . "/../uploads/" . $path, 9);
break;
case 'GIF':
imageGIF( $this->img_output, __DIR__ . "/../uploads/" . $path);
break;
default:
throw new Exception("This extension " . $ext . " it's not compatible.");
break;
}
}else{
copy($this->img_src, __DIR__ . "/../uploads/" . $path);
}
}
public function create_thumbnail($imgSrc, $savePath, $size = 100)
{
$this->img_src = '../uploads/' . $img;
if(file_exists($this->img_src)){
list($this->x_input, $this->y_input) = getimagesize($imageSrc);
$this->format = strtoupper(pathinfo($img, PATHINFO_EXTENSION));
$this->resize($size);
$this->save_img($savePath);
$this->clear_cache();
}else{
throw new Exception("Image not found in " . $imdSrc);
}
}
// Get width
public function get_width()
{
return $this->x_input;
}
// Get height
public function get_height()
{
return $this->y_input;
}
// Clear image cache
public function clear_cache()
{
#ImageDestroy($this->img_input);
#ImageDestroy($this->img_output);
}
}
You can give this package a try http://image.intervention.io/getting_started/introduction . http://image.intervention.io/getting_started/installation, here it has all the configuration instruction.
It should work correctly and very easy to setup with composer.
I suggest you to use Intervention Image Library for image handling and manipulation. I have this type of issue in past and switching to a different library solved the issue.
Secondly, the use of this library is extremely simple which is already available on website.
I will recommend
convert your image into base64 then update the base64 string then on server side again covert that base64 string into image. you will find the method for conversion
image to base64: https://stackoverflow.com/a/13758760/11956865
base64 to image: https://stackoverflow.com/a/15153931/11956865

Convert jpg to webp using imagewebp

I'm having trouble using imagewebp to convert an image to webp.
I use this code:
$filename = dirname(__FILE__) .'/example.jpg';
$im = imagecreatefromjpeg($filename);
$webp =imagewebp($im, str_replace('jpg', 'webp', $filename));
imagedestroy($im);
var_dump($webp);
$webp returns true but when I try to view the webp-image in Chrome it just shows blank, but with the correct size. If I instead load the image and set headers with PHP (see below) it shows up, but with wrong colors (too much yellow).
$im = imagecreatefromwebp('example.webp');
header('Content-Type: image/webp');
imagewebp($im);
imagedestroy($im);
If I convert the same image with command line it works as expected.
cwebp -q 100 example.jpg -o example.webp
I'm testing this on Ubuntu 14, Apache 2.4.7 and PHP 5.5.9-1ubuntu4.4.
It works:
$jpg=imagecreatefromjpeg('filename.jpg');
$w=imagesx($jpg);
$h=imagesy($jpg);
$webp=imagecreatetruecolor($w,$h);
imagecopy($webp,$jpg,0,0,0,0,$w,$h);
imagewebp($webp, 'filename.webp', 80);
imagedestroy($jpg);
imagedestroy($webp);
I had same problem, my solution is:
$file='hnbrnocz.jpg';
$image= imagecreatefromjpeg($file);
ob_start();
imagejpeg($image,NULL,100);
$cont= ob_get_contents();
ob_end_clean();
imagedestroy($image);
$content = imagecreatefromstring($cont);
imagewebp($content,'images/hnbrnocz.webp');
imagedestroy($content);
I user this
function webpConvert2($file, $compression_quality = 80)
{
// check if file exists
if (!file_exists($file)) {
return false;
}
$file_type = exif_imagetype($file);
//https://www.php.net/manual/en/function.exif-imagetype.php
//exif_imagetype($file);
// 1 IMAGETYPE_GIF
// 2 IMAGETYPE_JPEG
// 3 IMAGETYPE_PNG
// 6 IMAGETYPE_BMP
// 15 IMAGETYPE_WBMP
// 16 IMAGETYPE_XBM
$output_file = $file . '.webp';
if (file_exists($output_file)) {
return $output_file;
}
if (function_exists('imagewebp')) {
switch ($file_type) {
case '1': //IMAGETYPE_GIF
$image = imagecreatefromgif($file);
break;
case '2': //IMAGETYPE_JPEG
$image = imagecreatefromjpeg($file);
break;
case '3': //IMAGETYPE_PNG
$image = imagecreatefrompng($file);
imagepalettetotruecolor($image);
imagealphablending($image, true);
imagesavealpha($image, true);
break;
case '6': // IMAGETYPE_BMP
$image = imagecreatefrombmp($file);
break;
case '15': //IMAGETYPE_Webp
return false;
break;
case '16': //IMAGETYPE_XBM
$image = imagecreatefromxbm($file);
break;
default:
return false;
}
// Save the image
$result = imagewebp($image, $output_file, $compression_quality);
if (false === $result) {
return false;
}
// Free up memory
imagedestroy($image);
return $output_file;
} elseif (class_exists('Imagick')) {
$image = new Imagick();
$image->readImage($file);
if ($file_type === "3") {
$image->setImageFormat('webp');
$image->setImageCompressionQuality($compression_quality);
$image->setOption('webp:lossless', 'true');
}
$image->writeImage($output_file);
return $output_file;
}
return false;
}

image upload problem

I wrote a function to resize and upload images...it works, but only for one image. So if I call the function three times, I end up with 3 copies of the last image.....
function uploadImage($name,$width,$height,$size,$path='content/user_avatars/')
{
//===================================================
//Handle image upload
$upload_error=0;
//Picture
$img = $_FILES[$name]['name'];
if($img)
{
$file = stripslashes($_FILES[$name]['name']);
$ext = strtolower(getExt($file));
if($ext!='jpg' && $ext!='jpeg' && $ext!='png' && $ext!='gif')
{
$error_msg = "Unknown extension";
$upload_error = 1;
return array($upload_error,$error_msg);
}
if(filesize($_FILES[$name]['tmp_name'])>$size*1024)
{
$error_msg = "Max file size of ".($size*1024)."kb exceeded";
$upload_error = 2;
return array($upload_error,$error_msg);
}
$newFile = time().'.'.$ext;
resizeImg($_FILES[$name]['tmp_name'],$ext,$width,$height);
$store = copy($_FILES[$name]['tmp_name'],$path.$newFile);
if(!$store)
{
$error_msg = "Uploading failed";
$upload_error = 3;
return array($upload_error,$error_msg);
}
else
{
return array($upload_error,$newFile);
}
}
}
//=========================================================================================
//Helper Functions
function getExt($str)
{
$i = strpos($str,".");
if(!$i)
{
return "";
}
$l = strlen($str)-$i;
$ext = substr($str,$i+1,$l);
return $ext;
}
function resizeImg($file,$ext,$width,$height)
{
list($aw,$ah) = getimagesize($file);
$scaleX = $aw/$width;
$scaleY = $ah/$height;
if($scaleX>$scaleY)
{
$nw = round($aw*(1/$scaleX));
$nh = round($ah*(1/$scaleX));
}
else
{
$nw = round($aw*(1/$scaleY));
$nh = round($ah*(1/$scaleY));
}
$new_image = imagecreatetruecolor($nw,$nh);
imagefill($new_image,0,0,imagecolorallocatealpha($new_image,255,255,255,127));
if($ext=='jpg'||$ext=='jpeg')
{
$src_image = imagecreatefromjpeg($file);
}
else if($ext=='gif')
{
$src_image = imagecreatefromgif($file);
}
else if($ext=='png')
{
$src_image = imagecreatefrompng($file);
}
imagecopyresampled($new_image,$src_image,0,0,0,0,$nw,$nh,$aw,$ah);
if($ext=='jpg'||$ext=='jpeg')
{
imagejpeg($new_image,$file,100);
}
else if($ext=='gif')
{
imagegif($new_image,$file);
}
else if($ext=='png')
{
imagepng($new_image,$file,9);
}
imagedestroy($src_image);
imagedestroy($new_image);
}
I have a form with two upload fields, 'face_pic' and 'body_pic', and I want to upload these two to the server and resize them before storing. Any ideas?
You use the current time to determine the resulting name of the file. The function executes so fast, that time() yields the same result for both images.
Use some other means to disambiguate the resulting name of the file. Best choice would be to pass the resulting name as a parameter. That way, the environment can determine how the file is named. Candidates are primary key of the meta information (in case they are stored in the database), original file name, universally unique identifier.
In any case, check whether the resulting name is a legal filename on your platform and that you do not accidentally overwrite files.
Also consider using move_uploaded_file to move the file from the temporary location to the destination. That function does some security checking.
md5(microtime())
Try naming it like this.
Or try something like this...
function slikeAvatar($slika,$id = 0){
copy($slika, "avatari/{$id}l.jpg");
$gfx = new Thumbnail($slika, 200);
$gfx->save("avatari/{$id}.jpg");
unset($gfx);
$gfx = new Thumbnail($slika, 75);
$gfx->save("avatari/{$id}s.jpg");
unset($gfx);
slikeCrop("avatari/{$id}s.jpg","avatari/{$id}s.jpg");
}
slike = images

Resize image before uploading PHP

I have no idea how to resize image in PHP, my code is:
for ($index = 1; $index <= 2; $index++) {
if (!empty($_FILES["pic$index"]["name"])) {
$ext = substr($_FILES["pic$index"]["name"], strrpos($_FILES["pic$index"]["name"], '.') + 1);
$dir = "../gallery/$mkdir";
HERE I NEED THE RESIZE OF THE TMP FILE OF IMAGE
move_uploaded_file($_FILES["pic$index"]["tmp_name"] , "$dir/img-$index.$ext");
}
}
$mkdir = the name of the gallery's folder (there are many galleries).
$dir = where the pics will be placed.
$ext = the type of the image (png, gif or jpg).
foreach loop runs two times because you can upload two pics.
This script is working good, I just need to do resize and I dont have an idea how to do it..
Here is the code I'm using to resize images.
In my case I give to the function the original file name and then the thumbnail file name.
You can adapt it for your case very easily.
public static function GenerateThumbnail($im_filename,$th_filename,$max_width,$max_height,$quality = 0.75)
{
// The original image must exist
if(is_file($im_filename))
{
// Let's create the directory if needed
$th_path = dirname($th_filename);
if(!is_dir($th_path))
mkdir($th_path, 0777, true);
// If the thumb does not aleady exists
if(!is_file($th_filename))
{
// Get Image size info
list($width_orig, $height_orig, $image_type) = #getimagesize($im_filename);
if(!$width_orig)
return 2;
switch($image_type)
{
case 1: $src_im = #imagecreatefromgif($im_filename); break;
case 2: $src_im = #imagecreatefromjpeg($im_filename); break;
case 3: $src_im = #imagecreatefrompng($im_filename); break;
}
if(!$src_im)
return 3;
$aspect_ratio = (float) $height_orig / $width_orig;
$thumb_height = $max_height;
$thumb_width = round($thumb_height / $aspect_ratio);
if($thumb_width > $max_width)
{
$thumb_width = $max_width;
$thumb_height = round($thumb_width * $aspect_ratio);
}
$width = $thumb_width;
$height = $thumb_height;
$dst_img = #imagecreatetruecolor($width, $height);
if(!$dst_img)
return 4;
$success = #imagecopyresampled($dst_img,$src_im,0,0,0,0,$width,$height,$width_orig,$height_orig);
if(!$success)
return 4;
switch ($image_type)
{
case 1: $success = #imagegif($dst_img,$th_filename); break;
case 2: $success = #imagejpeg($dst_img,$th_filename,intval($quality*100)); break;
case 3: $success = #imagepng($dst_img,$th_filename,intval($quality*9)); break;
}
if(!$success)
return 4;
}
return 0;
}
return 1;
}
The return codes are just here to differentiate between different types of errors.
By looking back at that code, I don't like the "magic number" trick. I'm gonna have to change that (by exceptions for example).
if (!empty($_FILES["pic$index"]["name"])) {
$ext = substr($_FILES["pic$index"]["name"], strrpos($_FILES["pic$index"]["name"], '.') + 1);
$dir = "../gallery/$mkdir";
// Move it
if(move_uploaded_file($_FILES["pic$index"]["tmp_name"] , "$dir/img-$index.$ext.tmp"))
{
// Resize it
GenerateThumbnail("$dir/img-$index.$ext.tmp","$dir/img-$index.$ext",600,800,0.80);
// Delete full size
unlink("$dir/img-$index.$ext.tmp");
}
}
Use move_uploaded_file to move it (recommanded) and then you can resize it and send it to it's final destination. You might not even need the ".tmp", you can use.
// Move it
if(move_uploaded_file($_FILES["pic$index"]["tmp_name"] , "$dir/img-$index.$ext"))
// Resize it
GenerateThumbnail("$dir/img-$index.$ext","$dir/img-$index.$ext",600,800);
Keep in mind that the picture you are dealing with is already uploaded on the server. You actualy want to resize picture before storing it in "safe place".
$_FILES["pic$index"]["tmp_name"] is probably /tmp/somepicturesname

Categories