Convert jpg to webp using imagewebp - php

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

Related

PHP 8.0 Ajax Upload compatibility issues

I have some issues with my upload.php code.
It works fine with PHP 7.4.
Only Notice is: "Undefined index: submitbtn".
However in PHP 8.0 it turns to a Warning: "Undefined array key "submitbtn", and the code does not execute.
Basically the code does:
Upload an image (html5 input) to folder: /uploads - without refresh!
Rotate the image if needed (needs to be vertical) - because some capture with mobile-phone and the photo gets horizontal aligned when uploaded for some reason.
Compress the image to folder: /compresseduploads.
Echo' some Javascript to exucute (a way for me to get the new /compresseduploads image path).
I really hope you can help me get it compatible with the new PHP version. Thanks :-)
(I dont think imagerotate() works with PHP 8.1 yet - therefore I am aiming for PHP 8.0.)
pssstt.. any other improvements is also welcome as I am very new to PHP.
CODE:
Index.php (input)
<form class="uploadform" method="post" enctype="multipart/form-data"
action="/wp-content/plugins/Painting_Preview/upload.php" accept="image/*" capture="camera" />
<input type="file" id="imgInp" class="span10" value="Capture photo" name="imagefile" />
<input type="submit" value="Submit" name="submitbtn" id="submitbtn">
</form>
Upload.php (compress, rotate, upload and echo js)
<?php
$file_formats = array("jpg", "jpeg", "png", "gif", "bmp"); // Set File format
$filepath = "uploads/";
if ($_POST['submitbtn']=="Submit") {
$name = $_FILES['imagefile']['name'];
$size = $_FILES['imagefile']['size'];
if (strlen($name)) {
$extension = substr($name, strrpos($name, '.')+1);
if (in_array($extension, $file_formats)) {
if ($size < 1500000000) {
$imagename = md5(uniqid().time()).".".$extension;
$tmp = $_FILES['imagefile']['tmp_name'];
if (move_uploaded_file($tmp, $filepath . $imagename)) {
echo 'THIS IS JUST THE JAVASCRIPT....
<script>jQuery(document).ready(function(.....</script>';
function compress($source, $destination, $quality) {
$info = getimagesize($source);
if ($info['mime'] == 'image/jpeg') {
$image = imagecreatefromjpeg($source);
////FIX ROTATE///
# Get exif information
$exif = exif_read_data($source);
# Add some error handling
# Get orientation
$orientation = $exif['Orientation'];
# Manipulate image
switch ($orientation) {
case 2:
imageflip($image, IMG_FLIP_HORIZONTAL);
break;
case 3:
$imageObject = imagerotate($image, 180, 0);
break;
case 4:
imageflip($image, IMG_FLIP_VERTICAL);
break;
case 5:
$imageObject = imagerotate($image, -90, 0);
imageflip($image, IMG_FLIP_HORIZONTAL);
break;
case 6:
$image = imagerotate($image, -90, 0);
break;
case 7:
$image = imagerotate($imageObject, 90, 0);
imageflip($image, IMG_FLIP_HORIZONTAL);
break;
case 8:
$image = imagerotate($imageObject, 90, 0);
break;
}
}
elseif ($info['mime'] == 'image/gif')
$image = imagecreatefromgif($source);
elseif ($info['mime'] == 'image/png')
$image = imagecreatefrompng($source);
imagejpeg($image, $destination, $quality);
return $destination;
}
$src = 'uploads/'.$imagename;
$dest = 'compresseduploads/'.$imagename;
compress($src, $dest, $quality=30);
} else {
echo "Error. Please try again.";
}
} else {
echo "Error - Your image exceeds 15 MB.";
}
} else {
echo "Invalid file format - please use .jpg or .png.";
}
} else {
echo ".....";
}
exit();
}
?>

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?

why imagecreatefromjpeg() function is not opening the file from the folder

I want to resize the image file after upload with the help of imagecreatefromjpeg function but this function is unable to access the file from the folder as it's throwing the error i.e., **
imagecreatefromjpeg(): gd-jpeg: JPEG library reports unrecoverable
error: in D:\xampp\htdocs\resize\index.php
** but file is uploaded & I wrote the following code.
<form method="post" enctype="multipart/form-data">
<input type="file" name="f1">
<input type="submit" name="btn" value="Upload">
</form>
<?php
ini_set("memory_limit","256M");
if(isset($_POST['btn']))
{
if(move_uploaded_file($_FILES['f1']['tmp_name'], "images/".$_FILES['f1']['name']))
{
$filename = "images/".$_FILES['f1']['name'];
$original_info = getimagesize($filename);
$original_w = $original_info[0];
$original_h = $original_info[1];
echo "<img src =$filename>";
if( ini_get('allow_url_fopen') ) {
// it's enabled, so do something
$original_img = imagecreatefromjpeg($filename);
$thumb_w = 100;
$thumb_h = 60;
$thumb_img = imagecreatetruecolor($thumb_w, $thumb_h);
$thumb_filename = "new.jpg";
imagecopyresampled($thumb_img, $original_img,
0, 0,
0, 0,
$thumb_w, $thumb_h,
$original_w, $original_h);
imagejpeg($thumb_img, $thumb_filename);
imagedestroy($thumb_img);
imagedestroy($original_img);
}
}
}
?>
You must make sure of the type of file.
<?php
$type = exif_imagetype($filename);
// types 1=>gif, 2=>jpg, 3=>png, 6=>bmp
switch ($type) {
case 1 : $img = imageCreateFromGif ( $src );break;
case 2 : $img = imageCreateFromJpeg( $src );break;
case 3 : $img = imageCreateFromPng ( $src );break;
case 6 : $img = imageCreateFromBmp ( $src );break;
}
// or if you cannot use exif_imagetype
// you can use getImageSize
$type = getImageSize($filename);
switch ($type) {
case 'image/gif' : $img = imageCreateFromGif ( $filename ); break;
case 'image/jpeg' : $img = imageCreateFromJpeg( $filename ); break;
case 'image/png' : $img = imageCreateFromPng ( $filename ); break;
case 'image/bmp' : $img = imageCreateFromBmp ( $filename ); break;
}
//// than you can create new file with resize or crop...
?>

Creating thumbnail from an uploaded image in Joomla 2.5

I'm really new to joomla, I don't have idea what should I do to make it done. I just have this kind of code in administrator table, it refers to uploading files.
//Support for file field: cover
if(isset($_FILES['jform']['name']['cover'])):
jimport('joomla.filesystem.file');
jimport('joomla.filesystem.file');
$file = $_FILES['jform'];
//Check if the server found any error.
$fileError = $file['error']['cover'];
$message = '';
if($fileError > 0 && $fileError != 4) {
switch ($fileError) :
case 1:
$message = JText::_( 'File size exceeds allowed by the server');
break;
case 2:
$message = JText::_( 'File size exceeds allowed by the html form');
break;
case 3:
$message = JText::_( 'Partial upload error');
break;
endswitch;
if($message != '') :
JError::raiseWarning(500,$message);
return false;
endif;
}
else if($fileError == 4){
if(isset($array['cover_hidden'])):;
$array['cover'] = $array['cover_hidden'];
endif;
}
else{
//Check for filesize
$fileSize = $file['size']['cover'];
if($fileSize > 10485760):
JError::raiseWarning(500, 'File bigger than 10MB' );
return false;
endif;
//Replace any special characters in the filename
$filename = explode('.',$file['name']['cover']);
$filename[0] = preg_replace("/[^A-Za-z0-9]/i", "-", $filename[0]);
//Add Timestamp MD5 to avoid overwriting
$filename = md5(time()) . '-' . implode('.',$filename);
$uploadPath = JPATH_ADMINISTRATOR.DIRECTORY_SEPARATOR.'components'.DIRECTORY_SEPARATOR.'com_comic'.DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR.$filename;
$fileTemp = $file['tmp_name']['cover'];
if(!JFile::exists($uploadPath)):
if (!JFile::upload($fileTemp, $uploadPath)):
JError::raiseWarning(500,'Error moving file');
return false;
endif;
endif;
$array['cover'] = $filename;
}
endif;
I could upload the file (in this case, an image) from the codes above, but what I'll do next is creating a thumbnail for the uploaded image. I searched for the php codes through the internet but it doesn't seem to work since I can't synchronize it into joomla codes. Umm.. I've made a folder named thumbnail in images folder. So what should I do next?
I'll be so happy and grateful if any of you could help me with this. Thanks.
Well i can share technique I'm using, i hope it will help:
In table's method check after the all validation is done (at the end of the method, just before returning true) i add the following code:
$input = JFactory::getApplication()->input;
$files = $input->files->get('jform');
if (!is_null($files) && isset($files['image']))
$this->image = $this->storeImage($files['image']);
The i create a new method called storeImage() :
protected $_thumb = array('max_w' => 200, 'max_h' => 200);
private function storeImage($file) {
jimport('joomla.filesystem.file');
$filename = JFile::makeSafe($file['name']);
$imageSrc = $file['tmp_name'];
$extension = strtolower(JFile::getExt($filename));
// You can add custom images path here
$imagesPath = JPATH_ROOT . '/media/';
if (in_array($extension, array('jpg', 'jpeg', 'png', 'gif'))) {
// Generate random filename
$noExt = rand(1000, 9999) . time() . rand(1000, 9999);
$newFilename = $noExt . '.' . $extension;
$imageDest = $imagesPath . $newFilename;
if (JFile::upload($imageSrc, $imageDest)) {
// Get image size
list($w, $h, $type) = GetImageSize($imageDest);
switch ($extension) {
case 'jpg':
case 'jpeg':
$srcRes = imagecreatefromjpeg($imageDest);
break;
case 'png':
$srcRes = imagecreatefrompng($imageDest);
break;
case 'gif':
$srcRes = imagecreatefromgif($imageDest);
break;
}
// Calculating thumb size
if($w > $h) {
$width_ratio = $this->_thumb['max_w'] / $w;
$new_width = $this->_thumb['max_w'];
$new_height = $h * $width_ratio;
} else {
$height_ratio = $this->_thumb['max_w'] / $h;
$new_width = $w * $height_ratio;
$new_height = $this->_thumb['max_w'];
}
$destRes = imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($destRes, $srcRes, 0, 0, 0, 0, $new_width, $new_height, $w, $h);
// Creating resized thumbnail
switch ($extension) {
case 'jpg':
case 'jpeg':
imagejpeg($destRes, $imagesPath . 'thumb_' . $newFilename, 100);
break;
case 'png':
imagepng($destRes, $imagesPath . 'thumb_' . $newFilename, 1);
break;
case 'gif':
imagegif($destRes, $imagesPath . 'thumb_' . $newFilename, 100);
break;
}
imagedestroy($destRes);
// Delete old image if it was set before
if (($this->image != "") && JFile::exists($imagesPath . $this->image)) {
JFile::delete($imagesPath . $this->image);
JFile::delete($imagesPath . 'thumb_' . $this->image);
}
return $newFilename;
}
}
}
}
return null;
}
This method returns uploaded file filename, which table stores in 'image' column. It creates two files, one original image and resized thumb with file prefix '_thumb'.
I hope it helps :)
I used Jimage : https://api.joomla.org/cms-3/classes/JImage.html
$JImage = new JImage($img_path);
$size_thumb = '150x150';
$JImage->createThumbs($size_thumb,1,$path.'/thumb');
Short, simple and efficient.

class in php for thumbs

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
}

Categories