Forums / Install & configuration / 'image()' always creates png - but I do need jpg

'image()' always creates png - but I do need jpg

Author Message

Peter Schnuerer

Wednesday 01 June 2005 11:02:17 am

Hello!

I got ez Publish 3.5.2. on SuSE Linux 9.0.
The following code creates an PNG image:

{let postkarte=imagefile('design/gallery/images/logo.jpg')}
 {image($postkarte)}
{ /let}

But as the Source File is JPG - I do need JPG as output. (Because PNG looses qualitiy!)

in my image.ini I got:

[OutputSettings]
AllowedOutputFormat[]
AllowedOutputFormat[]=image/jpeg
AllowedOutputFormat[]=image/png
AllowedOutputFormat[]=image/gif

[MIMETypeSettings]
ConversionRules[]
ConversionRules[]=image/gif;image/png
ConversionRules[]=image/jpeg;image/jpeg
ConversionRules[]=image/x-xpixmap;image/jpeg
ConversionRules[]=*;image/jpeg

I tried ImageMagick, GD2 and GD... the Result has always been PNG

Can anyone help?

Peter Schnuerer

Wednesday 01 June 2005 11:52:40 pm

I would be satisfied with PNG if the qualitiy was OK. But the PNG has a very poor qualitiy.

Is there a chance of changing quality?

Might be the same Problem as here:
http://www.ez.no/community/forum/install_configuration/poor_image_quality_to_much_compression

kracker (the)

Thursday 02 June 2005 3:25:56 am

Hey,

I didn't see anyone else reply so I thought I would take a moment to think aloud about your situation.

In my experience jpeg has always held a higher resolution and general quality for certain kinds of images. No wonder that most manufacturers use jpeg for digital cameras.

So I think a jpeg to png conversion + eZ publish quality settings could be the root of your problems.

An example improvement you might consider making is in an override of the image.ini setting :
<i>settings/override/image.ini.append.php</i>

[MIMETypeSettings]
# A list of mimetypes and their image quality value
# The value varies from mime type to mime type.
Quality[]
# Set JPEG quality from 0 (worst quality, smallest file) to 100 (best quality, biggest file)
# Quality[]=image/jpeg;75
Quality[]=image/jpeg;100

ConversionRules[]
# Fallback, try to force jpeg to jpeg converstions instead of jpeg to png 
ConversionRules[]=image/jpeg;image/jpeg

Let me know if this helps any..

:| kracker
<i>Fiona Apple : Mistake</i>

Member since: 2001.07.13 || http://ezpedia.se7enx.com/

kracker (the)

Thursday 02 June 2005 5:05:54 am

hrm,

I hacked on this for quite a while and have come to the conclusion that either based on kernel code or settings the template operator image() turns just about any image run through it into a png.

You can test this by outputing some information

{let postkarte=imagefile('design/gallery/images/logo.jpg')}

{image($postkarte)}

{let postkarte_img=image($postkarte)}
{$postkarte_img|attribute( show )}
{/let}

{$postkarte|attribute( show )}
{ /let}

Not sure just why it works this way but I do know that you can opt to not use the image operator and instead build your own html image tag to output the original image full_path instead.

//kracker
<i>Coldplay : Shiver</i>

Member since: 2001.07.13 || http://ezpedia.se7enx.com/

Peter Schnuerer

Thursday 02 June 2005 9:29:00 am

Thank You! I'm afraid I can't use the oroginal file, bacause this is just the first step!

In the next step I'd like to merge two images (two JPGs) - which works fine with the image()-operator, but the qualitiy is very poor....

kracker (the)

Thursday 02 June 2005 4:34:13 pm

I wondered if that isn't what you were trying to do. Thanks for the heads up, it does help to know what your aiming for.

I see now that the image operator defaults to png in a hard coded fashion for the outputted image.
<i>lib/eztemplate/classes/eztemplateimageoperator.php</i>

