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

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?

Related

Why is imageinterlace not working?

I created a function to upload a cropped image from an html5 canvas which works fine. The only issue I have is that the imageinterlace function doesn't create
a progressive jpeg.
if (is_uploaded_file($_FILES['image_file']['tmp_name'])) {
$tmp_name = $folder . $new_name;
move_uploaded_file($_FILES['image_file']['tmp_name'], $tmp_name);
if (file_exists($tmp_name) && filesize($tmp_name) > 0) {
$size = getimagesize($tmp_name);
switch($size[2]) {
case IMAGETYPE_JPEG:
$ext = '.jpg';
$v_image = #imagecreatefromjpeg($tmp_name);
break;
default:
return false;
}
imageinterlace($v_image, 1);
$destination_image = #imagecreatetruecolor( $request['width'], $request['height'] );
imagecopyresampled($destination_image, $v_image, 0, 0, (int)$request['x1'], (int)$request['y1'], (int)$request['width'], (int)$request['height'], (int)$request['w'], (int)$request['h']);
$result_name = $tmp_name . $ext;
imagejpeg($destination_image, $result_name, 90);
}
}
What am I doing wrong?

input file type, upload only selected extension

I have php file to upload different kind of image file like .jpg, .gif an soon but my problem is that i also need to upload file like Microsoft office file like .doc, .docx, and .xlsx and I can't figure out how to make this thing work with that kind of extension, also video and music is restricted to upload.
my current code below:
function
function GetExtension($imagetype){
if(empty($imagetype)) return false;
switch($imagetype){
case 'image/bmp': return '.bmp';
case 'image/gif': return '.gif';
case 'image/jpeg': return '.jpg';
case 'image/png': return '.png';
default: return false;
}
}
code process
if(isset($_POST['submit'])){
$tmp_file = $_FILES['file_upload']['tmp_name'];
$target_file = basename($_FILES['file_upload']['name']);
$imgtype = $_FILES['file_upload']['type'];
$ext = GetImageExtension($imgtype);
$imagename = date("d-m-Y")."-".time().$ext;
$upload_dir = "../images/file/".$imagename;
if(move_uploaded_file($tmp_file, $upload_dir)){
//// some code here...........
} else {
$error = $_FILES['file_upload']['error'];
}
}
You can get the extension like below:
function GetExtension($imagetype){
if(empty($imagetype)) return false;
switch($imagetype){
case '.bmp': return true;
case '.gif': return true;
case '.jpg': return true;
case '.png': return true;
case '.doc': return true;
case '.docx': return true;
case '.xls': return true;
case '.xlsx': return true;
default: return false;
}
}
....
$path = $_FILES['file_upload']['name'];
$ext = pathinfo($path, PATHINFO_EXTENSION);
$check_ext = GetImageExtension($ext);
if($check_ext) {
....
}
....

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

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