DOMPDF images have poor quality when processing in server - php

I am working on a website with different jQuery forms that output to a html result page, this html is converted to a pdf file with DOMPDF library. When the conversion is made in local, there is no problem, but when it takes place in the server, the resulting pdf images have lower quality than the originals, with white scratches and blur (I can upload an example if necessary).
Doing some research, I tried the following solutions:
- tried different image formats (jpg, png, gif)
- tried different values for "DOMPDF_PDF_BACKEND" (rendering backend to use) (CPDF, PDFLib, GD)
- tried different "DOMPDF_DPI" values
- "DOMPDF_ENABLE_REMOTE" value is set to "true"
- tried opening the resulting pdf with different applications (ubuntu pdf viewer, adobe acrobat pdf, gimp, photoshop)
all with the same result.
Also took a look at phpinfo() both in local and server:
PHP version
local: PHP Version 5.5.11
server: PHP Version 5.3.29
GD version:
both: bundled (2.1.0 compatible)
GD FreeType Version :
local: 2.4.8
version: 2.4.9
libPNG Version:
local: 1.5.9
server: 1.2.49
I don't know what other parameters to compare.
I don't know what else to try.
Thanks in advance.

Thanks for the anwswer, I saw that post yesterday, I had tried different image formats, but I had pending playing with the libraries.
Finally, commenting out the code regarding the imagick image processing "// Use PECL imagick + ImageMagic to process transparent PNG images" solved the problem, that was due to images containing transparencies (alpha) such as png and gif.
// Use PECL imagick + ImageMagic to process transparent PNG images
}elseif (extension_loaded("imagick")) {
$imagick = new Imagick($file);
$imagick->setFormat('png');
// Get opacity channel (negative of alpha channel)
$alpha_channel = clone $imagick;
$alpha_channel->separateImageChannel(Imagick::CHANNEL_ALPHA);
$alpha_channel->negateImage(true);
$alpha_channel->writeImage($tempfile_alpha);
// Cast to 8bit+palette
$imgalpha_ = imagecreatefrompng($tempfile_alpha);
imagecopy($imgalpha, $imgalpha_, 0, 0, 0, 0, $wpx, $hpx);
imagedestroy($imgalpha_);
imagepng($imgalpha, $tempfile_alpha);
// Make opaque image
$color_channels = new Imagick();
$color_channels->newImage($wpx, $hpx, "#FFFFFF", "png");
$color_channels->compositeImage($imagick, Imagick::COMPOSITE_COPYRED, 0, 0);
$color_channels->compositeImage($imagick, Imagick::COMPOSITE_COPYGREEN, 0, 0);
$color_channels->compositeImage($imagick, Imagick::COMPOSITE_COPYBLUE, 0, 0);
$color_channels->writeImage($tempfile_plain);
$imgplain = imagecreatefrompng($tempfile_plain);
}
Then it would use the "}else{" option that extracts the image without alpha channel.
You can also disable imagick module in the php.ini

Related

getimagesize unable to get size of remote webp files with PHP version 5.3.29