Search for the line

var $StoreAs = 'png';

It's at the very bottom of the eztemplateimageoperator.php class. You can change this line to the format of your choice, for you jpg

var $StoreAs = 'jpg';

Then clear all cache. Unfortunately that did not improve the quality for me but did force it to output jpg images of the same quality level.

Fyi, you can also make this an ini setting by adding these lines into the modify() function in the same file instead. Be sure to create the an override: <i>settings/override/texttoimage.ini.append.php</i>
With the following settings to make this a modular setting:

[ImageSettings]
UseCache=enabled
#DefaultImageOperatorFormat=png
DefaultImageOperatorFormat=jpg

Search for this code:

else if ( $operatorName == 'image' )
        {
            $useCache = $this->UseCache;

And insert the following just after $useCache.

$ini =& eZINI::instance( 'texttoimage.ini' );
            $StoreAs = $ini->variable( "ImageSettings", "DefaultImageOperatorFormat" );
            $this->StoreAs = $StoreAs;

It's not perfect yet, still we are learning and making progress, up next imageoperator quality control!

//kracker
<i>Sage Francis - Personal Journals - Message Sent</i>

<i>http://www.google.com/search?hl=en&client=ig&q=ImageCreate%2C+Quality&btnG=Google+Search</i>

Member since: 2001.07.13 || http://ezpedia.se7enx.com/

kracker (the)

Thursday 02 June 2005 5:46:55 pm

well...

I have been tearing through the lib/ code assocaiated with the actual createion of the image, adding quality controll tests which have not produced beter results.

Have found this very interesting bits of documentaiton regarding this.

See:

"ImageJPEG" in <i>http://us4.php.net/imageJPEG</i>
<i>http://forums.devarticles.com/archive/t-5678/resize-pics-makes-poor-quality
http://www.nyphp.org/content/presentations/GDintro/gd8.php</i>

One guy in the php.net documentation had this to say about quality of using GD image manipulation (fyi what version of GD are you using? this makes a difference)

gzink at zinkconsulting dot com
01-Jan-2004 04:17
Don't forget that JPEG compression has artifacts! And they're not all really obvious. The PHP JPEG compression is pretty decent, but it seems to generally:

-Lighten the image overall, by a reasonable amount (never seen this before, but it will drive graphic designers crazy, you might want to darken the image before compressing it)
-Reduce saturation, especially with images with lots of points of different color within a few pixels of each other (this is a documented feature of JPEG)
-Seriously mess with blue colors, which is common to all JPEG but really annoying in some situations with blue and black or other detailed blue parts

You might want to consider using imagepng() and outputting a PNG image instead of a JPEG if any of the above affect you, or your image is not very photo-like. Sometimes I have an algorithm compare JPEG to PNG for an image and send the smaller version to the user.

Also, when using imagepng(), you should use imageinterlace() before it 95% of the time. Interlaced JPEGs load progressively, improving in quality as the image loads, so users on slower connections see the whole image at low quality. All this happens without affecting the file size (actually, sometimes the file size is smaller!) or final quality.

Hope this helps a few people out. It's not all that obvious without lots of playing around.

I only bring up these references because 1) I am not coming up with a simple solution so I'm reverting to telling you everything and leaving the details in the <i>open</i> so you can perhaps pickup where I falter or fail.

I'd also like to note that I experience similar quality degradation even when I hack in static code to replace the key areas which generate the image.

I get varying degree's of quality per original, meaning for a red image i get a red haze on the whole image after it goes through the image() operator, if it's a white image i get a white haze.

So I think the quality setting really is not the key here. I think it has to do with the subsystem used specifically. Which pushes all of this just one more step outside the realm of my understanding and abilities.

I wonder if imagemagic can do a better job in this situation, how would one test each for differences ie force it to use image magic instead of gd?

Best wishes,
//kracker
<i>Buck 65 : Bandits</i>

