I have to check few JPEG files for quality level and give to every file corresponding quality mark. Then I must be able to choose better image by this mark.
How to decide about visual image quality?
I'm dealing with photographs. Image dimensions and even compression ratio cannot indicate
visual quality of of the image. For example, if you enlarge the image and save it with bigger quality the visual quality will be reduced...
The code is in PHP.
Any advises will be very thankful!
If you have access to the original image then SSIM is one of the better methods to do this. It'd be pretty slow to do in pure PHP, but if you can execute shell commands, check DSSIM tool (you'll need to adapt it to load JPEGs instead of PNGs).
ImageMagick has compare command that can return Mean Square Error/PSNR of the image (compared to original), but these measurements only check per-pixel differences, so they are a poor way measure distortion caused by blockyness and ringing of JPEG compression.
Related
I use imagemagick to create thumbnails from images on my website using convert like so: convert -size 220x220 %s -resize 220 -profile '*' %s", $image, $thumb and this has worked great for a long time. Thousands of images have been processed and all the thumbnails look great ... except for one. For some reason this image produces a very ugly thumbnail and I can't figure out why.
Original image: http://i.imgur.com/fCbAN.jpg
Generated Thumbnail: http://i.imgur.com/MdLCs.jpg
Does anyone have any insight as to why this might happen with my convert code?
The thumbnail has been saved with very low quality (approximately 10-15, 99 being close to lossless). I think the question is, "why did that happen".
I can think of some reasons, but you will have to experiment. I assume the images you posted are the real images (not copies done converting e.g. PNG to JPG, I mean), and the command line is complete and describes the complete image workflow.
your ImageMagick setup attempts to keep estimated image quality. You do not set a quality explicitly (e.g. -quality 75), so the thumbnail gets the same quantizer setting as the source image. Suppose the source has a low quantizer, but you do not see it due to the high-frequency component (the image is "noisy" due to scanning). When resampling, the background loses its noise and becomes a smooth gradient, which was absent in the source. And a smooth gradient is hell on low quantizers. Try explicitly setting a quality factor (40 to 99, 40 is better compressed but chunkier, 99 is very high quality but bigger file).
there is some kind of interference between the resampler and the Moiré pattern that the scanner creates in the acquired image. This is less likely, because I see a "wavelength" of about 8 pixels which isn't at all uncommon, nor do I think that with so many images you acquired, none had approximately the same size and aspect ratio of this one; which in this scenario ought to have triggered the same behaviour. You say it didn't happen, so if this image isn't uncommon for size, aspect ratio, or source (e.g. one of the very few images scanned with a Scan-o-matic 600 scanner in the batch), this scenario becomes pretty unlikely. But if it is correct, then add a Gaussian blur before resizing and it ought to fix things: e.g. -blur 2x2.
there is bad juju in the file name, and for some reason this gets the ImageMagick wrapper to interpret a command of "set quantizer to its crappiest value". REALLY unlikely (if the interpret interprets a part of the filename as an option, it shouldn't interpret it as a filename, and the rest of the filename is no longer the true filename; resulting in a "File not found" error which we don't observe. All the same, if the original file name is something like "--progressive-swedish-music.jpg", try renaming it before thumbnailing.
I'm putting my money on option #1, anyway.
Another test which you could attempt is to run the same command from ImageMagick (command line) and not from PHP.
Currently i am using gd to converting the image uploaded in jpg with
imagjpeg($data,NULL,85)
and storing it in a blob mysql field. Problem is the quality. Yes the quality is just awful. A screenshot of a window with some text inside becomes pretty hugly. (While with a game screenshot the quality is passable)
Should I use other lib than GD?
Should I use other gd format? (imagepng?)
ps. please note: this is not a duplicate.. i am not asking how to save an img to db
ps2. note that if i should change my currently format/method I have to convert something like 5000-6000 images already stored as jpg in my db
ps3. i use 85 for imagejpeg, can't use a higher value because the image size would grow more than the original version
ps4. I need to store image in db, please stay in topic
Thanks all
================================
REFORMULATING THE QUESTION
I save image (mostly software screenshots, sometime games screenshots) in BLOB field after doing an imagejpeg($resourceFromImageCreateFromString,NULL,85);
Problem I am experiencing is the image uploaded looks pretty bad in confront of the original even if it's the same size. (sometime it gets bigger because of 85)
Is the imagejpeg implementations that sucks?
ps. my simple upload script does the follow calls:
upload file
open it with "rb" (binary)
pass the data to imagecreatefromstring
pass the result to imagejpeg
Thanks again
Is there a special reason you want to store your image inside a BLOB?
What quality argument did you pass to imagejpeg()?
You can set the quality of your output with the 3rd parameter to imagejpeg(). The problem is that JPEG is not the best format for images with a lot of text - you have to choose between turning down the quality and getting a lot of artifacts in your image, or turning up the quality and having a large file size. You might consider using PNG instead.
my first recommendation would be to try saving it as a png as the quality is better.
my second recommendation is to try the quality parameter in imagejpeg($image, $filename, $quality).
recommendation #3 - I worked on a site that I had to rewrite the image storage system because they implemented just what you are doing, storing images as BLOBs in the database. Their system only had about 20K images in it and it was crashing weekly because the database could not handle the load.
The conversion process for 5-6K images should not take more than a couple hours no matter how large the images. When I converted my images to disk storage from db storage, I ran 1K images at a time and each run took 5-10 minutes.
Why do you re-code anyway if it already IS a jpeg? To save space? Well, but then you already have your answer, in part - to save space from jpg to jpg you have to save in lower quality.
You cannot specify quality with imagecopyresampled, with imagejpeg you can. Use a high(er) value for the quality parameter.
Please note that JPEG is a format optimized for storing FOTOS. Images with large areas of the same color, straight lines etc. are much better stored in a lossless format like PNG. Of course, if you have a screenshot taken from a screen with fotos as desk background you have elements of both - so choose your format according to what you want. If the foto-part is more important and you don't care as much about fonts and lines, go with jpeg. Of course JPEG can be just as good quality as PNG for screenshots as well, but then you miss out on most of its compression capabilities, you have to use a 90+% quality setting. At 100% JPEG too is lossless, but by then a PNG might actually be of smaller (file)size.
I'm implementing an image upload facility for my website. The uploading facility is complete but what I'm working on at the moment is manipulating the images. For this task I am using PHPThumb (http://phpthumb.gxdlabs.com).
Anyway as I go along I'm coming across potential issues, to do with resizing and compression. Basically I want to acheive the following results:
The ideal image dimensions are: 800px width, 600px height. If an uploaded image exceeds either of these dimensions, it will need be resized to meet the requirements. Otherwise, leave as it is.
The ideal file size is 200kb. If an uploaded image exceeds this then it will need to be compressed to meet this requirement. Otherwise, leave as it is.
So in a nutshell: 1) Check the dimensions, resize if required. 2) Check the filesize, compress if required.
Has anybody done anything like this / could you give me some pointers? Is PHPThumb the correct tool to do this in?
As long as I can see just from the docs, phpThumb should be good enough for this task.
phpThumb can be used in an easy way like this:
Call phpThumb() just like you would a normal image.
Examples:
<IMG SRC="phpThumb.php?src=/image.jpg&w=100">
<IMG SRC="phpThumb.php?src=http://example.com/foo.jpg">
See the "demo" link on
http://phpthumb.sourceforge.net for
more usage examples). Parameters that
can be passed are listed below under
"URL Parameters".
The phpThumb() website says that it has the following image-processing feature:
Quality can be auto-adjusted to fit a certain output byte size.
This looks like what you want. It works by passing a maximum byte size parameter. The readme tells you how:
maxb = MAXimum Byte size - output quality is auto-set to
fit thumbnail into "maxb" bytes (compression
quality is adjusted for JPEG, bit depth is adjusted
for PNG and GIF)
edit: it seems that we were talking about different utilities with the same name. I did not found the same functionality in the other one, so I can only recommend using what I've found.
See the gd extension, in particular the functions getimagesize and imagecopyresized.
Enforcing a file size is more difficult, the best you can do is stick with jpeg and some arbitrary level of compression; for a certain combination of dimensions+compression, you can more or less predict the final file size of the image.
As to PHPThumb, I have no idea, as I've never used it.
Lot of user opening my site in mobile,
Tell me which image type will load quickly in mobile device ,
jpg,gif,png ,
Which one is best ?
Go with PNG8 where possible and limit the color palette. Try to only use as many colors as strictly needed not more.
There are PNG tweaking tools which allow you to get rid of unnecessary chunks of that PNG. For more information on PNG chunks there is the PNG chunks specification found here.
http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html
The tweaking tool I was talking about can be found here. It runs on Linux using wine as far as I have tested it.
http://entropymine.com/jason/tweakpng/
Additionally TinySVG is a pretty interesting format. SVG graphics allow lossless rescaling and because it is in fact a XML file you can modify it in a programmatic way.
EDIT: One note on JPEG graphics. If the file size exceeds 10kb save it progressive if it is under 10bk save it baseline. It is a small optimization for JPEGs.
There is no single "best" image type. The image that loads the quickest is the smallest one. But quick loading does you no good if your image is distorted and unidentifiable.
Pick image format base on the type of image you are trying to render:
JPEG is hands down the best for photos 99% of the time when you consider perceived image quality relative to file size; but JPEG's lossy compression algorithm relies on the existence of noise (lots of soft/subtle color transitions) and a lack of sharp lines/edges in the source image for the best effect. Never use JPEG for rasterized text!
PNG is the best option for rasterized images comprised of sharp edges and smooth/solid color blocks. Basically, anytime you need clean/lossless images (logos, icons, UI elements, text, etc.—anything but photos/paintings basically), you'd use PNG. It is also the only real option when you need alpha channel/partial transparency.
GIF is the only universally support animated image format, but aside from that I would just use PNG in most cases.
SVG is for vector images, but I'm not sure how many mobile browsers support it.
From a quick read, it seems that jpeg would be the best option. However, that is dependent on any specific needs you may have for some images (ie jpeg does not do transparent backgrounds, etc.)
Also, especially for a mobile site, if the images are frequently used parts of the website's layout (ie buttons, etc.) then using CSS Sprites is a good practice as it reduces the number of elements being downloaded to the user (of course, at the tradeoff that the image(s) which are downloaded are larger).
I want to know if its possible (and how) to check for real image quality (.jpg) using the GD library.
Obviously we need to check for file size, colors, image size, and number of pixels and compare between them.
For example if an 1200x600px image has a size of 60kb probably its in bad quality. But if the image is in grey scale, or uses only some colors, then maybe its in good quality...
So... any ideas?
What you want is a no-reference image quality assessment. I don't know of a specific implementation for PHP but you can take a look in IEEE Transactions on Image Processing for algorithms.
There's an implementation with focus on JPEG compression here:
http://www.cns.nyu.edu/~zwang/files/research/nr_jpeg_quality/index.html