Following is the code snippet -
list($campaign_image_width, $campaign_image_height, $campaign_image_type, $campaign_image_attr)=getimagesize($campaign_image);
Wherein $campaign_image contains the url of third party images.
Problem
$campaign_image_width comes out empty for this url -
https://lh3.googleusercontent.com/VRY0O_3L8VH2wxJSTiKPr72PeM5uhPPFEsHzzYdxenddpTI150M0TYpljnZisQaROR0=h256-rw
I am not sure if it is the limitation of getimagesize(), because of unsupported format, which is causing this, or it is because of accessibility issues with the image.
Note -
- The =h256-rw appeneded at the end seems to tell the server to return a different sized version of the image.
- I found that if I try to open the file using firefox browser, it does not display the image, but rather asks to download a webp file (an image format by google it seems).
Google chrome opens the file and displays the image, normally.
Since your server is already downloading the file you might as well do it yourself (if the problem is that it can't do it correctly for webp). You can easily do this using the GD methods imagecreatefromwebp with imagesx and imagesy:
<?php
$url = 'https://lh3.googleusercontent.com/VRY0O_3L8VH2wxJSTiKPr72PeM5uhPPFEsHzzYdxenddpTI150M0TYpljnZisQaROR0=h256-rw';
$img = imagecreatefromwebp($url);
$width = imagesx($img);
$height = imagesy($img);
var_dump($width, $height);
Note:
imagecreatefromwebp() was first introduced in PHP 5.5, so make sure your minimum version is 5.5 with the GD extension installed.
If possible you can install Google's own webp converter as a binary on your server:
https://developers.google.com/speed/webp/docs/compiling#building
In this instance you're running Amazon linux which is based on Fedora and hence uses yum as the package manager, so you should be able to run the following command:
sudo yum install libwebp;
Once you have installed this you can make sure that your safemode supports the binary by using safe_mode_exec_dir and one of the following execution methods:
exec
passthru
system
popen
Once you've run the conversion to eg. JPG, you can run the usual PHP tools to get the image dimensions:
$hnd = imagecreatefromjpeg('convertedImage.jpg');
$width = imagesx($hnd);
$height = imagesy($hnd);
I think it's beacause of unsupported format. Try imagetypes to know what is supported.
$bits = imagetypes();
Check out this post, it can be helpful. After installing you'll be able to do
$image = new Imagick($originalFilepath);
$origImageDimens = $image->getImageGeometry();
$origImgWidth = $origImageDimens['width'];
$origImgHeight = $origImageDimens['height'];

Creating/Saving DirectDraw Surface (DDS) Image via Imagick

This is the first time I use PHP Imagick and experiencing problems with it.
I'm creating a website module where users can upload images that need to be converted to an encrypted file type containing the uploaded image as a DDS texture.
So what I need to do is convert the uploaded image to dds file format.
Code:
$img = new Imagick('test.png'); //Load the uploaded image
$img->setformat('dds'); //Set the format to dds
$img->setImageCompression(Imagick::COMPRESSION_DXT3); //Set compression method
$img->writeimage('test.dds'); //Write/save the dds texture
The problem: the output file is always an empty, 0 byte file.
PNG That needs to be converted: test.png
DDS That needs to be the output: test.dds
Maybe I need other version Imagick or ImageMagick?
My old version of these are:
PHP 5.5.15
Imagick 3.1.2-5.5-ts-vc11-x86
ImageMagick 6.8.4-0-Q16-x86
I am currently testing on Windows 8.1 x64.
Any suggestion/help would be appreciated.
Edit: Edited the question, hopefully its clear now what I am trying to achieve.
Solved: The problem was the version of ImageMagick that had no support for DDS write.
Installed ImageMagick 6.8.6-10-Q16-x86 since the DDS write support was added in that version (newer versions caused the imagick not to be loaded).
Current version of what I use and works:
PHP 5.5.15
Imagick 3.1.2-5.5-ts-vc11-x86
ImageMagick 6.8.6-10-Q16-x86
From the debugging above the issue is that your version of ImageMagick doesn't support writing DXT3 compressed DDS files.
The options to solve this problem are:
Use a different compression format - DXT5 might be okay, but it's not exactly the same as DXT3.
Upgrade to a newer version of ImageMagick and Imagick that support writing in DXT3 format.

PHP Image Processing GD JPEG Quality

I started using the WideImage image processing library and I'm having a problem with the quality of the JPEG images it's generating. WideImage actually uses GD, so I'm testing just using the GD PHP image functions.
My aim is ultimately to resize images, but here's my test code with no resizing taking place:
$srcImage = "path/to/image.jpg";
list($width, $height) = getimagesize($srcImage);
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($srcImage);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width, $height);
imagejpg($image_p, "path/to/image_resized.jpg", 100);
This works, but outputs a lower quality more washed out version of the original image.
Here is an example next to the original split down the center:
This happens when I do perform a resize also, but I want to maintain the same colours/quality of the original image.
Has anyone got any ideas as to how I can achieve this? Is there perhaps a setting in my php.ini that I am missing or something? I also tried using imagepng() but with much the same results.
I'm using PHP Version 5.3.29, here is my GD info from phpinfo():
GD Support : enabled
GD Version : bundled (2.1.0 compatible)
FreeType Support : enabled
FreeType Linkage : with freetype
FreeType Version : 2.3.11
T1Lib Support : enabled
GIF Read Support : enabled
GIF Create Support: enabled
JPEG Support : enabled
libJPEG Version : 6b
PNG Support : enabled
libPNG Version : 1.2.49
WBMP Support : enabled
XPM Support : enabled
libXpm Version : 30411
XBM Support : enabled
Thanks!
At squeamish ossifrage's request, here is the original file and the converted file.
EDIT - as per the squeamish ossifrage's answer marked correct below, I took the following steps to solve the issue:
Installed exiftool on the server
Generated the following command with PHP:
exiftool -TagsFromFile "/var/www/vhosts/path/to/image/the file name.jpg" -icc_profile "/var/www/vhosts/path/to/image-processed/the file name.jpg"
Ran the command with PHP's exec() method:
$arrOutput = array();
$return_var = "";
$directOutput = exec($exiftoolCommand, $arrOutput, $return_var);
Worked like a charm!
The original image contains an ICC colour profile. GD doesn't know anything about colour profiles, so this information is missing from the converted file. To fix this problem, you basically have two options:
Save the original file without a colour profile, or
Copy the colour profile from the original file to the converted file.
I'd go with option 1 if you're planning to publish this file on the web, as colour profiles and other EXIF information use up bandwidth for no good reason.
Alternatively, you can use a free tool like exiftool to copy the colour profile from one file to the other. This should work on the command line:
exiftool -TagsFromFile so_original.jpg -icc_profile so_converted.jpg

