Ejemplo n.º 1
0
        /// <summary>
        /// Store layer metadata and image data.
        /// </summary>
        public static void StoreLayer(
            BitmapLayerInfo layerInfo,
            PhotoshopFile.Layer psdLayer,
            PsdSaveConfigToken psdToken)
        {
            var layer = layerInfo.Layer;

            // Set layer metadata
            psdLayer.Name = layerInfo.Name;
            psdLayer.Rect = FindImageRectangle(layer.Surface);

            psdLayer.Opacity            = layer.Opacity;
            psdLayer.Masks              = new MaskInfo();
            psdLayer.BlendingRangesData = new BlendingRanges(psdLayer);

            // Store channel metadata
            int layerSize = psdLayer.Rect.Width * psdLayer.Rect.Height;

            for (int i = -1; i < 3; i++)
            {
                var ch = new Channel((short)i, psdLayer);
                ch.ImageCompression = psdToken.RleCompress ? ImageCompression.Rle : ImageCompression.Raw;
                ch.ImageData        = new byte[layerSize];
                psdLayer.Channels.Add(ch);
            }

            psdLayer.BlendModeKey = layer.BlendMode.ToPsdBlendMode();
            psdLayer.Visible      = layer.Visible;

            // Create folders/groups before actual image data will be saved.
            if (psdToken.SaveLayers && !layerInfo.RenderAsRegularLayer)
            {
                if (layerInfo.IsGroupStart)
                {
                    var status = layer.Visible ? LayerSectionType.OpenFolder : LayerSectionType.ClosedFolder;
                    psdLayer.AdditionalInfo.Add(new LayerSectionInfo(status));
                    psdLayer.Name    = layerInfo.Name;
                    psdLayer.Visible = true;
                }
                else if (layerInfo.IsGroupEnd)
                {
                    // End of the group
                    psdLayer.Opacity      = 255;
                    psdLayer.BlendModeKey = PsdBlendMode.PassThrough;
                    psdLayer.Name         = "</Layer group>";
                    psdLayer.AdditionalInfo.Add(new LayerSectionInfo(LayerSectionType.SectionDivider));
                }

                return;
            }

            // Store and compress channel image data
            var channelsArray = psdLayer.Channels.ToIdArray();

            StoreLayerImage(channelsArray, psdLayer.AlphaChannel, layer.Surface, psdLayer.Rect);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Prepare Paint.NET's flat layer list to be exported as Photoshop layers.
        /// Indicate where layer sections begin and end and create missing layers while user can break the structure.
        /// </summary>
        private static IEnumerable <BitmapLayerInfo> PrepareLayers(IEnumerable <BitmapLayer> paintLayers, bool saveGroupLayers)
        {
            var toReturn          = new List <BitmapLayerInfo>();
            var layer             = paintLayers.FirstOrDefault();
            var openedGroupsCount = 0;
            var reversed          = paintLayers.Reverse();

            foreach (var paintLayer in reversed)
            {
                var layerInfo = new BitmapLayerInfo();
                layerInfo.Name  = paintLayer.Name;
                layerInfo.Layer = paintLayer;
                // Render as default image
                layerInfo.RenderAsRegularLayer = true;

                var isGroupLayerStart = false;
                var layerGroup        = string.Empty;

                if (saveGroupLayers && CheckIsGroupLayer(paintLayer, out isGroupLayerStart, out layerGroup))
                {
                    layerInfo.Name                 = layerGroup ?? "Layer";
                    layerInfo.IsGroupStart         = isGroupLayerStart;
                    layerInfo.IsGroupEnd           = !isGroupLayerStart;
                    layerInfo.RenderAsRegularLayer = false;
                    if (isGroupLayerStart)
                    {
                        openedGroupsCount++;
                    }
                    else if (layerInfo.IsGroupEnd)
                    {
                        if (openedGroupsCount == 0)
                        {
                            // Structure is broken. Close layer tag is before any other start.
                            // In this case we should render group as regular layer.
                            layerInfo.RenderAsRegularLayer = true;
                        }
                        else
                        {
                            openedGroupsCount--;
                        }
                    }
                }

                toReturn.Add(layerInfo);
            }

            toReturn.Reverse();
            // Add missing close groups.
            if (openedGroupsCount > 0)
            {
                for (int count = 0; count < openedGroupsCount; count++)
                {
                    var emptyLayer = new BitmapLayer(layer.Width, layer.Height);
                    var layerInfo  = new BitmapLayerInfo()
                    {
                        Layer = emptyLayer, IsGroupEnd = true, Name = "Layer end"
                    };
                    toReturn.Insert(0, layerInfo);
                }
            }

            return(toReturn);
        }