bug when converting PSD to TIFF with transparency

Post any defects you find in the released or beta versions of the ImageMagick software here. Include the ImageMagick version, OS, and any command-line required to reproduce the problem. Got a patch for a bug? Post it here.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: bug when converting PSD to TIFF with transparency

Post by fmw42 »

246246 wrote:Look carefully what I am checking. Converting to tiff from PSD results the same thing.
Mickey_PS.psd is made by Photoshop. (I don't know exactly how you made your PSD. In my case it is simply converted. It has only 1 layer.)

$ convert Mickey_PS.psd[0] MP0.tif
$ convert Mickey_PS.psd[1] MP1.tif
$ compare -metric PSNR -format "\n" MP[0].tif MP[1].tif null:
31.3439
$ compare -metric PSNR -format "\n" Mickey_Mouse.png MP[0].tif null:
31.3439
$ compare -metric PSNR -format "\n" Mickey_Mouse.png MP[1].tif null:
inf
I never use PSNR, only rmse. Nevertheless, your comparison is unfair. You do not compare a TIF saved from Photoshop to either MP0.tif or MP1.tif from IM

246246 wrote: Converting from PSD[1] to Tiff does not alter anything. So there is no bug in converting process.
The problem is that PSD[1] is not the same size as PSD[0]. PSD 1 is the size of my original Mickey PNG and has an offset. PSD 0 is the flattened PSD and has the larger size. Note that I opened the PNG into PSD and pasted it into a larger transparent background. So saving PSD 1 to TIFF will only have the size of my original and not the full size of the new PSD file

Code: Select all

convert mickey.psd mickey.tif
desktop fred$ identify mickey.tif
mickey.tif[0] TIFF 300x300 300x300+0+0 8-bit sRGB 674KB 0.000u 0:00.000
mickey.tif[1] TIFF 250x250 250x250+25+25 8-bit sRGB 674KB 0.000u 0:00.000

tif[1] looks fine, but is too small. tif[0] is the correct size, but has aliasing issues

246246 wrote: If you start from PSD[0], any conversion with IM cannot generate the same one as the original, because we don't know how Photoshop changed original to PSD[0].
True right now. That is what we are struggling to resolve. GIMP can convert PSD to TIFF just fine and it matches Photoshop conversion to TIFF. But IM has aliased away the boundary of the Mickey figure in its TIFF in comparison to the other two as shown in my animation
246246
Posts: 190
Joined: 2015-07-06T07:38:22-07:00
Authentication code: 1151

Re: bug when converting PSD to TIFF with transparency

Post by 246246 »

fmw42 wrote:

Code: Select all

convert mickey.psd mickey.tif
desktop fred$ identify mickey.tif
mickey.tif[0] TIFF 300x300 300x300+0+0 8-bit sRGB 674KB 0.000u 0:00.000
mickey.tif[1] TIFF 250x250 250x250+25+25 8-bit sRGB 674KB 0.000u 0:00.000

tif[1] looks fine, but is too small. tif[0] is the correct size, but has aliasing issues
True, but it is because psd[0] already has anti-aliasing issues. That's why it is not a bug I said.
fmw42 wrote:
246246 wrote: If you start from PSD[0], any conversion with IM cannot generate the same one as the original, because we don't know how Photoshop changed original to PSD[0].
True right now. That is what we are struggling to resolve. GIMP can convert PSD to TIFF just fine and it matches Photoshop conversion to TIFF.
I understand what you are struggling with. In this simple case, we know layer is only 1 mickey and background is just transparent, so it is probably easy to create 300x300 one from PSD[1]. But in general case, we need to know how Gimp convert PSD to TIFF from source, as long as you are satisfied with Gimp conversion (that is not 100% equal with Photoshop one though).

I know you are already trying to simulate merging using IM methods '-layers merge' etc. If you find odd behavior in it, I think it is better spotting that point only. You know RGBA processing better than I :)
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: bug when converting PSD to TIFF with transparency

Post by fmw42 »

My comparison of the PS converted TIFF to the GIMP converted TIFF is close enough. And a visual comparison shows not differences as well.

Code: Select all

compare -metric rmse mickey_ps_nolayers.tif mickey_gimp_none.tif null:
22.653 (0.000345663)
So we are trying to find out how GIMP code differs from what IM is doing. If you or anyone else have any insight into what GIMP is doing or can read the GIMP code and let us know, that would be very helpful. I am not a software engineer and do not read code well. But one of the IM developers will try to look into it when he has time. However, any help on this to speed up the time it takes to figure this out would be very welcome.
246246
Posts: 190
Joined: 2015-07-06T07:38:22-07:00
Authentication code: 1151

Re: bug when converting PSD to TIFF with transparency