TCPDF: PNG image rendered incorrectly

I'm working on a project which involves TCPDF. I've been working with it for a while now but, after the last update (6.0) my PNG images get really broken although its fragments still visible on the document.
I'm using the Image() method as follows:
$pdf->Image($img, $x, $y, $twidth, $theight);
where $img is the source URL, $x and $y the position and $twidth and $theight the size.
I've tested GIF and JPG and it works just fine. There is a GIF image on the PDF to prove that. The PNG image is the VLC icon logo.
The image:
From the project site, to a user who had a similar problem:
Probably you have problems with PNG images with transparency that are
handled in different way depending on the php-imagick or php-gd
version used. Try to update php-imagick and disable php-gd
I had this problem, tcpdf not displaying PNG only images.
(provided tbe path of the images are correct)
It is definetely a GD version problem, at least when you still use old versions of PHP (like 5.3). Uninstalling/removing Gd is often not an option, because it is used elsewhere.
Here is how I fixed it: the general idea is to force TCPDF to use imagemagick instead of GD for PNG files. Without removing GD.
Steps:
Install imagemagick dev packages
On debian:
apt-get -y install libmagickwand5 libmagickwand-dev
Install imagemagick PECL extension (via apt or by compiling it->google is your friend)
don't forget to activate
echo "extension=/usr/lib/php/20090626-zts/imagick.so" > /etc/php5/conf.d/41-imagick.ini
in TCPDF somewhere (top of the file?) define a global variable:
define('USE_GD',0);
in tcpdf.php (my version is tcpdf 5.0.002) within the function public function Image($file, $x='', $y='', $w=0, $h=0, $type=''....) near line 5305:
find
if ( (method_exists($this, $mtd)) AND (!($resize AND function_exists($gdfunction))))
replace by (USE_GD added)
if (USE_GD && (method_exists($this, $mtd)) AND (!($resize AND function_exists($gdfunction))))
find (a few lines below)
if (function_exists($gdfunction)) {
replace by (USE_GD added)
if (USE_GD && function_exists($gdfunction)) {
and generally speaking everywhere function_exists($gdfunction) is mentioned
Because I had the same problem i pick up this old problem. In my case the solution was simple:
Open the Image with Photoshop --> Save for web
I know this is not a real solution for the problem, but it could be a simple work-around that saves you a lot of time.

PHP JPEG Functions Not Working

Any PHP functions that deal with JPEGs don't seem to be working on my server.
This code:
<?php
$im = imagecreatetruecolor(120, 20);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5, 'A Simple Text String', $text_color);
header('Content-type: image/jpeg');
imagejpeg($im);
imagedestroy($im);
?>
creates an empty file.
Using a GIF or PNG function will create an image containing the text "A Simple Text String" as expected.
This:
$im = imagecreatefromjpeg("test.jpg");
returns
Warning: imagecreatefromjpeg() [function.imagecreatefromjpeg]: 'test.jpg' is not a valid JPEG file in /path/to/test.php on line 2
A phpinfo() shows:
gd
GD Support enabled
GD Version 2.0 or higher
FreeType Support enabled
FreeType Linkage with freetype
FreeType Version 2.3.9
T1Lib Support enabled
GIF Read Support enabled
GIF Create Support enabled
JPG Support enabled
PNG Support enabled
WBMP Support enabled
And the webserver can read any relevant files.
GIF and PNG functions work fine, and as expected.
Any ideas?
EDIT:
Found this in my Apache error log file:
gd-jpeg: JPEG library reports unrecoverable error: Wrong JPEG library version: library is 80, caller expects 62
Your error log clearly shows that your PHP is compiled against/requires libjpeg version 62, while the library on your server is version 80.
Either install the correct version of libjpeg, or recompile gd/php.
It appears that the file test.jpg doesn't exist, or isn't the correct filetype headers (eg, if someone renames a test.png as test.jpg it will still have the .png headers). Try creating a new test.jpg file using an image editing program and see if it works.
An answer that worked for me was to work around the image altogether and trearit as a string.
Ill try to do it the standard way, but if it doesnt work, try it as a string
$src = imagecreatefromjpeg($file);
if (!$src) {
$src = imagecreatefromstring(file_get_contents($file));
}
There are apparently some issue wilth older versions or combos of GD an PHP.
In my case I had an image using a newer version/compression of jpeg 7 I think.

Categories