For those who read the forum a lot, this topic was brought up previously ...
but I couldn't find the thread, but we have gone as far as it ever did I think :|

Member since: 2001.07.13 || http://ezpedia.se7enx.com/

kracker (the)

Thursday 02 June 2005 6:23:41 pm

So ... a few follow up questions to be clear on the details of the implementation your using:

1. What version of GD and or ImageMagic do you have installed?
2. echo a phpinfo() out for your server. Do you have --with-gd or (and this is important) -with-gd=shared
3. Which leads back to what do your image.ini settings say the system your really using <i>right now</i> to convert images GD2 or ImageMagic?

Apparently from all this afternoons reading, the version and how you have apache / php (built, compiled and installed) affects image quality.

There is also a question of just why my tests were not using the function php image function, 'ImageCreateTrueColor'.
Which is reported to do a better job of retaining quality of original image under GD2.

//kracker
<i>Not giving up, just taking a breather</i>

Coldplay : Clocks

Member since: 2001.07.13 || http://ezpedia.se7enx.com/

kracker (the)

Thursday 02 June 2005 7:16:49 pm

<b>End Game : Solutions</b>

I found a solution that I consider very acceptable. I don't exactly know which image system was being used before (I guess imagemagic as I don't think even had GD installed at all) but this is what I did ...

1. Checked my server's apache/php configuration by reviewing phpinfo();

2. Installed GD2 (v2.0.28, needs to be at least v2.0.1 using yum/rpm)

3. Enabled these setting in <i>settings/override/image.ini.append.php</i>

[GDSettings]
# If set to true more advanced functionality will be available
# which is present in GD2. This requires GD2 to be compiled in
# the PHP module. HasGD2=false
HasGD2=true

[MIMETypeSettings]
# A list of mimetypes and their image quality value
# The value varies from mime type to mime type.

Quality[]
# Set JPEG quality from 0 (worst quality, smallest file) to 100 (best quality, biggest file)
# Quality[]=image/jpeg;75
Quality[]=image/jpeg;100
Quality[]=image/jpg;100

I can't even begin to tell you how <i>amazing</i> GD2 jpg output looks using the image() operator. This should be turned into a solid faq / article in the future.

4. Add a setting to make the image operator which defaults to png in a hard coded (static) fashion for the outputted image to instead use an setting just before the image is created (dynamic).
<i>lib/eztemplate/classes/eztemplateimageoperator.php</i>

Make this an ini setting by adding these lines into the modify() function in the same file instead. Be sure to create the an override: settings/override/texttoimage.ini.append.php
With the following settings to make this a modular setting:

[ImageSettings]
UseCache=enabled
DefaultImageOperatorFormat=png
#DefaultImageOperatorFormat=jpg

Search for this code:

