TCPDF: PNG image rendered incorrectly - php

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.

Related

Getting error message on Cpanel using Imagick

I am using Imagick to edit and save svg image.
I am getting an error when I save svg image after having croped it.
Here is my code to operate svg images:
$image = new Imagick();
$image->readImage($path1);
$image -> cropImage($rw*11.2, $sw*7.7, 0, 0);
$image->writeImage('Cvilogpdfbackend/core/images/tempimage/'.$targetfile.'.svg');
When i call this function, I am getting bellow error
PHP Fatal error: Uncaught ImagickException: delegate failed
`'potrace' --svg --output '%o' '%i'' #
error/delegate.c/InvokeDelegate/1897 in
/home/civilogc/public_html/resizeimage.php:19 Stack trace:
#0 /home/civilogc/public_html/resizeimage.php(19): Imagick->writeimage('Cvilogpdfbacken...')
#1 {main} thrown in /home/civilogc/public_html/resizeimage.php on line 19
How to solve this issue?
Why would you want to use mainly bitmap/raster based image processing library (ImageMagick) to modify vector SVG images?
Let me first point you to do the right way:
ImageMagick should be mostly used for reading and writing bitmap images and for creating/writing SVG images (and other vector based format if required, e.g. EPS, PDF etc).
Instead of using ImageMagick/Imagick for your conversion (changing vector image to bitmap and back again - losing quality) just read your image for example with this code:
$image = file_get_contents($path1);
$svg_dom = new DOMDocument();
$tmp_obj = $svg_dom->getElementsByTagName("svg")->item(0);
$svg_width = floatval($tmp_obj->getAttribute("width"));
$svg_height = floatval($tmp_obj->getAttribute("height"));
$svg_viewbox = floatval($tmp_obj->getAttribute("vieWBox"));
and then I suggest you just calculate the new viewBox with your cropping adjustment (create a function for that) and set it back, optionally set new width and height as well:
$svg_viewBox = calculateCroppedView($svg_viewbox, $new_width, $new_height, $top, $left);
$tmp_obj->setAttribute("viewBox", $svg_viewBox);
$tmp_obj->setAttribute("width", $new_width."px");
$tmp_obj->setAttribute("height", $new_height."px");
file_put_contents('Cvilogpdfbackend/core/images/tempimage/'.$targetfile.'.svg', $svg_dom->saveXML());
Note: you are not really cropping the SVG image (SVG elements), just changing the view (e.g. zoom) to it. Converting all cut paths, shapes, text etc is possible but would require a lot of coding. Either way the goal is to keep the (vector) image quality.
For an excellent explanation of the SVG viewBox attribute read this section:
https://css-tricks.com/scale-svg/#the-viewbox-attribute
To answer your question:
This error states that ImageMagick in your webserver cannot find or doesn't have installed the (free) potrace software that does the actual vectorization of a bitmap image.
Note: you need to have ImageMagick version 7 since older version just embedded bitmap images and data encoded (base64) string to the SVG image tag or maybe used a weird conversion - depending of ImageMagick version - of converting dots to 1px SVG circle tags. And ImageMagick installed needs to be the same version as Imagick as well for the mentioned reasons.
Potrace software command line is set in delegates.xml of the ImageMagick/Imagick installation and ImageMagick or Imagick needs to find potrace in the PATH (environment variable).
I suggest you to contact your web hosting provider to install Potrace that can be downloaded here:
http://potrace.sourceforge.net/#downloading
And then you'll have to test your script, most likely your web hosting provider will already solve the issue just by installing Potrace. Maybe a path to it will need to be added to a user/system PATH variable and that should practically solve your issue.
If not, you can try to use ImageMagick (convert or now renamed magick, main program) and potrace using exec() command in PHP yet your web hosting must allow that since it's usually forbidden in PHP configuration.
To go for other help:
Well, ask a question here on SO or on ImageMagick support forum that based on their main site forum (where you cannot register anymore) is now here:
https://github.com/ImageMagick/ImageMagick/discussions

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'];

DOMPDF images have poor quality when processing in server

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

Typo3: ImageMagick combine does not work

I'm looking to use image masks in Typo3. After trying out various things and none of them worked, I decided to check out the install tool.
Install tool says ImageMagick is installed correctly, paths are correct and all image test complete successfully, except the convert/combine test. The test says "There was no result from the ImageMagick operation".
Also, when I'm using gifbuilder to output an image the image's dimensions get read correctly, allthough the outputted image stays blank. (which is white or another color when I have backColor set)
I am using:
Max OSX 10.7.5
XAMPP
PHP 5.3.1
Typo3 6.0.4
ImageMagic 6.7.3-2
Here is some test typoscript code (which on my install results in a fully red image instead of the original image)
lib.test = IMAGE
lib.test {
file = GIFBUILDER
file {
XY = [10.w],[10.h]
backColor = #FF0000
10 = IMAGE
10.file = fileadmin/user_upload/test.jpg
}
}
Attached is the result from the combining images test.
Does anyone have an idea as to what I might be doing wrong?
Some newer imagemagick versions use composite as command instead of combine. There is an option in the install tool to set the command to use. The setting is called [GFX][im_combine_filename].

How do I process jpg files using ImageMagick (IMagick API)? I am getting an exception, NoDecodeDelegateForThisImageFormat, whenver I try

I am using ImageMagick with the PHP IMagick API to process uploaded jpg files - however, when I try to read a Blob or even read a physical file, I get a NoDecodeDelegateForThisImageFormat exception.
An example of the code I am using is below:
private function resizeImageBlob($blob, $width, $height) {
$image = new Imagick();
$image->readImageBlob($blob);
$image->resizeImage($width, $height, IMAGICK::FILTER_LANCZOS, 1);
$resizedBlob = $image->getImageBlob();
return $resizedBlob;
}
The image that the blob represents is a jpg image, but ImageMagick throws the exception when it tries to read the line:
$image->readImageBlob($blob);
Does anybody know why this might be happening?
I figured out the answer to my problem. The reason the exception was occurring was indeed due to the fact that the library did not have jpeg support built in, but the reason this happened was because the Imagick php extension's version and the ImageMagick library's version were different.
A good way to make sure not to run into this problem is to download both the ImageMagick library and the Imagick php extension, and specifically look at the versions to see that they match.
Alternatively, you can check the version of your Imagick php extension in the php/ext folder by enabling it in your php.ini file, and using
echo phpinfo();
to check the version of the extension. Then, you can download the same version of the ImageMagick library.

Categories