Page 2 of 2

Re: quality of downsampled images once JPEG compressed

Posted: 2011-04-16T18:47:14-07:00
by NicolasRobidoux
fmw42 wrote:
Doing it "straight" ("no blur" postfix) and doing it by enlarging -define filter:blur depending on the requested quality ("blur" postfix)
Can you explain what you mean by this? Sounds like minifying by enlarging, but that seems rather strange.
I should have posted the code outside of the tar archive. Here it is. It is based on code Fred put together earlier.

Code: Select all

#!/bin/bash

# For best results, use with IM compiled with --enable-hdri.
# Reason:
# The conversion to YCbCr may lead to negative (intermediate) color
# values. I (Nicolas Robidoux) am not completely sure that conversion
# to YCbCr for the resampling part of the computation is totally
# necessary.
# Rationale for the conversion:
# 1) Conversion to a "linear" colorspace for resampling purposes, and
# 2) (hopefully) smoother values in the colorspace actually used by
# JPEG, which leads to smaller compressed files for a fixed quality
# level.

# test image from http://www.pbase.com/konascott/image/69543104/original
infile="original.jpg"

# Warning: quality = 0 has a special meaning.

# A wide range of quality value gives good results. Without actively
# looking for artifacts, knowing what to look for, or zooming in,
# no-one should notice any compression artifacts above, more or less,
# quality = 80. For thumbnails produced with the lanczos2sharp filter
# (see below), compression artifacts are nearly invisible, even when
# zooming, at quality = 98.
# Note that "2x2" below hardwires chroma subsampling (meaning that
# 4:2:0 chroma subsampling is always on, irregardless of the requested
# quality).  IMHO, 4:2:0 should be used even when the quality is high
# and the thumbnail small. If you want "true" maximal quality, remove
# "-sampling-factor 2x2" when you are using a very high quality level
# (97 and above, say), even though it is a waste from a perceptual
# viewpoint.

size="512x512"

# I don't believe that -distort resize works in PerlMagick, and I
# don't think that the lanczos2sharp and lanczossharp filters are
# available ether (they should only be used with distort anyway).
# Use the slightly inferior (IMHO)
#   -filter lanczos -resize
# or
#   -filter lanczos2 -resize
# instead.
# I don't think that additional sharpening is needed with distort
# lanczossharp, distort lanczos2sharp, or resize lanczos. Maybe (?)
# with resize lanczos2. For a fixed quality level, sharpening
# Increases file size and the visibility of JPEG artifacts. Let me
# know if you want additional sharpening.

# In the following, I set the extra "blur" for the versions with extra
# smoothing by interpolating linearly from 1.5 when quality = 0 to 1
# (=none) when quality = 100. I've not studied things too carefully,
# but this seems to strike a reasonable balance between JPEG artifact
# reduction and sharpness.

for quality in 30 40 50 60 65 66 67 68 69 70 75 80 85 90 95 98; do
    for filter in lanczos2sharp lanczos lanczossharp; do
	convert $infile \
	    -colorspace YCbCr \
	    -filter $filter \
 	    -distort resize $size^ \
	    -gravity Center \
	    -crop $size+0+0 \
	    +repage \
	    -colorspace sRGB \
	    -sampling-factor 2x2 \
	    -quality $quality \
	    -strip \
 	    $quality\_$filter\_noblur.jpg
	blur=$(echo "1.5-.005*$quality" | bc -q 2>/dev/null)
	convert $infile \
	    -colorspace YCbCr \
	    -filter $filter \
	    -define filter:blur=$blur \
 	    -distort resize $size^ \
	    -gravity Center \
	    -crop $size+0+0 \
	    +repage \
	    -colorspace sRGB \
	    -sampling-factor 2x2 \
	    -quality $quality \
	    -strip \
 	    $quality\_$filter\_blur.jpg
    done
done

for quality in 30 40 50 60 65 66 67 68 69 70 75 80 85 90 95 98; do
    for filter in lanczos; do
	convert $infile \
	    -colorspace YCbCr \
	    -filter $filter \
	    -resize $size^ \
	    -gravity Center \
	    -crop $size+0+0 \
	    +repage \
	    -colorspace sRGB \
	    -sampling-factor 2x2 \
	    -quality $quality \
	    -strip \
	    $quality\_resize\_noblur.jpg
	blur=$(echo "1.5-.005*$quality" | bc -q 2>/dev/null)
	convert $infile \
	    -colorspace YCbCr \
	    -filter $filter \
	    -define filter:blur=$blur \
	    -resize $size^ \
	    -gravity Center \
	    -crop $size+0+0 \
	    +repage \
	    -colorspace sRGB \
	    -sampling-factor 2x2 \
	    -quality $quality \
	    -strip \
	    $quality\_resize\_blur.jpg
    done
