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
Related
I am using a PHP Thumbnail Generating script that I have used without issue many times in the past. I am currently using it without issue on the very same domain that I am now having problems.
The script is processing to a point. It is generating physical thumbnail images and saving them into the preset cache directory but it is not returning resized images to the browser.
The image src is in the following format:
<img src="thumbnail.php?file=sample/02.jpg&w=100&h=70&el=0&gd=0" />
I have confirmed that the image exists and can be displayed in a browser itself.
Also, the PHP script loads ok as I have tested it by adding an 'echo' to confirm.
I have installed this script in multiple locations on the server and the result is the same. I have even tried other versions of PHP Thumbnail Generators and none of them produce resized images in the browsers.
I have checked that GD is active on my server:
GD Support enabled
GD Version bundled (2.1.0 compatible)
FreeType Support enabled
FreeType Linkage with freetype
FreeType Version 2.4.2
GIF Read Support enabled
GIF Create Support enabled
JPEG Support enabled
libJPEG Version 6b
PNG Support enabled
libPNG Version 1.2.44
WBMP Support enabled
XBM Support enabled
PHP is version 5.3.29
Imagemagick is available and path confirmed as '/usr/bin/convert/'.
Here you see the result:
http://demos.mitey.co.nz/image_processor/index.php
All that appears is broken image placeholders instead of the dynamically generated thumbnails.
All relevant permissions have be set to 0777 or 0755, tried both.
This really isn't a difficult script to use and I have numerous times in the past but I am unable to debug whatever is causing it to fail in this instance.
Anybody have any ideas as to what could be stopping the image source from correctly processing the PHP contained within it?
I have tried so many different things that I can no longer focus on the issue and come up with anything else to try.
SOLVED: I was trying to load images into the script from another sub-domain. The Thumbnail script I was using claims to allow loading images from another domain using http however it thens fails when it comes to the PHP function 'file_exists' which does not work via the http protocol. I removed the 'http://' part of the image path using 'str_replace' and replaced it with the file system path, i.e. /home/siteroot/' and all works as expected. When used with images on the same domain as the thumbnail generating script the script is happy for the full 'http://' path to remain. There was no useful error messages to point this out.
Download the latest PHPthumb from website
For generate thumb see documentation
don't forget to Change variable as per your need.
$thumbUrl = "somefolder/new.jpg";
$resizeWidth = "70"; // in pixels
$resizeHeight = "70"; // in pixels
$imageThumb = $directoryPath. "/phpThumb/phpThumb.php?src=" . $thumb1 . "&w=".$resizeWidth."&h=".$resizeHeight."&iar=1&hash=90e9d46c4d138a72574c52e31fbef0dc";
echo '<img src="'.$imageThumb.'" alt="filename.jpg" />';
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
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.
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.
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.