PHP JPEG Functions Not Working - php

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.

Related

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

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

Issues writing text to an image with PHP ImageMagick

I have attempted to create a png with imagemagick with the following code.
<?php
/* Create some objects */
$image = new Imagick();
$draw = new ImagickDraw();
$pixel = new ImagickPixel( 'gray' );
/* New image */
$image->newImage(800, 75, $pixel);
/* Black text */
$draw->setFillColor('black');
/* Font properties */
$draw->setFont('Oxin_free_promo.ttf');
$draw->setFontSize( 30 );
/* Create text */
$image->annotateImage($draw, 10, 45, 0, 'The quick brown fox jumps over the lazy dog');
/* Give image a format */
$image->setImageFormat('png');
/* Output the image with headers */
header('Content-type: image/png');
echo $image;
But I keep getting the errors below. /usr/local/zend/tmp/ is chmod'd to be 777 and owned by daemon:zend and magick-* doesnt exist. Any ideas?
httpd: FreeType library is not available `/Users/gareth.williams/Sites/_tests/texttoimg/Oxin_free_promo.ttf'.
httpd: Postscript delegate failed `/usr/local/zend/tmp/magick-tmfNBDIx': No such file or directory.
PHP Fatal error: Uncaught exception 'ImagickException' with message 'Unable to annotate image'
Look at the error messages given, it says the problem right there.
"FreeType library is not available" - ImageMagick uses the FreeType library to render fonts, you have given it a TTF to use, and it says FreeType is not installed, so it can not use the font. Install FreeType, then reinstall/recompile ImageMagick to get FreeType support.
The second error is probably ImageMagick trying to fallback to rendering the font using its postscript rasterisation support, usually this is via ghostscript (gs), hence "Postscript delegate failed". Either ghostscript is not available, or the path for the temporary file it asks ghostscript to render too/from is not writable. Could be fixed by installing ghostscript and making sure that temporary directory has full write access, as people mention in the comments to the question.
To confirm these causes, use the -list option of convert.
convert -list format : This will show you the supported file types, look for TTF, make sure it has at least r-- status, it should say something like "TTF* TTF r-- TrueType font (Freetype 2.2.1)" if FreeType is installed correctly.
convert -list delegate : This will show handling of delegated types and the command line used. It will be using one of the ps converters as a fallback.
As I say, easiest fix is to install FreeType, then recompile/reinstall ImageMagick.

php header, content type png doesn't work

I am having hard time with php headers, i'm trying to create any kind of image in my browser without saving it in a file, but no matter what i do i can't get it working.
So for example if i use this basic example from php manual:
$im = imagecreate(100, 100);
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
It would set correct header and even output that icon which u get when image is not found.
Also i use xampp which have GD enabled, here is my phpinfo GD part:
GD Support enabled
GD Version bundled (2.0.34 compatible)
FreeType Support enabled
FreeType Linkage with freetype
FreeType Version 2.4.3
GIF Read Support enabled
GIF Create Support enabled
JPEG Support enabled
libJPEG Version 6b
PNG Support enabled
libPNG Version 1.2.46
WBMP Support enabled
XBM Support enabled
Is my code is wrong or do i need to configure something?
You should not only create the image but also fill it some way:
error_reporting(E_ALL);
ini_set('display_errors', 1);
$im = imagecreate(100, 100) or die("Cannot Initialize new GD image stream");
$background_color = imagecolorallocate($im, 0, 0, 0);
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
PHP is probably outputting an error message, thus messing up the binary image data. For this reason I always disable display_errors and enable log_errors in the PHP configuration when working with image scripts; that way you can see any errors without screwing up the output. If you're sure there are no PHP errors in play, try dumping the full script output to a file (ob_start(); at the beginning of the script, file_put_contents("outfile", ob_get_clean()); at the end) and analyze that with a hex editor to see what's messing up the PNG.

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