Magick.NET icon indicating copy to clipboard operation
Magick.NET copied to clipboard

How to get layer information of psd, so as to rebuild the whole image with the extracted layers

Open wyshmily opened this issue 6 years ago • 16 comments

Thanks for this great tool, I can get all the layers of psd file easily. But I still need more info of the layers to rebuild the image with the sub layers ( not with the first thumb image of psd file).

wyshmily avatar Oct 22 '19 03:10 wyshmily

I am sorry but I have no idea what you are asking? What kind of extra information do you need?

dlemstra avatar Oct 22 '19 05:10 dlemstra

I mean for example the visibility of layer, and the z order of layers

wyshmily avatar Oct 22 '19 06:10 wyshmily

I found the IMagickImage.Compose Property covers the visibility, and the layers in MagickImageCollection are already in proper order.

Now I am looking for property that describes the mask of a layer. Need some help, thanks !

wyshmily avatar Oct 22 '19 07:10 wyshmily

I have this test psd file 2016-12-19.psd image

My job is to extract layers from the psd, and then reproduce the picture in our own editor. I made a small demo to exam this, with the following (WPF) code :

            // extract layers from psd file

            string path = @"C:\Users\wyshmily\desktop\test\";
            string psdFile = Path.Combine(path, "2016-12-19.psd");
            List<PsdLayer> layers = new List<PsdLayer>();
            using (MagickImageCollection magickImages = new MagickImageCollection(psdFile))
            {
                int i = 0;
                foreach (var image in magickImages)
                {
                    string layerFile = Path.Combine(path, $"{ i }.png");
                    image.Write(layerFile);

                    // skip the first combined thumbnail, and only display layers of Compose == Over
                    if (i++ == 0 || image.Compose != CompositeOperator.Over) continue;

                    layers.Add(new PsdLayer
                    {
                        FileName = layerFile,
                        Left = image.Page.X,
                        Top = image.Page.Y,
                        Width = image.Page.Width,
                        Height = image.Page.Height,
                    });
                }
            }
    <Viewbox Width="1024" Height="670" >
        <ItemsControl Width="2048" Height="1340" ItemsSource="{Binding Layers}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemContainerStyle>
                <Style TargetType="ContentPresenter">
                    <Setter Property="Canvas.Left" Value="{Binding Left}" />
                    <Setter Property="Canvas.Top" Value="{Binding Top}" />
                </Style>
            </ItemsControl.ItemContainerStyle>
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type local:PsdLayer}">
                    <Image Width="{Binding Width}" Height="{Binding Height}" Source="{Binding FileName}" Stretch="Uniform" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Viewbox>

And I got this : image

You see that some image layers are incorrectly placed, that's because those layers have masks in the original psd file (Rectangles with rounded corner).

Does MagickImage.net read mask infomation from psd file? And how can I find the access ?

Thanks again !

wyshmily avatar Oct 22 '19 11:10 wyshmily

ImageMagick reads the opacity mask but it looks like you want to some kind of other mask. How does this look in Photshop?

dlemstra avatar Oct 22 '19 18:10 dlemstra

I think it is indeed an opacity mask. In photoshop cc, it is called Clipping Mask in the context menu.

See the following screenshots .

image layer with clipping mask applied : image

the original image : image

the clipping mask : image

With the code I posted above, I got all the layers including image layers and clipping mask layers, just have no idea how to get the relationships, or is it possible to get the merged images with masks applied directly.

wyshmily avatar Oct 23 '19 02:10 wyshmily

Another minor problem, you see that the layer names contain Chinese Characters, and with Magick.NET I got layers names of mess code, like this : image

What is the default encoding ?

wyshmily avatar Oct 23 '19 03:10 wyshmily

@dlemstra could you please take a look at this, I need your help.

wyshmily avatar Oct 29 '19 02:10 wyshmily

Why do you really need all the layers and not just the combined image? And I don't think that you should have the statement image.Compose != CompositeOperator.Over in your check. That might break it? And the label names probably need to be converted to UTF8 to read them.

dlemstra avatar Nov 04 '19 19:11 dlemstra

@dlemstra Thanks for your reply.

I need the layers because I'm working on an Editor Program a bit like photoshop, with layers supported. And I'm trying to import psd to our editor.

So currently such mask relationships between layers are not avaliable, am I right ?

wyshmily avatar Nov 05 '19 06:11 wyshmily

If there is an opacity mask in a layer the mask will directly be applied but other masks will not be detected.

dlemstra avatar Nov 07 '19 12:11 dlemstra

@dlemstra do you think I should post an issue at ImageMagick, for this kind of feature: detect and apply clipping mask layer

wyshmily avatar Nov 08 '19 02:11 wyshmily

You could open an issue there instead but I have no idea when we will be able to work on this.

dlemstra avatar Jan 02 '20 09:01 dlemstra

@dlemstra @wyshmily Did this ever get resolved?

PtrStruct avatar Nov 16 '20 21:11 PtrStruct

Turns out support for non ASCI layer names was added in 7.17.0.0: https://github.com/dlemstra/Magick.NET/discussions/620#discussioncomment-8943

dlemstra avatar Nov 16 '20 23:11 dlemstra

@dlemstra Oh I should of been more specific, my bad. I was talking about the clipping layer mask issue.

PtrStruct avatar Nov 17 '20 16:11 PtrStruct