done
What I meant is this: When you filter, you can use -define filter:blur=2, say, to double the smoothing effect of a filter kernel. You can, for example, double the sigma of Gaussian blur this way. (I'm using various Lanczoses.) It is my opinion that increasing the "strength" of the low pass filter used to downsample is better than applying some form of blur separately.

-------

RE: HDRI:

I'm not totally sure its needed, but I'm converting to YCbCr which, if I understand properly, can get negative values if converted to/from, say, RGB or sRGB. So, I've not checked that the script gives bad results if you don't use and hdri-enabled IM, I just played it safe, given that my understanding is that non-hdri IM won't store negative intermediate values.

Re: quality of downsampled images once JPEG compressed

Posted: 2012-01-30T11:26:35-07:00
by fmw42
toddb570 wrote:Hi,

I am also using the convert process to resize images down to various sizes based on site configuration, For example 800x800, 400x400, 350x350, 120x120 and 60x60).

I need to rezize those image to all those sizes for my couple of website.But when I compressed the size I don not find the quality what I want. By the Way, all of those images are in JPEG format.

Any help or suggestions would be greatly appreciated
This should be posted in the User's topic as it is IM specific.

Please repost there and provide your command line so we can see what you are doing. Also identify your IM version and platform as some syntax varies on windows. But note that when you start with a jpg and end with a jpg, you will lose quality as the image has to be decompressed and recompressed and jpg is a lossy compression. Also you may not get the same output quality factor as the input so you may need to provide the -quality argument.

see

http://www.imagemagick.org/Usage/formats/#jpg
http://www.imagemagick.org/Usage/formats/#jpg_write
http://www.imagemagick.org/script/comma ... hp#quality

Re: quality of downsampled images once JPEG compressed

Posted: 2012-01-31T06:28:23-07:00
by anthony
NicolasRobidoux wrote:I just noticed that -distort resize leaves a one-pixel wide "light" band around the edge of the image. :-(

Corrected: It is not -distort resize that leaves a "light" band around, it is unsharp. I imagine this can be fixed with an appropriate choice of alpha/virtual-pixel.
Correct. distort -resize goes through some 'acrobatic hoops' to ensure that virtual-pixels do not contribute to the results, just as -resize directly ignores virtual-pixel effects. other convolution and morphology (local area effect) operations does not do this.

One proposed 'channel' addition to IMv7 is a 'read-mask' that can say 'these pixels are NOT to contribute to results'. This can be used to exclude pixels from area effect operations (like convolutions). A "-virtual-pixel none" setting could in effect make operations ignore virtual pixel contributions (EG in blurs, and sharpening methods :-)

ASIDE: at this time Cristy is working on the existing write mask handling. (see -clip, -clip-path, and 'compose mask' information). This will allow IMv7 operations to ignore the processing of a pixels that can't be written because of 'write mask', something that can be a big saving in some convolutions. This is NOT possible in the pixel cache handling of IMv6

Re: quality of downsampled images once JPEG compressed

Posted: 2012-01-31T06:37:03-07:00
by anthony
NicolasRobidoux wrote:(I'll repost when I figure out how to unsharp without the boundary "red drift.")
The 'trick' used for "-distort Resize" is to make virtual pixels transparent, then remove transparency afterward. Transparent pixels can not (should not) contribute to color channels as color in transparency is suposed to be 'undefined'.

Of course if the image also contains a alpha channel, then preventing virtual-pixel contribution requires the alpha to be separately processed as a color channel, so that you can then mark virtual pixels using transparency, and ignore its contributions.

Distort resize also does this if alpha is enabled on the image!

See the discussion, that created Distort Resize for examples...
viewtopic.php?p=68362#p68362
It is summarized in the second part of Distort Resize in IM Examples...
http://www.imagemagick.org/Usage/distorts/#resize


NOTE: "-distort Resize" and its processing of its argument as a 'geometry' rather than a 'list of floats' is a HACK.
It really is more of a operator that uses 'distort' as part of its processing.

I am thinking of removing that 'hack' and making it an operator completely separate to distort as part of IMv7.

It would probably be part of a merging of all the 'special' resizes into method-type resize operator.
EG: merger of special resize methods...
interpolative (using the -interpolate setting, rather than a filter)
adaptive (actually interpolative mesh)
scale (interpolating box)
sample (interolative nearest-neighbour)
liquid
distort (or EWA cylindrical filtered resize)