Page 1 of 1

-resize followed by -layers merge on PSD file

Posted: 2010-06-29T02:20:28-07:00
by axelrose
Hello all,

I found it confusing to get different results when converting a PSD (containing
an alpha channel) depending on the order of options:

Code: Select all

convert hevertotox.psd -resize 100x100 -layers merge heverotox-resized-merged.jpg

Code: Select all

convert hevertotox.psd -layers merge -resize 100x100 heverotox-merged-resized.jpg
The images can be found here:

http://dl.dropbox.com/u/84530/IM/hevertotox.psd
http://dl.dropbox.com/u/84530/IM/hevero ... esized.jpg
http://dl.dropbox.com/u/84530/IM/hevero ... merged.jpg

It would be nice if the resize operation would work on unmerged layers as well.


Thanks for you help
Axel

Re: -resize followed by -layers merge on PSD file

Posted: 2010-06-29T05:01:22-07:00
by snibgo
I think this is the expected bahaviour, not a bug.

When that file is read, you will have a sequence of 4 images. "-resize" works on the last image in the sequence. I can't think of a way to make it work on all the images in the sequence unless, of course, you "-layers merge" first.

Re: -resize followed by -layers merge on PSD file

Posted: 2010-06-30T00:06:25-07:00
by axelrose
I understand that this has low priority for the developers.

Nonetheless I see no reason for "-resize" to work only on the last layer and ignore all others.


Cheers,
Axel.

Re: -resize followed by -layers merge on PSD file

Posted: 2010-06-30T06:28:20-07:00
by snibgo
Most IM operations (blur, crop, level, sharpen and so on) operate on a single image. If they were changed to operate on all the images, huge numbers of scripts would no longer work.

EDIT: Incidentally, I have heard but can't confirm that layer 0 of PSD files are a pre-flattenend version of the entire image. If so, you don't need to flatten them yourself:

convert hevertotox.psd[0] -resize 100x100 hevertotox-resized.jpg

Re: -resize followed by -layers merge on PSD file

Posted: 2010-07-01T19:48:37-07:00
by anthony
snibgo wrote:I think this is the expected bahaviour, not a bug.

When that file is read, you will have a sequence of 4 images. "-resize" works on the last image in the sequence. I can't think of a way to make it work on all the images in the sequence unless, of course, you "-layers merge" first.

-resize works on ALL images in the image sequence independantally of each other. as such ALL the images were resized separatally, before thay were merged, just as the user specified. Most image operators do this. Including blur, crop, distort etc.

Only 'image list operators' like -fx, -layers, -flatten, -composite etc.. apply the operator over
all the images in memory together!

See IM Examples, Basics, Types of Options - Operators and Settings...
http://www.imagemagick.org/Usage/basics/#options

It is the special 'unique' operator -geometry that will resize only the last image. This usage is not recommended and only provided for legacy and easier layering techniques. The -geometry operator's true role in "convert" and "composite" is to specify an images offset in a image composition or animation. It is used for other (related) things in "display" and "montage".

See IM Examples, Resizing Images, Geometry
http://www.imagemagick.org/Usage/resize/#geometry

The difference here is that after merging all the images will have been merged into ONE image, so when resize is applied it resizes the single image. The Order is important! See the VERY first this in IM exmaples..
Basics, ImageMagick Command Line Processing
http://www.imagemagick.org/Usage/basics/#cmdline

If it wasn't for the order, we would have the mess we had in IM version 5 where just about anything could happen when multiple operations was specified, and you could only trust IM to do one operation per command! It was a horrible time for everyone!

Re: -resize followed by -layers merge on PSD file

Posted: 2010-07-02T08:24:48-07:00
by axelrose
Thanks Anthony for your nice explanation.

Meanwhile I found out what is going on here.

The PSD has four layers. One of them, the alpha channel, has a different
aspect ratio. If I "-resize 100x100" the aspect ratio is preserved. But
now merging layers with different aspect ratios give unpredictable results.

Using my sample data and this little script

Code: Select all

#!/bin/bash

C=/path/to/imagemagick/bin/convert
I=/path/to/imagemagick/bin/identify

IN=/tmp/hevertotox.psd
cd /tmp

for layer in 0 1 2 3; do
    cmd="$C $IN[$layer] h-$layer-0.jpg"
    # echo $cmd
    eval $cmd
    cmd="$C $IN[$layer] -resize '100x100>' h-$layer.jpg"
    # echo $cmd
    eval $cmd
done

echo "without resize"
echo "--------------"
for layer in 0 1 2 3; do
    $I "h-$layer-0.jpg"
done

echo "   with resize"
echo "--------------"
for layer in 0 1 2 3; do
    $I "h-$layer.jpg"
done
I get these results:

Code: Select all

without resize
--------------
h-0-0.jpg JPEG 1479x1560 1479x1560+0+0 8-bit DirectClass 1.901MB 0.010u 0:00.019
h-1-0.jpg JPEG 1128x465 1128x465+0+0 8-bit DirectClass 1.221MB 0.010u 0:00.019
h-2-0.jpg JPEG 596x1490 596x1490+0+0 8-bit DirectClass 1.537MB 0.020u 0:00.019
h-3-0.jpg JPEG 475x1299 475x1299+0+0 8-bit DirectClass 1.599MB 0.010u 0:00.019
   with resize
--------------
h-0.jpg JPEG 95x100 95x100+0+0 8-bit DirectClass 1.221MB 0.010u 0:00.009
h-1.jpg JPEG 100x41 100x41+0+0 8-bit DirectClass 1.212MB 0.010u 0:00.019
h-2.jpg JPEG 40x100 40x100+0+0 8-bit DirectClass 1.215MB 0.010u 0:00.009
h-3.jpg JPEG 37x100 37x100+0+0 8-bit DirectClass 1.216MB 0.010u 0:00.009
The alpha channel is within "h-1.jpg" and after resizing has a width of 100.
All other layers have a height of 100!

Resizing works as designed. To solve my issue I could merge all layers
as a first step and don't care or find an algorithm to resize each channel
accordingly.


Regards,
Axel.

Re: -resize followed by -layers merge on PSD file

Posted: 2010-07-04T18:24:55-07:00
by anthony
The nitty-gritty....

As I said each image is resizes separately and independently of all the others.

The one image having landscape aspect ratio, will resize much more than the others containing portrait aspect ratio, but each image will still be resized differentially to achieve the result you requested (though not what you wanted).

If you just want, You can make all the images the same width or height, (just leave out just one of the resize dimensions), however each image will still be resized by different scaling factors.

Another solution is to specify the actual scaling amount, as a percentage resize argument. In this case all the image will be resized by almost exactly the same amount.
For example use... -resize 20%
See IM Examples, Resize, Percentage
http://www.imagemagick.org/Usage/resize/#percent

I said almost, because resize will still vary the actual scale of the image resize slightly, so as to always resize to the nearest integer dimension. It will not do a resize involving partial pixels sizes, only to whole pixels, so the scaling factors across all the images (even between X and Y axis) can vary slightly to ensure the final image sizes are whole pixels.

These differences are very small, and generally only noticeable when resizing very small images (which produces larger relative differences), or when multiple images are very precisely aligned in the image layers.

On the other hand -distort (using "SRT" or "Affine" distortion methods) will resize images even to partial pixels sizes, though this will generate slightly 'fuzzy' edges, which hold the partial pixel information for those edge pixels.
See IM Examples, Resize, Distort free-form resizing...
http://www.imagemagick.org/Usage/resize/#distort

That being said. The simplest and best solution is to merge the images first, and then resize so that only one image is resized. This will obviously guarantee that all the components also get resized by the same amount.