else if ( $operatorName == 'image' )
        {
            $useCache = $this->UseCache;

And insert the following just after $useCache.

$ini =& eZINI::instance( 'texttoimage.ini' );
            $StoreAs = $ini->variable( "ImageSettings", "DefaultImageOperatorFormat" );
            $this->StoreAs = $StoreAs;

5. In the end I see that on some of my full resolution images output by the image() template operator are of greater quality using png instead of jpg, especially images which start as jpg originals and are converted to png. Odd I know but GD2 does an even better quality job with png than jpg (IMHO). So I switched my setting back to the DefaultImageOperatorFormat=png

Thanks for the fun, I learned a lot! Here's hoping you can gleam out enough to solve your breakdown as well :)

//kracker
<i>eminem : patiently waiting</i>

Member since: 2001.07.13 || http://ezpedia.se7enx.com/

Peter Schnuerer

Thursday 09 June 2005 3:04:53 am

Hi Kracker!

Thank you very much! I've been absent a few days, so I was not able yet to thank you nor to test it!

I'll do it the next days and tell you the result!

kracker (the)

Thursday 09 June 2005 3:55:04 am

No worries Peter,

Do get back to let us know just how my little explosion of ideas (positively ?) affected your development.

cheers,
//kracker

<i>Film : Napoleon Dynamite</i>

Member since: 2001.07.13 || http://ezpedia.se7enx.com/

Peter Schnuerer

Monday 13 June 2005 2:57:01 am

Thank you!

It work's with GD2 (I have 2.0.23).

But it was some hard work:

Using the Admin-Interface, the Flag "HasGD2" will regularily be set to false. I always had to correct this in the ini-file. (ezPublish 3.5.2)

I used ImageMagick at first and even when setting "IsEnabled" on "false" - it still seemed to use ImageMagick?! (cleariung cache had no effect). So I deleted Imagemagick from my [ImageConverterSettings] at all - and it worked.

The only thing, I did not get running was "transparency":

{image( $postkarte, array($logo, hash(transparency, 0.5, halign, right, valign, bottom)))}

The transparency attribute had no effect at all - but I can live with this!

Tkank you very much for helping!!!

kracker (the)

Monday 13 June 2005 4:27:54 am

Peter,

Your more than welcome. You and I had a very deep session here over the past few weeks. I'm very pleased that it has come around full circle to (at the end of the day) help you solve your primary breakdown. I hope it also serves to help others in the future.

Sorry I don't know about the transparency issue you mention :|

I would check to make sure your version of GD (or) imagemagic supports transparency and search in the code and settings heavily for any leads on how it (transparency) is implemented / used / or controlled via settings or defaults.

I am sure that if they say it's possible than it is possible, but exactly how it is possible is not always readily apparent.

best regards,
//kracker

<i>eminem : we came to party</i>

Member since: 2001.07.13 || http://ezpedia.se7enx.com/

Esteban Rodriguez

Friday 23 December 2005 7:50:00 am

Great Job, Kracker, you really took a lot of trouble. I found your posts very helpful.

We were having trouble with the image conversion, had a site where we needed to merge the image of a product with a sign marking it as sold.
Using image-gd we were having lots of artifacts on the .png, and it was shifting the whole image to some sort of sepia color (images had a red background, so I guess it's what you experienced about the red shade).

We installed lib-gd2, and deactivated image magic and that was it. There was no need to change any further settings. Granted the images are converted to png, but that's ok with me.

Just in case anybody else needs it... you can deactivate image magik on image.ini

[ImageMagick]
Name=ImageMagick
# If set to true then this handler will be used,
# The setup wizard will turn this off it ImageMagick is not found on the system
IsEnabled=false

Don't know about the problem Peter had disabling ImageMagik, it worked for us just clearing the cache.

pretty straightforward when you know where to find it!

I have great faith in fools; self-confidence my friends call it.

http://presencia.net

Jean-Luc Mathieu

Wednesday 03 March 2010 5:16:27 pm

I have found the reason why JPEGs are so degraded using GD : this is due to a bug in the file lib/ezimage/classes/ezimageinterface.php.

In the store() method, the ImageJPEG() method of GD is called to save the image in the JPEG format :

ImageJPEG( $imageObject, eZDir::path( array( $filePath, $fileName ) ) );

As you can see, the third parameter of this function, indicating quality of the JPEG to produce, is missing ; the GD documentation says that 75 is used in this case. That's why JPEG quality is so poor whatever the configuration.

You should modify this class to either set quality to a desired value (100 for max quality as of following) :

ImageJPEG( $imageObject, eZDir::path( array( $filePath, $fileName ) ), 100 );

... or (better solution) to load quality factor to use from [MIMETypeSettings] section of the image.ini configuration file.

Combined with modification of the eztemplateimageoperator.php file, it is now possible to get the image operator fully usable with JPEGs.

Concerning the "sepia tone" images, it is probably the HasGD2=true configuration missing in the image.ini file, section [GDSettings], or the version of GD which is not 2+.