Post by 246246 »

Currently only I can show you is where Gimp read PSD and write TIFF - they are "plug-ins/file-psd/psd-load.c" and "plug-ins/common/file-tiff-save.c" respectably.

And for those who have interests on batch scripting, following is a bash script to convert PSD to TIFF with Gimp. (I glanced Gimp forum, but most answers suggest to use ImageMagick because it is easier ;) )

Code: Select all

#!/bin/bash

GIMP=/Applications/GIMP.app/Contents/MacOS/Gimp

$GIMP -n -i -b - <<EOF
((lambda (filename outfile)
  (let* ((image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
         (drawable (car (gimp-image-merge-visible-layers image CLIP-TO-IMAGE))))
    (file-tiff-save RUN-NONINTERACTIVE image drawable outfile outfile 2)
    (gimp-image-delete image)))
 "$1" "$2")
(gimp-quit 0)
EOF
Above works in version 2.8.14 for Mac, it is a little special - it seems the place of interactive gimp is different by version. (See http://sourceforge.net/p/gimponosx/disc ... /ec2c465d/
http://assorted-experience.blogspot.jp/ ... x-105.html )

For other platform, simply set GIMP for proper place, in Unix "/usr/local/bin/gimp" or something.

6th argument of file-tiff-save is compression type. 2 is RLE.

To use it, give input file as 1st argument and output tif file as 2nd argument.

It generates tiff (from psd) with no anti-alias issue. (But it is still different with psd[0] and also different with psd[1].)
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: bug when converting PSD to TIFF with transparency

Post by fmw42 »

246246 wrote:Currently only I can show you is where Gimp read PSD and write TIFF - they are "plug-ins/file-psd/psd-load.c" and "plug-ins/common/file-tiff-save.c" respectably.

Thank you. I already found those and passed them on to one of the IM developers to review.
246246
Posts: 190
Joined: 2015-07-06T07:38:22-07:00
Authentication code: 1151

Re: bug when converting PSD to TIFF with transparency

Post by 246246 »

I think app/core/gimpimage-merge.c is also the key point. (See my script above, it calls "gimp-image-merge-visible-layers", and "gimp_image_merge_visible_layers" is defined there.) And I believe file-tiff-save.c is irrelevant because writing to PNG has same issue.

[EDIT 1]
Looking through the source, I think they have do nothing special. Without using flattened layer (PSD[0]), do simply merge layers (PSD[1], PSD[2] ...).

So the following should have same result. (As long as your test file, I confirmed it as below.)

Code: Select all

$ identify mickey.psd 
mickey.psd[0] PSD 300x300 300x300+0+0 8-bit sRGB 231KB 0.000u 0:00.000
mickey.psd[1] PSD 300x300 300x300+0+0 8-bit sRGB 231KB 0.000u 0:00.000
mickey.psd[2] PSD 250x250 250x250+25+25 8-bit sRGB 231KB 0.000u 0:00.000
Then

Code: Select all

$ convert mickey.psd[1] \( mickey.psd[2] -geometry +25+25 \) -compose over -composite mickey-im.tif

$ gimp -cni -b '((lambda (filename outfile)
  (let* ((image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
         (drawable (car (gimp-image-merge-visible-layers image CLIP-TO-IMAGE))))
    (file-tiff-save RUN-NONINTERACTIVE image drawable outfile outfile 2)
    (gimp-image-delete image)))
 "mickey.psd" "mickey-gimp.tif")
(gimp-quit 0)'

$ compare -metric PSNR mickey-im.tif mickey-gimp.tif -format "\n" null:
inf
(But more than 2 layers case should have to be confirmed.)

[EDIT 2]
Also Krita (2.9.6) do the same conversion. (It can be used from command line also, although I don't know how to hide splash.)

Code: Select all

$ krita --export --export-filename mickey-krita.tif -- mickey.psd 

$ compare -metric PSNR mickey-im.tif mickey-krita.tif -format "\n" null:
inf
FYI, unlike Photoshop or Gimp, it seems Krita saves the exactly same one to PSD[0] as PSD[1] if PSD file has only 1 layer (and it is nothing special i.e. opacity is 100% etc).
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: bug when converting PSD to TIFF with transparency

Post by fmw42 »

I have finally figured out how to do this. Take the first layer and make it totally transparent, since it is larger than the second layer. But since the second layer has the correct alpha blending, I then use -layers merge to place it over the fully transparent first layer.

This should provide a guide for the IM developers to do this internally when converting PSD to TIFF.

Code: Select all

convert -quiet mickey.psd \
\( -clone 0 -alpha on -channel rgba -evaluate set 0 +channel \) \
-delete 0 \
+swap -background none -layers merge +repage \
-compress none \
-define tiff:alpha=associated  \
mickey_im_none.tif

Code: Select all

compare -metric rmse mickey_im_none.tif mickey_ps_nolayers.tif null:
0 (0)
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: bug when converting PSD to TIFF with transparency

Post by fmw42 »

This same procedure (code) below seems to work for all 3 of the following PSD files.

The first image has two layers, the second and third images have 3 layers (all including the flattened layer 0). The second is the same basic image rotated but composited not overlapping. The third overlaps.


Input PSD files with PNG images just for viewing:
http://www.fmwconcepts.com/misc_tests/p ... mickey.psd
Image

http://www.fmwconcepts.com/misc_tests/p ... ickey2.psd
Image

http://www.fmwconcepts.com/misc_tests/p ... ickey3.psd
Image


Photoshop converted TIFF files with no layers:
http://www.fmwconcepts.com/misc_tests/p ... layers.tif

http://www.fmwconcepts.com/misc_tests/p ... layers.tif

http://www.fmwconcepts.com/misc_tests/p ... layers.tif

Code: Select all

convert -quiet mickey.psd \
\( -clone 0 -alpha on -channel rgba -evaluate set 0 +channel \) \
-delete 0 \
-insert 0 -background none -layers merge +repage \
-compress none \
-define tiff:alpha=associated  \
mickey_im_assoc.tif

compare -metric rmse mickey_im_assoc.tif mickey_ps_nolayers.tif null:
0 (0)

Code: Select all

convert -quiet mickey2.psd \
\( -clone 0 -alpha on -channel rgba -evaluate set 0 +channel \) \
-delete 0 \
-insert 0  -background none -layers merge +repage \
-compress none \
-define tiff:alpha=associated  \
mickey2_im_assoc.tif

compare -metric rmse mickey2_im_assoc.tif mickey2_ps_nolayers.tif null:
0 (0)

Code: Select all

convert -quiet mickey3.psd \
\( -clone 0 -alpha on -channel rgba -evaluate set 0 +channel \) \
-delete 0 \
-insert 0 -background none -layers merge +repage \
-compress none \
-define tiff:alpha=associated  \
mickey3_im_assoc.tif

compare -metric rmse mickey3_im_assoc.tif mickey3_ps_nolayers.tif null:
3.3707 (5.14336e-05)




Whereas, just converting the PSD (flattened) layer 0 does not work:

Code: Select all

convert mickey.psd[0] mickey_im_psd0.tif
compare -metric rmse mickey_im_psd0.tif mickey_ps_nolayers.tif null:
1479.38 (0.022574)

Code: Select all

convert mickey2.psd[0] mickey2_im_psd0.tif
compare -metric rmse mickey2_im_psd0.tif mickey2_ps_nolayers.tif null:
1255.3 (0.0191546)

Code: Select all

convert mickey3.psd[0] mickey3_im_psd0.tif
compare -metric rmse mickey3_im_psd0.tif mickey3_ps_nolayers.tif null:
1024.02 (0.0156256)
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: bug when converting PSD to TIFF with transparency

Post by fmw42 »

Also works with 3 layers (plus the flattened layer)

Image
http://www.fmwconcepts.com/misc_tests/p ... ickey4.psd

http://www.fmwconcepts.com/misc_tests/p ... layers.tif



Code: Select all

convert -quiet mickey4.psd \
\( -clone 0 -alpha on -channel rgba -evaluate set 0 +channel \) \
-delete 0 \
-insert 0 -background none -layers merge +repage \
-compress none \
-define tiff:alpha=associated  \
mickey4_im_assoc.tif

compare -metric rmse mickey4_im_assoc.tif mickey4_ps_nolayers.tif null:
3.71536 (5.66927e-05)
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: bug when converting PSD to TIFF with transparency

Post by fmw42 »

Dirk and I have finally figured out what is going on.

When a PSD file has transparency, the flattened layer [0] is flattened with the transparency. So when IM puts the alpha channel back on the layer [0] in appropriate output image that support transparency, it effectively has transparency added twice. What we found was that we needed to unblend the alpha from the flattened layer and then put the alpha channel back.

This fix (in upcoming IM 6.9.2.5) will be the default. That is, when saving the layer [0] from the PSD file that has transparency, the unblending (unflattening) of the alpha channel will occur automatically. Then the alpha channel will be included. If one saves this layer to PNG or TIFF, the alpha channel will be there, if desired. If one wants to save to JPG, then one will need to use IM -flatten so that the alpha channel gets properly blended. If the alpha channel is not desired, then use -alpha off before saving the image.

To turn this behavior off and get the same result as all previous versions of IM, there is a new -define psd:alpha-unblend=off, which can be used. It must come before reading the input psd file.
Post Reply