Beispiel #1
0
        public Bitmap Render(Stream s, out IList<IPsdLayer> layers, out Size size,ShowLayerDelegate showLayerCallback, ComposeLayerDelegate composeLayer)
        {
            PsdFile file = new PsdFile();
            file.Load(s);
            //Start with a transparent bitmap (not all PSD files have background layers)
            size = new Size(file.Columns, file.Rows);
            Bitmap b = new Bitmap(file.Columns, file.Rows);

            //ImageDecoder.DecodeImage(file.Layers[0]); //Layers collection doesn't include the composed layer

            Graphics g = Graphics.FromImage(b);
            using (g){
                g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

                for (int i = 0; i < file.Layers.Count; i++)
                {
                    if (showLayerCallback(i,file.Layers[i].Name,file.Layers[i].Visible)){
                        using (Bitmap frame = ImageDecoder.DecodeImage(file.Layers[i])){
                            composeLayer(g, frame, file.Layers[i]);
                        }
                    }
                }
            }
            layers = getLayers(file);
            return b;
        }
Beispiel #2
0
 public IList<IPsdLayer> GetLayersAndSize(Stream s, out Size size)
 {
     PsdFile file = new PsdFile();
     file.Load(s);
     size = new Size(file.Columns,file.Rows);
     return getLayers(file);
 }
Beispiel #3
0
        public void MapLayers(PsdFile ps)
        {
            output.Clear();

            ps.Layers.OrderBy(l => l.Rect.X).ThenBy(l => l.Rect.Y)
                .ToList()
                .ForEach(l =>
                {
                    var nameTokens = l.Name.Split(new char[] { '-' }, 2);
                    var sizeTokens = nameTokens[0].Split('x');

                    var size = new Size(Convert.ToInt32(sizeTokens[0]), Convert.ToInt32(sizeTokens[1]));
                    var name = nameTokens[1];

                    var x = l.Rect.X - Math.Round((size.Width - l.Rect.Width) / 2.0, MidpointRounding.AwayFromZero);
                    var y = l.Rect.Y - Math.Round((size.Height - l.Rect.Height) / 2.0, MidpointRounding.AwayFromZero);

                    output.AppendText(
                        String.Format(".{0} {{ width: {1}px; height: {2}px; background-position: {3}px {4}px; }}{5}",
                            name,
                            size.Width,
                            size.Height,
                            x,
                            y,
                            Environment.NewLine
                        )
                    );
                });
        }
Beispiel #4
0
        ///////////////////////////////////////////////////////////////////////////

        public Layer(PsdFile psdFile)
        {
            PsdFile        = psdFile;
            Rect           = new Rect();
            Channels       = new ChannelList();
            BlendModeKey   = PsdBlendMode.Normal;
            AdditionalInfo = new List <LayerInfo>();
        }
Beispiel #5
0
        ///////////////////////////////////////////////////////////////////////////

        private static Color GetColor(PsdFile psdFile, int pos)
        {
            Color c = Color.White;

            switch (psdFile.ColorMode)
            {
            case PsdFile.ColorModes.RGB:
                c = Color.FromArgb(psdFile.ImageData[0][pos],
                                   psdFile.ImageData[1][pos],
                                   psdFile.ImageData[2][pos]);
                break;

            case PsdFile.ColorModes.CMYK:
                c = CMYKToRGB(psdFile.ImageData[0][pos],
                              psdFile.ImageData[1][pos],
                              psdFile.ImageData[2][pos],
                              psdFile.ImageData[3][pos]);
                break;

            case PsdFile.ColorModes.Multichannel:
                c = CMYKToRGB(psdFile.ImageData[0][pos],
                              psdFile.ImageData[1][pos],
                              psdFile.ImageData[2][pos],
                              0);
                break;

            case PsdFile.ColorModes.Bitmap:
                byte bwValue = ImageDecoder.GetBitmapValue(psdFile.ImageData[0], pos);
                c = Color.FromArgb(bwValue, bwValue, bwValue);
                break;

            case PsdFile.ColorModes.Grayscale:
            case PsdFile.ColorModes.Duotone:
                c = Color.FromArgb(psdFile.ImageData[0][pos],
                                   psdFile.ImageData[0][pos],
                                   psdFile.ImageData[0][pos]);
                break;

            case PsdFile.ColorModes.Indexed:
            {
                int index = (int)psdFile.ImageData[0][pos];
                c = Color.FromArgb((int)psdFile.ColorModeData[index],
                                   psdFile.ColorModeData[index + 256],
                                   psdFile.ColorModeData[index + 2 * 256]);
            }
            break;

            case PsdFile.ColorModes.Lab:
            {
                c = LabToRGB(psdFile.ImageData[0][pos],
                             psdFile.ImageData[1][pos],
                             psdFile.ImageData[2][pos]);
            }
            break;
            }

            return(c);
        }
Beispiel #6
0
 private IList<IPsdLayer> getLayers(PsdFile file)
 {
     List<IPsdLayer> items = new List<IPsdLayer>(file.Layers.Count);
     for (int i = 0; i < file.Layers.Count; i++)
     {
         items.Add(new PsdLayer(file.Layers[i],i));
     }
     return items;
 }
        private static Color GetColor(PsdFile psdFile, int pos)
        {
            Color c = Color.White;

            switch (psdFile.ColorMode)
            {
            case PsdFile.ColorModes.RGB:
                c = Color.FromArgb(
                    // read alpha if that channel is available (otherwise default to full alpha)
                    (3 < psdFile.ImageData.Length ? psdFile.ImageData[3][pos] : 255),
                    psdFile.ImageData[0][pos],
                    psdFile.ImageData[1][pos],
                    psdFile.ImageData[2][pos]);
                break;

            case PsdFile.ColorModes.CMYK:
                c = CMYKToRGB(psdFile.ImageData[0][pos],
                              psdFile.ImageData[1][pos],
                              psdFile.ImageData[2][pos],
                              psdFile.ImageData[3][pos]);
                break;

            case PsdFile.ColorModes.Multichannel:
                c = CMYKToRGB(psdFile.ImageData[0][pos],
                              psdFile.ImageData[1][pos],
                              psdFile.ImageData[2][pos],
                              0);
                break;

            case PsdFile.ColorModes.Grayscale:
            case PsdFile.ColorModes.Duotone:
                c = Color.FromArgb(psdFile.ImageData[0][pos],
                                   psdFile.ImageData[0][pos],
                                   psdFile.ImageData[0][pos]);
                break;

            case PsdFile.ColorModes.Indexed:
            {
                int index = (int)psdFile.ImageData[0][pos];
                c = Color.FromArgb((int)psdFile.ColorModeData[index],
                                   psdFile.ColorModeData[index + 256],
                                   psdFile.ColorModeData[index + 2 * 256]);
            }
            break;

            case PsdFile.ColorModes.Lab:
            {
                c = LabToRGB(psdFile.ImageData[0][pos],
                             psdFile.ImageData[1][pos],
                             psdFile.ImageData[2][pos]);
            }
            break;
            }

            return(c);
        }
        /////////////////////////////////////////////////////////////////////////// 
        public static Bitmap DecodeImage(PsdFile psdFile)
        {
            Bitmap bitmap = new Bitmap(psdFile.Columns, psdFile.Rows, PixelFormat.Format32bppArgb);

            #if TEST
              for (int y = 0; y < psdFile.Rows; y++)
              {
            int rowIndex = y * psdFile.Columns;

            for (int x = 0; x < psdFile.Columns; x++)
            {
              int pos = rowIndex + x;

              Color pixelColor=GetColor(psdFile,pos);

              bitmap.SetPixel(x, y, pixelColor);
            }
              }

            #else

              Rectangle r = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
              BitmapData bd = bitmap.LockBits(r, ImageLockMode.ReadWrite, bitmap.PixelFormat);

              unsafe
              {
            byte* pCurrRowPixel = (byte*)bd.Scan0.ToPointer();

            for (int y = 0; y < psdFile.Rows; y++)
            {
              int rowIndex = y * psdFile.Columns;
              PixelData* pCurrPixel = (PixelData*)pCurrRowPixel;
              for (int x = 0; x < psdFile.Columns; x++)
              {
            int pos = rowIndex + x;

            Color pixelColor = GetColor(psdFile, pos);

            pCurrPixel->Alpha = 255;
            pCurrPixel->Red = pixelColor.R;
            pCurrPixel->Green = pixelColor.G;
            pCurrPixel->Blue = pixelColor.B;

            pCurrPixel += 1;
              }
              pCurrRowPixel += bd.Stride;
            }
              }

              bitmap.UnlockBits(bd);
            #endif

              return bitmap;
        }
Beispiel #9
0
        ///////////////////////////////////////////////////////////////////////////

        public Layer(PsdFile psdFile)
        {
            PsdFile          = psdFile;
            Rect             = Rectangle.Empty;
            Channels         = new ChannelList();
            BlendModeKey     = PsdBlendMode.Normal;
            AdditionalInfo   = new List <LayerInfo>();
            IsGroup          = false;
            ParentLayer      = null;
            IsEndGroupMarker = false;
        }
Beispiel #10
0
        ///////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Decodes the main, composed layer of a PSD file into a bitmap with no transparency.
        /// </summary>
        /// <param name="psdFile"></param>
        /// <returns></returns>
        public static Bitmap DecodeImage(PsdFile psdFile)
        {
            Bitmap bitmap = new Bitmap(psdFile.Columns, psdFile.Rows, PixelFormat.Format32bppArgb);

#if TEST
            for (int y = 0; y < psdFile.Rows; y++)
            {
                int rowIndex = y * psdFile.Columns;

                for (int x = 0; x < psdFile.Columns; x++)
                {
                    int pos = rowIndex + x;

                    Color pixelColor = GetColor(psdFile, pos);

                    bitmap.SetPixel(x, y, pixelColor);
                }
            }
#else
            Rectangle  r  = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            BitmapData bd = bitmap.LockBits(r, ImageLockMode.ReadWrite, bitmap.PixelFormat);

            unsafe
            {
                byte *pCurrRowPixel = (byte *)bd.Scan0.ToPointer();

                for (int y = 0; y < psdFile.Rows; y++)
                {
                    int        rowIndex   = y * psdFile.Columns;
                    PixelData *pCurrPixel = (PixelData *)pCurrRowPixel;
                    for (int x = 0; x < psdFile.Columns; x++)
                    {
                        int pos = rowIndex + x;

                        Color pixelColor = GetColor(psdFile, pos);

                        pCurrPixel->Alpha = 255;
                        pCurrPixel->Red   = pixelColor.R;
                        pCurrPixel->Green = pixelColor.G;
                        pCurrPixel->Blue  = pixelColor.B;


                        pCurrPixel += 1;
                    }
                    pCurrRowPixel += bd.Stride;
                }
            }

            bitmap.UnlockBits(bd);
#endif

            return(bitmap);
        }
    public void OnGUI()
    {
        EditorGUI.BeginChangeCheck();
        image = (Texture2D)EditorGUILayout.ObjectField("PSD File", image, typeof(Texture2D), true);
        bool changed = EditorGUI.EndChangeCheck();

        if (image != null) {
            if (changed) {
                string path = AssetDatabase.GetAssetPath(image);

                if (path.ToUpper().EndsWith(".PSD")) {
                    psd = new PsdFile(path, Encoding.Default);
                } else {
                    psd = null;
                }
            }
            if (psd != null) {
                scrollPos = EditorGUILayout.BeginScrollView(scrollPos);

                foreach (Layer layer in psd.Layers) {
                    if (layer.Name != "</Layer set>") {
                        layer.Visible = EditorGUILayout.ToggleLeft(layer.Name, layer.Visible);
                    }
                }

                EditorGUILayout.EndScrollView();

                if (GUILayout.Button("Export visible layers")) {
                    ExportLayers();
                }

                atlassize = EditorGUILayout.IntField("Max. atlas size", atlassize);

                if (!((atlassize != 0) && ((atlassize & (atlassize - 1)) == 0))) {
                    EditorGUILayout.HelpBox("Atlas size should be a power of 2", MessageType.Warning);
                }

                if (GUILayout.Button("Create atlas")) {
                    CreateAtlas();
                }
                if (GUILayout.Button("Create sprites")) {
                    CreateSprites();
                }
            } else {
                EditorGUILayout.HelpBox("This texture is not a PSD file.", MessageType.Error);
            }
        }
    }
Beispiel #12
0
        public InfoLayers(PsdFile psdFile, string key)
        {
            PsdFile = psdFile;

            switch (key)
            {
            // The key does not have to match the bit depth, but it does have to
            // be one of the known values.
            case "Layr":
            case "Lr16":
            case "Lr32":
                this.key = key;
                break;

            default:
                throw new PsdInvalidException(
                          $"{nameof(InfoLayers)} key must be Layr, Lr16, or Lr32.");
            }
        }
Beispiel #13
0
        public InfoLayers(PsdBinaryReader reader, PsdFile psdFile,
                          string key, long dataLength)
            : this(psdFile, key)
        {
            if (psdFile.Layers.Count > 0)
            {
                throw new PsdInvalidException(
                          "Cannot have both regular layers and Additional Info layers");
            }

            var endPosition = reader.BaseStream.Position + dataLength;

            psdFile.LoadLayers(reader, false);

            if (reader.BaseStream.Position != endPosition)
            {
                throw new PsdInvalidException(
                          $"Incorrect length for {nameof(InfoLayers)}.");
            }
        }
Beispiel #14
0
        public Bitmap Decode(Stream s)
        {
            //Bitmap we will render to
            System.Drawing.Bitmap b = null;

            //Time just the parsing/rendering
            Stopwatch swRender = new Stopwatch();
            swRender.Start();

            PsdFile psdFile = new PsdFile();
            psdFile.Load(s);
            //Load background layer
            b = ImageDecoder.DecodeImage(psdFile); //Layers collection doesn't include the composed layer

            //How fast?
            swRender.Stop();
            trace("Parsing and rendering PSD to a Bitmap instance took " + swRender.ElapsedMilliseconds.ToString(NumberFormatInfo.InvariantInfo) + "ms");

            return b;
        }
Beispiel #15
0
        internal static void LoadAll(PsdBinaryReader reader, PsdFile psdFile,
                                     List <LayerInfo> layerInfoList, long endPosition, bool globalLayerInfo)
        {
            // LayerInfo has a 12-byte minimum length.  Anything shorter should be
            // ignored as padding.
            while (endPosition - reader.BaseStream.Position >= 12)
            {
                var layerInfo = Load(reader, psdFile, globalLayerInfo);
                layerInfoList.Add(layerInfo);
            }

            if (reader.BaseStream.Position < endPosition)
            {
                reader.BaseStream.Position = endPosition;
            }
            else if (reader.BaseStream.Position > endPosition)
            {
                throw new PsdInvalidException(
                          "Read past the end of the LayerInfo fields.");
            }
        }
    ///////////////////////////////////////////////////////////////////////////

    public Layer(PsdFile psdFile)
    {
      PsdFile = psdFile;
      Rect = new Rect();
      Channels = new ChannelList();
      BlendModeKey = PsdBlendMode.Normal;
      AdditionalInfo = new List<LayerInfo>();
    }
Beispiel #17
0
 public IList<IPsdLayer> GetLayers(Stream s)
 {
     PsdFile file = new PsdFile();
     file.Load(s);
     return getLayers(file);
 }
Beispiel #18
0
        public Layer(BinaryReverseReader reader, PsdFile psdFile)
        {
            //从文档 五 - 4 - 1) 开始读
            Children = new List <Layer>();
            PsdFile  = psdFile;

            Rect rect = new Rect();

            rect.y      = reader.ReadInt32();
            rect.x      = reader.ReadInt32();
            rect.height = reader.ReadInt32() - rect.y;
            rect.width  = reader.ReadInt32() - rect.x;
            Rect        = rect;

            int channelCount = reader.ReadUInt16();

            Channels       = new List <Channel>();
            SortedChannels = new SortedList <short, Channel>();
            for (int index = 0; index < channelCount; ++index)
            {
                Channel channel = new Channel(reader, this);
                Channels.Add(channel);
                SortedChannels.Add(channel.ID, channel);
            }

            string head = reader.ReadStringNew(4);

            if (head != "8BIM")
            {
                throw new IOException("Layer Channelheader error!");
            }

            string layerRecordsBlendModeKey = reader.ReadStringNew(4);

            Opacity = reader.ReadByte();

            int Clipping = reader.ReadByte();

            _flags = new BitVector32(reader.ReadByte());

            int Filler = reader.ReadByte();

            _imageTransparent = Convert.ToSingle(Opacity) / byte.MaxValue;

            //文档 五 - 4 - 13)
            uint num3      = reader.ReadUInt32();
            long position1 = reader.BaseStream.Position;

            MaskData = new Mask(reader, this);

            _blendingRangesData = new BlendingRanges(reader);
            long position2 = reader.BaseStream.Position;

            // 文档 五 - 4 - 21)
            Name = reader.ReadPascalString();
            // read the adjustment info
            int count = (int)((reader.BaseStream.Position - position2) % 4L);

            reader.ReadBytes(count);

            _adjustmentInfo = new List <AdjustmentLayerInfo>();
            long num4 = position1 + num3;

            while (reader.BaseStream.Position < num4)
            {
                try
                {
                    _adjustmentInfo.Add(new AdjustmentLayerInfo(reader, this));
                }
                catch
                {
                    reader.BaseStream.Position = num4;
                }
            }


            foreach (AdjustmentLayerInfo adjustmentLayerInfo in _adjustmentInfo)
            {
                if (adjustmentLayerInfo.Key == "TySh")
                {
                    ReadTextLayer(adjustmentLayerInfo.DataReader);
                }
                else if (adjustmentLayerInfo.Key == "luni")
                {
                    // read the unicode name
                    BinaryReverseReader dataReader = adjustmentLayerInfo.DataReader;
                    byte[] temp1     = dataReader.ReadBytes(3);
                    byte   charCount = dataReader.ReadByte();
                    //本来 charCount 是文本串的长度,可以传入ReadString()限定读取长度,但Text除串头无文本长度信息,因此改为读一段Unicode字符串
                    Name = dataReader.ReadString();
                    if (Name == "")
                    {
                        Name = DefaultLayerName;
                    }
                }
                //此处针对字体  图层样式
                else if (adjustmentLayerInfo.Key == "lrFX") //样式 相关,对于字体来说,就是描边之类的
                {
                    ParseLrfxKeyword(adjustmentLayerInfo);  //yanruTODO测试屏蔽
                }
                //仅对于图片的
                else if (adjustmentLayerInfo.Key == "lspf")
                {
                    BinaryReverseReader dataReader = adjustmentLayerInfo.DataReader;
                    byte[] data = dataReader.ReadBytes(4);
                }
                else if (adjustmentLayerInfo.Key == "lclr")
                {
                    BinaryReverseReader dataReader = adjustmentLayerInfo.DataReader;
                    byte[] data = dataReader.ReadBytes(10);
                }
            }

            reader.BaseStream.Position = num4;

            int deltaL = (int)(MaskData.Rect.x - Rect.x);
            int deltaR = (int)(Rect.xMax - MaskData.Rect.xMax);
            int deltaT = (int)(MaskData.Rect.y - Rect.y);
            int deltaB = (int)(Rect.yMax - MaskData.Rect.yMax);
            int l      = deltaL > 0 ? deltaL : 0;
            int r      = deltaR > 0 ? deltaR : 0;
            int t      = deltaT > 0 ? deltaT : 0;
            int b      = deltaB > 0 ? deltaB : 0;

            //Unity Document TextureImporter.spriteBorder  X=left, Y=bottom, Z=right, W=top.
            _border = new Vector4(l, b, r, t);
            //_is9Slice = SLICE_REG.Match(_name).Success;
            _is9Slice = _name.Contains(SLICE_HEAD);
        }
		public PsdFileInfo(PsdFile psd)
		{
			List<int> layerIndices = new List<int>();
			List<PSDLayerGroupInfo> layerGroups = new List<PSDLayerGroupInfo>();
			List<PSDLayerGroupInfo> openGroupStack = new List<PSDLayerGroupInfo>();
			List<bool> layerVisibility = new List<bool>();
			// Reverse loop through layers to get the layers in the
			// same way they are displayed in Photoshop
			for (int i = psd.Layers.Count - 1; i >= 0; i--)
			{
				Layer layer = psd.Layers[i];

				layerVisibility.Add(layer.Visible);

				// Get the section info for this layer
				var secInfo = layer.AdditionalInfo
					.Where(info => info.GetType() == typeof(LayerSectionInfo))
					.ToArray();
				// Section info is basically layer group info
				bool isOpen = false;
				bool isGroup = false;
				bool closeGroup = false;
				if (secInfo.Any())
				{
					foreach (var layerSecInfo in secInfo)
					{
						LayerSectionInfo info = (LayerSectionInfo)layerSecInfo;
						isOpen = info.SectionType == LayerSectionType.OpenFolder;
						isGroup = info.SectionType == LayerSectionType.ClosedFolder | isOpen;
						closeGroup = info.SectionType == LayerSectionType.SectionDivider;
						if (isGroup || closeGroup)
							break;
					}
				}

				if (isGroup)
				{
					// Open a new layer group info, because we're iterating
					// through layers backwards, this layer number is the last logical layer
					openGroupStack.Add(new PSDLayerGroupInfo(layer.Name, i, layer.Visible, isOpen));
				}
				else if (closeGroup)
				{
					// Set the start index of the last LayerGroupInfo
					var closeInfo = openGroupStack.Last();
					closeInfo.start = i;
					// Add it to the layerGroup list
					layerGroups.Add(closeInfo);
					// And remove it from the open group stack 
					openGroupStack.RemoveAt(openGroupStack.Count - 1);
				}
				else
				{
					// Normal layer
					layerIndices.Add(i);
					// look for instances	
					if (layer.Name.Contains(" Copy"))
					{
					}
				}
			} // End layer loop

			// Since loop was reversed...
			layerVisibility.Reverse();
			LayerVisibility = layerVisibility.ToArray();

			LayerIndices = layerIndices.ToArray();

			LayerGroups = layerGroups.ToArray();
		}
Beispiel #20
0
        public Layer(BinaryReverseReader reader, PsdFile psdFile)
        {
            Debug.WriteLine("Layer started at " + reader.BaseStream.Position.ToString());

            m_psdFile     = psdFile;
            m_rect        = new Rectangle();
            m_rect.Y      = reader.ReadInt32();
            m_rect.X      = reader.ReadInt32();
            m_rect.Height = reader.ReadInt32() - m_rect.Y;
            m_rect.Width  = reader.ReadInt32() - m_rect.X;

            //-----------------------------------------------------------------------

            int numberOfChannels = reader.ReadUInt16();

            this.m_channels.Clear();
            for (int channel = 0; channel < numberOfChannels; channel++)
            {
                Channel ch = new Channel(reader, this);
                m_channels.Add(ch);
                m_sortedChannels.Add(ch.ID, ch);
            }

            //-----------------------------------------------------------------------

            string signature = new string(reader.ReadChars(4));

            if (signature != "8BIM")
            {
                throw (new IOException("Layer Channelheader error!"));
            }

            m_blendModeKey = new string(reader.ReadChars(4));
            m_opacity      = reader.ReadByte();

            m_clipping = reader.ReadByte() > 0;

            //-----------------------------------------------------------------------

            byte flags = reader.ReadByte();

            m_flags = new BitVector32(flags);

            //-----------------------------------------------------------------------

            reader.ReadByte(); //padding

            //-----------------------------------------------------------------------

            Debug.WriteLine("Layer extraDataSize started at " + reader.BaseStream.Position.ToString());

            // this is the total size of the MaskData, the BlendingRangesData, the
            // Name and the AdjustmentLayerInfo
            uint extraDataSize = reader.ReadUInt32();

            // remember the start position for calculation of the
            // AdjustmentLayerInfo size
            long extraDataStartPosition = reader.BaseStream.Position;

            m_maskData           = new Mask(reader, this);
            m_blendingRangesData = new BlendingRanges(reader, this);

            //-----------------------------------------------------------------------

            long namePosition = reader.BaseStream.Position;

            m_name = reader.ReadPascalString();

            int paddingBytes = (int)((reader.BaseStream.Position - namePosition) % 4);

            Debug.Print("Layer {0} padding bytes after name", paddingBytes);
            reader.ReadBytes(paddingBytes);

            //-----------------------------------------------------------------------

            m_adjustmentInfo.Clear();

            long adjustmentLayerEndPos = extraDataStartPosition + extraDataSize;

            while (reader.BaseStream.Position < adjustmentLayerEndPos)
            {
                try
                {
                    AdjustmentLayerInfo ali = new AdjustmentLayerInfo(reader, this);
                    if (ali.Key.Equals("lrFX"))
                    {
                        //A sub-key - we want to merge its sub-layer info items with this dict.
                        m_adjustmentInfo.AddRange(new Effects(ali)._resources.Values);
                    }
                    else
                    {
                        m_adjustmentInfo.Add(ali); // Just add the items
                    }
                }
                catch
                {
                    reader.BaseStream.Position = adjustmentLayerEndPos;
                }
            }


            //-----------------------------------------------------------------------
            // make sure we are not on a wrong offset, so set the stream position
            // manually
            reader.BaseStream.Position = adjustmentLayerEndPos;
        }
        ///////////////////////////////////////////////////////////////////////////

        public static Bitmap DecodeImage(PsdFile psdFile)
        {
            var bitmap = new Bitmap(psdFile.Columns, psdFile.Rows, PixelFormat.Format32bppArgb);

            // Fix to support different pixel resolutions
            bitmap.SetResolution(psdFile.Resolution.HRes, psdFile.Resolution.VRes);

#if TEST
            for (int y = 0; y < psdFile.Rows; y++)
            {
                int rowIndex = y * psdFile.Columns;

                for (int x = 0; x < psdFile.Columns; x++)
                {
                    int pos = rowIndex + x;

                    Color pixelColor = GetColor(psdFile, pos);

                    bitmap.SetPixel(x, y, pixelColor);
                }
            }
#else
#if true  // fix remove unsafeness (admittedly slower)
#if false // safe + slow
            for (int y = 0; y < psdFile.Rows; y++)
            {
                int rowIndex = y * psdFile.Columns;
                for (int x = 0; x < psdFile.Columns; x++)
                {
                    int pos = rowIndex + x;

                    Color pixelColor = GetColor(psdFile, pos);

                    bitmap.SetPixel(x, y, pixelColor /*Color.FromArgb(255, pixelColor)*/);
                }
            }
#else // safe + fast
            // based on MSDN -- Bitmap.LockBits
            // Lock the bitmap's bits.
            var bmpData = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadWrite,
                bitmap.PixelFormat);

            // Get the address of the first line.
            var ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            var nDestLength     = Math.Abs(bmpData.Stride) * bitmap.Height;
            var arrayOutputARGB = new byte[nDestLength];

            // Copy the RGB values into the array.
            System.Runtime.InteropServices.Marshal.Copy(ptr, arrayOutputARGB, 0, nDestLength);

            var nOutputOffset = 0;
            for (var y = 0; y < psdFile.Rows; y++)
            {
                var rowIndex = y * psdFile.Columns;
                for (var x = 0; x < psdFile.Columns; x++)
                {
                    var nSourcePosition = rowIndex + x;
                    SetDestinationColor(psdFile, arrayOutputARGB, nOutputOffset, nSourcePosition);
                    nOutputOffset += 4;
                }
            }

            // Copy the RGB values back to the bitmap
            System.Runtime.InteropServices.Marshal.Copy(arrayOutputARGB, 0, ptr, nDestLength);

            // Unlock the bits.
            bitmap.UnlockBits(bmpData);
#endif
#else
            Rectangle  r  = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            BitmapData bd = bitmap.LockBits(r, ImageLockMode.ReadWrite, bitmap.PixelFormat);

            unsafe
            {
                byte *pCurrRowPixel = (byte *)bd.Scan0.ToPointer();

                for (int y = 0; y < psdFile.Rows; y++)
                {
                    int        rowIndex   = y * psdFile.Columns;
                    PixelData *pCurrPixel = (PixelData *)pCurrRowPixel;
                    for (int x = 0; x < psdFile.Columns; x++)
                    {
                        int pos = rowIndex + x;

                        Color pixelColor = GetColor(psdFile, pos);

                        pCurrPixel->Alpha = 255;
                        pCurrPixel->Red   = pixelColor.R;
                        pCurrPixel->Green = pixelColor.G;
                        pCurrPixel->Blue  = pixelColor.B;

                        pCurrPixel += 1;
                    }
                    pCurrRowPixel += bd.Stride;
                }
            }

            bitmap.UnlockBits(bd);
#endif
#endif

            return(bitmap);
        }
Beispiel #22
0
        public Layer(BinaryReverseReader reader, PsdFile psdFile)
        {
            Debug.WriteLine("Layer started at " + reader.BaseStream.Position);

            m_psdFile = psdFile;
            m_rect = new Rectangle
            {
                Y = reader.ReadInt32(),
                X = reader.ReadInt32()
            };
            m_rect.Height = reader.ReadInt32() - m_rect.Y;
            m_rect.Width = reader.ReadInt32() - m_rect.X;


            //-----------------------------------------------------------------------

            int numberOfChannels = reader.ReadUInt16();
            m_channels.Clear();
            for (int channel = 0; channel < numberOfChannels; channel++)
            {
                var ch = new Channel(reader, this);
                m_channels.Add(ch);
                m_sortedChannels.Add(ch.ID, ch);
            }

            //-----------------------------------------------------------------------

            var signature = new string(reader.ReadChars(4));
            if (signature != LayerConstants.EightBimSignature)
                throw (new IOException("Layer Channelheader error!"));

            m_blendModeKey = new string(reader.ReadChars(4));
            m_opacity = reader.ReadByte();

            m_clipping = reader.ReadByte() > 0;

            //-----------------------------------------------------------------------

            byte flags = reader.ReadByte();
            m_flags = new BitVector32(flags);

            //-----------------------------------------------------------------------

            reader.ReadByte(); //padding

            //-----------------------------------------------------------------------

            Debug.WriteLine("Layer extraDataSize started at " + reader.BaseStream.Position);

            // this is the total size of the MaskData, the BlendingRangesData, the 
            // Name and the AdjustmenLayerInfo
            uint extraDataSize = reader.ReadUInt32();


            // remember the start position for calculation of the 
            // AdjustmenLayerInfo size
            long extraDataStartPosition = reader.BaseStream.Position;

            m_maskData = new Mask(reader, this);
            m_blendingRangesData = new BlendingRanges(reader, this);

            //-----------------------------------------------------------------------

            var namePosition = reader.BaseStream.Position;

            m_name = reader.ReadPascalString();

            var paddingBytes = (int)((reader.BaseStream.Position - namePosition) % 4);

            Debug.Print("Layer {0} padding bytes after name", paddingBytes);
            reader.ReadBytes(paddingBytes);

            //-----------------------------------------------------------------------

            m_adjustmentInfo.Clear();

            long adjustmenLayerEndPos = extraDataStartPosition + extraDataSize;
            while (reader.BaseStream.Position < adjustmenLayerEndPos)
            {
                try
                {
                    m_adjustmentInfo.Add(new AdjusmentLayerInfo(reader, this));
                }
                catch
                {
                    reader.BaseStream.Position = adjustmenLayerEndPos;
                }
            }


            //-----------------------------------------------------------------------
            // make shure we are not on a wrong offset, so set the stream position 
            // manually
            reader.BaseStream.Position = adjustmenLayerEndPos;
        }
Beispiel #23
0
        public Layer(PsdBinaryReader reader, PsdFile psdFile)
            : this(psdFile)
        {
            Util.DebugMessage(reader.BaseStream, "Load, Begin, Layer");

            Rect = reader.ReadRectangle();

            //-----------------------------------------------------------------------
            // Read channel headers.  Image data comes later, after the layer header.

            int numberOfChannels = reader.ReadUInt16();
            for (int channel = 0; channel < numberOfChannels; channel++)
            {
                var ch = new Channel(reader, this);
                Channels.Add(ch);
            }

            //-----------------------------------------------------------------------
            //

            var signature = reader.ReadAsciiChars(4);
            if (signature != "8BIM")
            {
                throw (new PsdInvalidException("Invalid signature in layer header."));
            }

            BlendModeKey = reader.ReadAsciiChars(4);
            Opacity      = reader.ReadByte();
            Clipping     = reader.ReadBoolean();

            var flagsByte = reader.ReadByte();
            flags = new BitVector32(flagsByte);
            reader.ReadByte(); //padding

            //-----------------------------------------------------------------------

            // This is the total size of the MaskData, the BlendingRangesData, the
            // Name and the AdjustmentLayerInfo.
            var extraDataSize          = reader.ReadUInt32();
            var extraDataStartPosition = reader.BaseStream.Position;

            Masks = new MaskInfo(reader, this);
            BlendingRangesData = new BlendingRanges(reader, this);
            Name = reader.ReadPascalString(4);

            //-----------------------------------------------------------------------
            // Process Additional Layer Information

            long adjustmentLayerEndPos = extraDataStartPosition + extraDataSize;
            while (reader.BaseStream.Position < adjustmentLayerEndPos)
            {
                var layerInfo = LayerInfoFactory.Load(reader,
                                                      psdFile: this.PsdFile,
                                                      globalLayerInfo: false);
                AdditionalInfo.Add(layerInfo);
            }

            foreach (var adjustmentInfo in AdditionalInfo)
            {
                switch (adjustmentInfo.Key)
                {
                case "luni":
                    Name = ((LayerUnicodeName)adjustmentInfo).Name;
                    break;
                }
            }

            Util.DebugMessage(reader.BaseStream, "Load, End, Layer, {0}", Name);

            PsdFile.LoadContext.OnLoadLayerHeader(this);
        }
        /// <summary>
        /// Imports a Photoshop document (.psd) file at the given path.
        /// </summary>
        /// <param name="asset">The path of to the .psd file relative to the project.</param>
        private static void Import(string asset)
        {
            currentDepth = MaximumDepth;
            string fullPath = Path.Combine(GetFullProjectPath(), asset.Replace('\\', '/'));

            PsdFile psd = new PsdFile(fullPath);
            CanvasSize = new Vector2(psd.Width, psd.Height);

            // Set the depth step based on the layer count.  If there are no layers, default to 0.1f.
            depthStep = psd.Layers.Count != 0 ? MaximumDepth / psd.Layers.Count : 0.1f;

            int lastSlash = asset.LastIndexOf('/');
            string assetPathWithoutFilename = asset.Remove(lastSlash + 1, asset.Length - (lastSlash + 1));
            PsdName = asset.Replace(assetPathWithoutFilename, string.Empty).Replace(".psd", string.Empty);

            currentPath = GetFullProjectPath() + "Assets";
            currentPath = Path.Combine(currentPath, PsdName);
            Directory.CreateDirectory(currentPath);

            if (LayoutInScene || CreatePrefab)
            {
                if (UseUnityUI)
                {
                    CreateUIEventSystem();
                    CreateUICanvas();
                    rootPsdGameObject = Canvas;
                }
                else
                {
                    rootPsdGameObject = new GameObject(PsdName);
                }

                currentGroupGameObject = rootPsdGameObject;
            }

            List<Layer> tree = BuildLayerTree(psd.Layers);
            ExportTree(tree);

            if (CreatePrefab)
            {
                UnityEngine.Object prefab = PrefabUtility.CreateEmptyPrefab(asset.Replace(".psd", ".prefab"));
                PrefabUtility.ReplacePrefab(rootPsdGameObject, prefab);

                if (!LayoutInScene)
                {
                    // if we are not flagged to layout in the scene, delete the GameObject used to generate the prefab
                    UnityEngine.Object.DestroyImmediate(rootPsdGameObject);
                }
            }

            AssetDatabase.Refresh();
        }
Beispiel #25
0
        /// <summary>
        /// Imports a Photoshop document (.psd) file at the given path.
        /// </summary>
        /// <param name="asset">The path of to the .psd file relative to the project.</param>
        private static void Import(string asset)
        {
            createdNameList = new List<string>();

            currentDepth = MaximumDepth;
            string fullPath = Path.Combine(GetFullProjectPath(), asset.Replace('\\', '/'));

            PsdFile psd = new PsdFile(fullPath);
            CanvasSize = ScreenResolution;// new Vector2(psd.Width, psd.Height);
            Debug.Log(Time.time + "update canvasSize as UI size=" + CanvasSize);
            // Set the depth step based on the layer count.  If there are no layers, default to 0.1f.
            depthStep = psd.Layers.Count != 0 ? MaximumDepth / psd.Layers.Count : 0.1f;

            int lastSlash = asset.LastIndexOf('/');
            string assetPathWithoutFilename = asset.Remove(lastSlash + 1, asset.Length - (lastSlash + 1));
            PsdName = asset.Replace(assetPathWithoutFilename, string.Empty).Replace(".psd", string.Empty);

            currentPath = GetFullProjectPath() + "Assets/export_image"; //图片的相对目录!
            currentPath = Path.Combine(currentPath, PsdName);
            createDic(currentPath);

            if (LayoutInScene || CreatePrefab)
            {
                if (UseUnityUI)
                {
                    CreateUIEventSystem();
                    CreateUICanvas();
                }

                //create ui Root
                rootPsdGameObject = CreateObj(PsdName);
                updateParent(rootPsdGameObject, canvasObj);

                //if (fullScreenUI)
                {
                    RectTransform rectRoot = rootPsdGameObject.GetComponent<RectTransform>();
                    rectRoot.anchorMin = new Vector2(0, 0);
                    rectRoot.anchorMax = new Vector2(1, 1);
                    rectRoot.offsetMin = Vector2.zero;
                    rectRoot.offsetMax = Vector2.zero;
                }
                Vector3 rootPos = Vector3.zero;
                updateRectPosition(rootPsdGameObject, rootPos, true);

                currentGroupGameObject = rootPsdGameObject;
            }

            List<Layer> tree = BuildLayerTree(psd.Layers);
            ExportTree(tree);

            if (CreatePrefab)
            {
                UnityEngine.Object prefab = PrefabUtility.CreateEmptyPrefab(asset.Replace(".psd", ".prefab"));
                PrefabUtility.ReplacePrefab(rootPsdGameObject, prefab);

                if (!LayoutInScene)
                {
                    // if we are not flagged to layout in the scene, delete the GameObject used to generate the prefab
                    UnityEngine.Object.DestroyImmediate(rootPsdGameObject);
                }
            }

            //all ui items created, update components
            Debug.Log(Time.time + ",dealUI=" + rootPsdGameObject.name + ",finish");

            int childCount = rootPsdGameObject.transform.childCount;
            for (int index = 0; index < childCount; index++)
            {
                Transform tran = rootPsdGameObject.transform.GetChild(index);
                tran.position += new Vector3(ScreenResolution.x / 2f, ScreenResolution.y / 2f, 0);
            }

            Dictionary<Transform, bool> _dealDic = new Dictionary<Transform, bool>(); //flag if item will be deleted

            List<Transform> btnList = new List<Transform>();
            List<Transform> deleteList = new List<Transform>();

            Transform[] allChild = rootPsdGameObject.GetComponentsInChildren<Transform>();
            for (int index = 0; index < allChild.Length; index++)
            {
                Transform tran = allChild[index];
                if (tran.name.IndexOf(BTN_HEAD) == 0)
                {
                    Button button = tran.gameObject.AddComponent<Button>();
                    tran.GetComponent<Image>().raycastTarget = true;
                    button.transition = Selectable.Transition.SpriteSwap;
                    btnList.Add(tran);
                }
            }

            for (int btnIndex = 0; btnIndex < btnList.Count; btnIndex++)
            {
                string btnName = btnList[btnIndex].name;
                for (int index = 0; index < allChild.Length; index++)
                {
                    Transform tran = allChild[index];

                    //update image sprite deltaSize and PNG attribute
                    Image image = tran.GetComponent<Image>();
                    if (image != null && image.sprite != null)
                    {
                        string spriteName = image.sprite.name;

                        //匹配以 数字_数字 结尾的串。匹配结果作为九宫格尺寸
                        string str1 = spriteName; // "4343434";// "testrewer_4_3";
                        Regex reg = new Regex(@"\d+[_]\d+$");
                        Match match = reg.Match(str1);
                        if (match.ToString() != "")
                        {
                            //Debug.LogError(Time.time + ",str1=" + str1 + ",满足?" + reg.Match(str1).ToString());
                            string[] size = reg.Match(str1).ToString().Split('_');
                            int width = Convert.ToInt32(size[0]);
                            int height = Convert.ToInt32(size[0]);
                            image.GetComponent<RectTransform>().sizeDelta = new Vector2(width, height);
                            image.type = Image.Type.Sliced;

                            if (image.sprite.border == Vector4.zero)
                            {
                                Debug.LogError(Time.time + "need to set png=" + image.sprite.name + ",slice border");
                            }
                        }
                    }

                    if (allChild[index].name.IndexOf(btnName) == 0)
                    {
                        if (allChild[index].name.Contains(BTN_TAIL_HIGH))//按钮的高亮图
                        {
                            SpriteState sprite = btnList[btnIndex].GetComponent<Button>().spriteState;
                            sprite.pressedSprite = allChild[index].GetComponent<Image>().sprite;
                            btnList[btnIndex].GetComponent<Button>().spriteState = sprite;
                            deleteList.Add(tran);
                        }
                        if (allChild[index].name.Contains(BTN_TAIL_DIS))//按钮的禁用图
                        {
                            SpriteState sprite = btnList[btnIndex].GetComponent<Button>().spriteState;
                            sprite.disabledSprite = allChild[index].GetComponent<Image>().sprite;
                            btnList[btnIndex].GetComponent<Button>().spriteState = sprite;
                            deleteList.Add(tran);
                        }
                    }
                }
            }

            //delete no use items

            for (int index = 0; index < deleteList.Count; index++)
            {
                destroyItem(deleteList[index]);
            }

            AssetDatabase.Refresh();
        }
Beispiel #26
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Layer"/> class using the provided reader containing the PSD file data.
        /// </summary>
        /// <param name="reader">The reader containing the PSD file data.</param>
        /// <param name="psdFile">The PSD file to set as the parent.</param>
        public Layer(BinaryReverseReader reader, PsdFile psdFile)
        {
            Children = new List <Layer>();
            PsdFile  = psdFile;

            // read the rect
            Rect rect = new Rect();

            rect.y      = reader.ReadInt32();
            rect.x      = reader.ReadInt32();
            rect.height = reader.ReadInt32() - rect.y;
            rect.width  = reader.ReadInt32() - rect.x;
            Rect        = rect;

            // read the channels
            int channelCount = reader.ReadUInt16();

            Channels       = new List <Channel>();
            SortedChannels = new SortedList <short, Channel>();
            for (int index = 0; index < channelCount; ++index)
            {
                Channel channel = new Channel(reader, this);
                Channels.Add(channel);

                //Debug.Log(Time.time + "channel.ID=" + channel.ID + ",layer=" + this.Name);
                SortedChannels.Add(channel.ID, channel);
            }

            string head = reader.readStringNew(4);

            //Debug.Log(Time.time + ",head=" + head);
            // read the header and verify it
            if (head != "8BIM")
            {
                throw new IOException("Layer Channelheader error!");
            }

            // read the blend mode key (unused) (defaults to "norm")
            //reader.ReadChars(4);
            string layerRecordsBlendModeKey = reader.readStringNew(4);

            // read the opacity
            Opacity = reader.ReadByte();

            // read the clipping (unused) (< 0 = base, > 0 = non base)
            int Clipping = reader.ReadByte();

            // read all of the flags (protectTrans, visible, obsolete, ver5orLater, pixelDataIrrelevant)
            flags = new BitVector32(reader.ReadByte());

            // skip a padding byte
            int Filler = reader.ReadByte();

            imageTransparent = Convert.ToSingle(Opacity) / byte.MaxValue;
            Debug.Log("layerRecordsBlendModeKey=" + layerRecordsBlendModeKey
                      + ",Opacity=" + Opacity
                      + ",Clipping=" + Clipping
                      + ",flags=" + flags
                      + ", Filler=" + Filler
                      + ",LayerTransparent=" + imageTransparent);

            uint num3      = reader.ReadUInt32();
            long position1 = reader.BaseStream.Position;

            MaskData = new Mask(reader, this);

            BlendingRangesData = new BlendingRanges(reader);
            long position2 = reader.BaseStream.Position;

            // read the name
            Name = reader.ReadPascalString();
            //Debug.Log(Time.time + ",read layer Name=" + Name + ".end");

            // read the adjustment info
            int count = (int)((reader.BaseStream.Position - position2) % 4L);

            reader.ReadBytes(count);
            //Debug.Log(Time.time + ",read count=" + count + ".end");

            AdjustmentInfo = new List <AdjustmentLayerInfo>();
            long num4 = position1 + num3;

            while (reader.BaseStream.Position < num4)
            {
                try
                {
                    AdjustmentInfo.Add(new AdjustmentLayerInfo(reader, this));
                }
                catch
                {
                    reader.BaseStream.Position = num4;
                }
            }


            string keyInfo = "";

            foreach (AdjustmentLayerInfo adjustmentLayerInfo in AdjustmentInfo)
            {
                keyInfo += ",key=" + adjustmentLayerInfo.Key + "\n";

                if (adjustmentLayerInfo.Key == "TySh")
                {
                    ReadTextLayer(adjustmentLayerInfo.DataReader);
                }
                else if (adjustmentLayerInfo.Key == "luni")
                {
                    // read the unicode name
                    BinaryReverseReader dataReader = adjustmentLayerInfo.DataReader;
                    byte[] temp1     = dataReader.ReadBytes(3);
                    byte   charCount = dataReader.ReadByte();
                    //本来 charCount 是文本串的长度,可以传入ReadString()限定读取长度,但Text除串头无文本长度信息,因此改为读一段Unicode字符串
                    Name = dataReader.ReadString();
                    if (Name == "")
                    {
                        Name = defaultLayerName;
                    }
                }
                //此处针对字体  图层样式
                else if (adjustmentLayerInfo.Key == "lrFX") //样式 相关,对于字体来说,就是描边之类的
                {
                    parseLrfxKeyword(adjustmentLayerInfo);  //yanruTODO测试屏蔽
                }
                //仅对于图片的
                else if (adjustmentLayerInfo.Key == "lspf")
                {
                    BinaryReverseReader dataReader = adjustmentLayerInfo.DataReader;
                    byte[] data = dataReader.ReadBytes(4);
                    printbytes(data, "lspf data", true);
                }
                else if (adjustmentLayerInfo.Key == "lclr")
                {
                    BinaryReverseReader dataReader = adjustmentLayerInfo.DataReader;
                    byte[] data = dataReader.ReadBytes(10);
                    printbytes(data, "lclr data", true);
                }
            }

            Debug.Log("layer=" + Name + ",Totalkey=\n" + keyInfo);

            reader.BaseStream.Position = num4;
        }
Beispiel #27
0
        public Layer(BinaryReverseReader reader, PsdFile psdFile)
        {
            Debug.WriteLine("Layer started at " + reader.BaseStream.Position.ToString());

              m_psdFile = psdFile;
              m_rect = new Rectangle();
              m_rect.Y = reader.ReadInt32();
              m_rect.X = reader.ReadInt32();
              m_rect.Height = reader.ReadInt32() - m_rect.Y;
              m_rect.Width = reader.ReadInt32() - m_rect.X;

              //-----------------------------------------------------------------------

              int numberOfChannels = reader.ReadUInt16();
              this.m_channels.Clear();
              for (int channel = 0; channel < numberOfChannels; channel++)
              {
            Channel ch = new Channel(reader, this);
            m_channels.Add(ch);
            m_sortedChannels.Add(ch.ID, ch);
              }

              //-----------------------------------------------------------------------

              string signature = new string(reader.ReadChars(4));
              if (signature != "8BIM")
            throw (new IOException("Layer Channelheader error!"));

              m_blendModeKey = new string(reader.ReadChars(4));
              m_opacity = reader.ReadByte();

              m_clipping = reader.ReadByte() > 0;

              //-----------------------------------------------------------------------

              byte flags = reader.ReadByte();
              m_flags = new BitVector32(flags);

              //-----------------------------------------------------------------------

              reader.ReadByte(); //padding

              //-----------------------------------------------------------------------

              Debug.WriteLine("Layer extraDataSize started at " + reader.BaseStream.Position.ToString());

              // this is the total size of the MaskData, the BlendingRangesData, the
              // Name and the AdjustmentLayerInfo
              uint extraDataSize = reader.ReadUInt32();

              // remember the start position for calculation of the
              // AdjustmentLayerInfo size
              long extraDataStartPosition = reader.BaseStream.Position;

              m_maskData = new Mask(reader, this);
              m_blendingRangesData = new BlendingRanges(reader, this);

              //-----------------------------------------------------------------------

              long namePosition = reader.BaseStream.Position;

              m_name = reader.ReadPascalString();

              int paddingBytes =(int)((reader.BaseStream.Position - namePosition) % 4);

              Debug.Print("Layer {0} padding bytes after name", paddingBytes);
              reader.ReadBytes(paddingBytes);

              //-----------------------------------------------------------------------

              m_adjustmentInfo.Clear();

              long adjustmentLayerEndPos = extraDataStartPosition + extraDataSize;
              while (reader.BaseStream.Position < adjustmentLayerEndPos)
              {
            try
            {
            AdjustmentLayerInfo ali = new AdjustmentLayerInfo(reader, this);
            if (ali.Key.Equals("lrFX"))
            {
                //A sub-key - we want to merge its sub-layer info items with this dict.
                m_adjustmentInfo.AddRange(new Effects(ali)._resources.Values);
            } else
                m_adjustmentInfo.Add(ali); // Just add the items
            }
            catch
            {
              reader.BaseStream.Position = adjustmentLayerEndPos;
            }
              }

              //-----------------------------------------------------------------------
              // make sure we are not on a wrong offset, so set the stream position
              // manually
              reader.BaseStream.Position = adjustmentLayerEndPos;
        }
        ///////////////////////////////////////////////////////////////////////////

        // fix for performance
        private static void SetDestinationColor(PsdFile psdFile, byte[] arrayARGB, int nOutputOffset,
                                                int nSourcePosition)
        {
            Color c = Color.White;

            switch (psdFile.ColorMode)
            {
            case PsdFile.ColorModes.RGB:
                // can take advantage of a direct copy of the bytes
                arrayARGB[nOutputOffset + 3] = (3 < psdFile.ImageData.Length
                        ? psdFile.ImageData[3][nSourcePosition]
                        : (byte)255);
                // ABGR - apparently
                arrayARGB[nOutputOffset + 2] = psdFile.ImageData[0][nSourcePosition];
                arrayARGB[nOutputOffset + 1] = psdFile.ImageData[1][nSourcePosition];
                arrayARGB[nOutputOffset + 0] = psdFile.ImageData[2][nSourcePosition];
                return;

            case PsdFile.ColorModes.CMYK:
                c = CMYKToRGB(psdFile.ImageData[0][nSourcePosition],
                              psdFile.ImageData[1][nSourcePosition],
                              psdFile.ImageData[2][nSourcePosition],
                              psdFile.ImageData[3][nSourcePosition]);
                break;

            case PsdFile.ColorModes.Multichannel:
                c = CMYKToRGB(psdFile.ImageData[0][nSourcePosition],
                              psdFile.ImageData[1][nSourcePosition],
                              psdFile.ImageData[2][nSourcePosition],
                              0);
                break;

            case PsdFile.ColorModes.Grayscale:
            case PsdFile.ColorModes.Duotone:
                // can take advantage of a direct copy of the bytes
                // TODO: can alpha channel be used?
                arrayARGB[nOutputOffset + 3] = 0xff;
                arrayARGB[nOutputOffset + 0] = psdFile.ImageData[0][nSourcePosition];
                arrayARGB[nOutputOffset + 1] = psdFile.ImageData[0][nSourcePosition];
                arrayARGB[nOutputOffset + 2] = psdFile.ImageData[0][nSourcePosition];
                return;

            case PsdFile.ColorModes.Indexed:
            {
                var index = (int)psdFile.ImageData[0][nSourcePosition];
                c = Color.FromArgb(psdFile.ColorModeData[index],
                                   psdFile.ColorModeData[index + 256],
                                   psdFile.ColorModeData[index + 2 * 256]);
            }
            break;

            case PsdFile.ColorModes.Lab:
            {
                c = LabToRGB(psdFile.ImageData[0][nSourcePosition],
                             psdFile.ImageData[1][nSourcePosition],
                             psdFile.ImageData[2][nSourcePosition]);
            }
            break;
            }

            // populate the color data
            // ABGR - apparently
            arrayARGB[nOutputOffset + 3] = c.A;
            arrayARGB[nOutputOffset + 0] = c.B;
            arrayARGB[nOutputOffset + 1] = c.G;
            arrayARGB[nOutputOffset + 2] = c.R;
        }
Beispiel #29
0
        private void Main_Load(object sender, EventArgs ev)
        {
            #region Form location

            Location = Settings.Default.StartLocation;

            FormClosing += (s, e) =>
            {
                Settings.Default.StartLocation = Location;
                Settings.Default.Save();
            };

            #endregion

            DragEventHandler enter = (s, e) =>
            {
                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    string[] files = e.Data.GetData(DataFormats.FileDrop, false) as string[];
                    if (files.FirstOrDefault<string>().EndsWith(".psd", StringComparison.OrdinalIgnoreCase))
                    {
                        e.Effect = DragDropEffects.Copy;
                    }
                }
            };
            DragEventHandler drop = (s, e) =>
            {
                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    string file = (e.Data.GetData(DataFormats.FileDrop, false) as string[]).FirstOrDefault<string>();
                    PsdFile ps = new PsdFile();
                    ps.Load(file);
                    MapLayers(ps);
                }
            };

            base.DragEnter += enter;
            base.DragDrop += drop;
        }
Beispiel #30
0
        ///////////////////////////////////////////////////////////////////////////

        public Layer(PsdFile psdFile)
        {
            m_psdFile = psdFile;
            m_psdFile.Layers.Add(this);
        }
Beispiel #31
0
 public virtual void OnLoadLayersHeader(PsdFile psdFile)
 {
 }
Beispiel #32
0
        public Layer(BinaryReverseReader reader, PsdFile psdFile)
        {
            Debug.WriteLine("Layer started at " + reader.BaseStream.Position);

            m_psdFile = psdFile;
            m_rect    = new Rectangle
            {
                Y = reader.ReadInt32(),
                X = reader.ReadInt32()
            };
            m_rect.Height = reader.ReadInt32() - m_rect.Y;
            m_rect.Width  = reader.ReadInt32() - m_rect.X;


            //-----------------------------------------------------------------------

            int numberOfChannels = reader.ReadUInt16();

            m_channels.Clear();
            for (int channel = 0; channel < numberOfChannels; channel++)
            {
                var ch = new Channel(reader, this);
                m_channels.Add(ch);
                m_sortedChannels.Add(ch.ID, ch);
            }

            //-----------------------------------------------------------------------

            var signature = new string(reader.ReadChars(4));

            if (signature != LayerConstants.EightBimSignature)
            {
                throw (new IOException("Layer Channelheader error!"));
            }

            m_blendModeKey = new string(reader.ReadChars(4));
            m_opacity      = reader.ReadByte();

            m_clipping = reader.ReadByte() > 0;

            //-----------------------------------------------------------------------

            byte flags = reader.ReadByte();

            m_flags = new BitVector32(flags);

            //-----------------------------------------------------------------------

            reader.ReadByte(); //padding

            //-----------------------------------------------------------------------

            Debug.WriteLine("Layer extraDataSize started at " + reader.BaseStream.Position);

            // this is the total size of the MaskData, the BlendingRangesData, the
            // Name and the AdjustmenLayerInfo
            uint extraDataSize = reader.ReadUInt32();


            // remember the start position for calculation of the
            // AdjustmenLayerInfo size
            long extraDataStartPosition = reader.BaseStream.Position;

            m_maskData           = new Mask(reader, this);
            m_blendingRangesData = new BlendingRanges(reader, this);

            //-----------------------------------------------------------------------

            var namePosition = reader.BaseStream.Position;

            m_name = reader.ReadPascalString();

            var paddingBytes = (int)((reader.BaseStream.Position - namePosition) % 4);

            Debug.Print("Layer {0} padding bytes after name", paddingBytes);
            reader.ReadBytes(paddingBytes);

            //-----------------------------------------------------------------------

            m_adjustmentInfo.Clear();

            long adjustmenLayerEndPos = extraDataStartPosition + extraDataSize;

            while (reader.BaseStream.Position < adjustmenLayerEndPos)
            {
                try
                {
                    m_adjustmentInfo.Add(new AdjusmentLayerInfo(reader, this));
                }
                catch
                {
                    reader.BaseStream.Position = adjustmenLayerEndPos;
                }
            }


            //-----------------------------------------------------------------------
            // make shure we are not on a wrong offset, so set the stream position
            // manually
            reader.BaseStream.Position = adjustmenLayerEndPos;
        }
        /////////////////////////////////////////////////////////////////////////// 
        private static Color GetColor(PsdFile psdFile, int pos)
        {
            Color c = Color.White;

              switch (psdFile.ColorMode)
              {
            case PsdFile.ColorModes.RGB:
              c = Color.FromArgb(psdFile.ImageData[0][pos],
                             psdFile.ImageData[1][pos],
                             psdFile.ImageData[2][pos]);
              break;
            case PsdFile.ColorModes.CMYK:
              c = CMYKToRGB(psdFile.ImageData[0][pos],
                        psdFile.ImageData[1][pos],
                        psdFile.ImageData[2][pos],
                        psdFile.ImageData[3][pos]);
              break;
            case PsdFile.ColorModes.Multichannel:
              c = CMYKToRGB(psdFile.ImageData[0][pos],
                        psdFile.ImageData[1][pos],
                        psdFile.ImageData[2][pos],
                        0);
              break;
            case PsdFile.ColorModes.Bitmap:
              byte bwValue = ImageDecoder.GetBitmapValue(psdFile.ImageData[0], pos);
              c = Color.FromArgb(bwValue, bwValue, bwValue);
              break;
            case PsdFile.ColorModes.Grayscale:
            case PsdFile.ColorModes.Duotone:
              c = Color.FromArgb(psdFile.ImageData[0][pos],
                             psdFile.ImageData[0][pos],
                             psdFile.ImageData[0][pos]);
              break;
            case PsdFile.ColorModes.Indexed:
              {
            int index = (int)psdFile.ImageData[0][pos];
            c = Color.FromArgb((int)psdFile.ColorModeData[index],
                             psdFile.ColorModeData[index + 256],
                             psdFile.ColorModeData[index + 2 * 256]);
              }
              break;
            case PsdFile.ColorModes.Lab:
              {
            c = LabToRGB(psdFile.ImageData[0][pos],
                         psdFile.ImageData[1][pos],
                         psdFile.ImageData[2][pos]);
              }
              break;
              }

              return c;
        }
Beispiel #34
0
        /// <summary>
        /// Loads the next LayerInfo record.
        /// </summary>
        /// <param name="reader">The file reader</param>
        /// <param name="psdFile">The PSD file.</param>
        /// <param name="globalLayerInfo">True if the LayerInfo record is being
        ///   loaded from the end of the Layer and Mask Information section;
        ///   false if it is being loaded from the end of a Layer record.</param>
        /// <returns>LayerInfo object if it was successfully read, or null if
        ///   padding was found.</returns>
        private static LayerInfo Load(PsdBinaryReader reader, PsdFile psdFile,
                                      bool globalLayerInfo)
        {
            Util.DebugMessage(reader.BaseStream, "Load, Begin, LayerInfo");

            // Most keys have undocumented signatures, so we always accept either one.
            var signature = reader.ReadAsciiChars(4);

            if ((signature != "8BIM") && (signature != "8B64"))
            {
                throw new PsdInvalidException(
                          $"{nameof(LayerInfo)} signature invalid, must be 8BIM or 8B64.");
            }

            var key           = reader.ReadAsciiChars(4);
            var hasLongLength = LayerInfoUtil.HasLongLength(signature, key, psdFile.IsLargeDocument);
            var length        = hasLongLength
        ? reader.ReadInt64()
        : reader.ReadInt32();
            var startPosition = reader.BaseStream.Position;

            LayerInfo result;

            switch (key)
            {
            case "Layr":
            case "Lr16":
            case "Lr32":
                result = new InfoLayers(reader, psdFile, key, length);
                break;

            case "lsct":
            case "lsdk":
                result = new LayerSectionInfo(reader, key, (int)length);
                break;

            case "luni":
                result = new LayerUnicodeName(reader);
                break;

            default:
                result = new RawLayerInfo(reader, signature, key, length);
                break;
            }

            // May have additional padding applied.
            var endPosition = startPosition + length;

            if (reader.BaseStream.Position < endPosition)
            {
                reader.BaseStream.Position = endPosition;
            }

            // Documentation states that the length is even-padded.  Actually:
            //   1. Most keys have 4-padded lengths.
            //   2. However, some keys (LMsk) have even-padded lengths.
            //   3. Other keys (Txt2, Lr16, Lr32) have unpadded lengths.
            //
            // Photoshop writes data that is always 4-padded, even when the stated
            // length is not a multiple of 4.  The length mismatch seems to occur
            // only on global layer info.  We do not read extra padding in other
            // cases because third-party programs are likely to follow the spec.

            if (globalLayerInfo)
            {
                reader.ReadPadding(startPosition, 4);
            }

            Util.DebugMessage(reader.BaseStream,
                              $"Load, End, LayerInfo, {result.Signature}, {result.Key}");
            return(result);
        }
    public Layer(PsdBinaryReader reader, PsdFile psdFile)
      : this(psdFile)
    {
      Rect = reader.ReadRectangle();

      //-----------------------------------------------------------------------
      // Read channel headers.  Image data comes later, after the layer header.

      int numberOfChannels = reader.ReadUInt16();
      for (int channel = 0; channel < numberOfChannels; channel++)
      {
        var ch = new Channel(reader, this);
        Channels.Add(ch);
      }

      //-----------------------------------------------------------------------
      // 

      var signature = reader.ReadAsciiChars(4);
      if (signature != "8BIM")
        throw (new PsdInvalidException("Invalid signature in layer header."));

      BlendModeKey = reader.ReadAsciiChars(4);
      Opacity = reader.ReadByte();
      Clipping = reader.ReadBoolean();

      var flagsByte = reader.ReadByte();
      flags = new BitVector32(flagsByte);
      reader.ReadByte(); //padding

      //-----------------------------------------------------------------------

      // This is the total size of the MaskData, the BlendingRangesData, the 
      // Name and the AdjustmentLayerInfo.
      var extraDataSize = reader.ReadUInt32();
      var extraDataStartPosition = reader.BaseStream.Position;

      Masks = new MaskInfo(reader, this);
      BlendingRangesData = new BlendingRanges(reader, this);
      Name = reader.ReadPascalString(4);

      //-----------------------------------------------------------------------
      // Process Additional Layer Information

      long adjustmentLayerEndPos = extraDataStartPosition + extraDataSize;
      while (reader.BaseStream.Position < adjustmentLayerEndPos)
      {
        var layerInfo = LayerInfoFactory.Load(reader);
        AdditionalInfo.Add(layerInfo);
      }

      foreach (var adjustmentInfo in AdditionalInfo)
      {
        switch (adjustmentInfo.Key)
        {
          case "luni":
            Name = ((LayerUnicodeName)adjustmentInfo).Name;
            break;
        }
      }

    }
Beispiel #36
0
        ///////////////////////////////////////////////////////////////////////////

        public Layer(PsdFile psdFile)
        {
            m_psdFile = psdFile;
            m_psdFile.Layers.Add(this);
        }
Beispiel #37
0
        private static Texture LoadSpriteSheetAbsolute(string title, string file_name)
        {
            // Load and decompress Photoshop file structures
            var psdFile = new PsdFile ();
            psdFile.Load (file_name, Encoding.Default);

            if (psdFile.Layers.Count == 0) {
                psdFile.BaseLayer.CreateMissingChannels ();
            }
            var layer = psdFile.BaseLayer;
            using (Bitmap bmp = new Bitmap(psdFile.ColumnCount, psdFile.RowCount)) {
                using (Graphics gfx = Graphics.FromImage(bmp)) {
                    gfx.Clear (Color.Transparent);
                    var bmp_data = bmp.LockBits (layer.Rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                    int pixel_size = 4 * sizeof(byte);
                    int idx = 0;
                    for (int i = 0; i < bmp_data.Height; i++) {
                        for (int j = 0; j < bmp_data.Width; j++) {
                            Marshal.Copy (new byte[]{
                            layer.Channels [2].ImageData [idx],
                            layer.Channels [1].ImageData [idx],
                            layer.Channels [0].ImageData [idx],
                            layer.Channels [3].ImageData [idx],
                        }, 0, new IntPtr ((long)bmp_data.Scan0 + i * bmp_data.Stride + j * pixel_size), pixel_size);
                            idx++;
                        }
                    }
                    bmp.UnlockBits (bmp_data);
                }
                var texture = Texture.LoadTexture (title, bmp);
                psdFile.SlicesToTextureRegionInfo (ref texture);
                return texture;
            }
        }
Beispiel #38
0
        //public BitVector32 Flags
        //{
        //    get { return flags; }
        //}
        /// <summary>
        /// Initializes a new instance of the <see cref="Layer"/> class using the provided reader containing the PSD file data.
        /// </summary>
        /// <param name="reader">The reader containing the PSD file data.</param>
        /// <param name="psdFile">The PSD file to set as the parent.</param>
        public Layer(BinaryReverseReader reader, PsdFile psdFile)
        {
            Children = new List<Layer>();
            PsdFile = psdFile;

            // read the rect
            Rect rect = new Rect();
            rect.y = reader.ReadInt32();
            rect.x = reader.ReadInt32();
            rect.height = reader.ReadInt32() - rect.y;
            rect.width = reader.ReadInt32() - rect.x;
            Rect = rect;

            // read the channels
            int channelCount = reader.ReadUInt16();
            Channels = new List<Channel>();
            SortedChannels = new SortedList<short, Channel>();
            for (int index = 0; index < channelCount; ++index)
            {
                Channel channel = new Channel(reader, this);
                Channels.Add(channel);
                SortedChannels.Add(channel.ID, channel);
            }

            // read the header and verify it
            if (new string(reader.ReadChars(4)) != "8BIM")
            {
                throw new IOException("Layer Channelheader error!");
            }

            // read the blend mode key (unused) (defaults to "norm")
            reader.ReadChars(4);

            // read the opacity
            Opacity = reader.ReadByte();

            // read the clipping (unused) (< 0 = base, > 0 = non base)
            reader.ReadByte();

            // read all of the flags (protectTrans, visible, obsolete, ver5orLater, pixelDataIrrelevant)
            flags = new BitVector32(reader.ReadByte());

            // skip a padding byte
            reader.ReadByte();

            uint num3 = reader.ReadUInt32();
            long position1 = reader.BaseStream.Position;
            MaskData = new Mask(reader, this);
            BlendingRangesData = new BlendingRanges(reader);
            long position2 = reader.BaseStream.Position;

            // read the name
            Name = reader.ReadPascalString();

            // read the adjustment info
            int count = (int)((reader.BaseStream.Position - position2) % 4L);
            reader.ReadBytes(count);
            AdjustmentInfo = new List<AdjustmentLayerInfo>();
            long num4 = position1 + num3;
            while (reader.BaseStream.Position < num4)
            {
                try
                {
                    AdjustmentInfo.Add(new AdjustmentLayerInfo(reader, this));
                }
                catch
                {
                    reader.BaseStream.Position = num4;
                }
            }

            foreach (AdjustmentLayerInfo adjustmentLayerInfo in AdjustmentInfo)
            {
                if (adjustmentLayerInfo.Key == "TySh")
                {
                    ReadTextLayer(adjustmentLayerInfo.DataReader);
                }
                else if (adjustmentLayerInfo.Key == "luni")
                {
                    // read the unicode name
                    BinaryReverseReader dataReader = adjustmentLayerInfo.DataReader;
                    dataReader.ReadBytes(3);
                    dataReader.ReadByte();
                    Name = dataReader.ReadString().TrimEnd(new char[1]);
                }
            }

            reader.BaseStream.Position = num4;
        }
Beispiel #39
0
        private void OnSaveClick(object sender, EventArgs e)
        {
            if (m_fileStructure.Nodes.Count == 0)
            return;

              PsdFile psdFileSrc = (PsdFile)m_fileStructure.Nodes[0].Tag;

              PsdFile psdFile = new PsdFile();

              //-----------------------------------------------------------------------

              psdFile.Rows = psdFileSrc.Rows;
              psdFile.Columns = psdFileSrc.Columns;

              // we have an Alpha channel which will be saved,
              // we have to add this to our image resources
              psdFile.Channels = 3;// 4;

              // for now we oly save the images as RGB
              psdFile.ColorMode = PsdFile.ColorModes.RGB;

              psdFile.Depth = 8;

              //-----------------------------------------------------------------------
              // no color mode Data

              //-----------------------------------------------------------------------

              psdFile.ImageResources.Clear();
              psdFile.ImageResources.AddRange(psdFileSrc.ImageResources.ToArray());

              //-----------------------------------------------------------------------

              int size = psdFile.Rows * psdFile.Columns;

              psdFile.ImageData = new byte[psdFile.Channels][];
              for (int i = 0; i < psdFile.Channels; i++)
              {
            psdFile.ImageData[i] = new byte[size];
              }

              Bitmap bmp = ImageDecoder.DecodeImage(psdFileSrc);

              for (int y = 0; y < psdFile.Rows; y++)
              {
            int rowIndex = y * psdFile.Columns;

            for (int x = 0; x < psdFile.Columns; x++)
            {
              int pos = rowIndex + x;

              Color pixelColor = bmp.GetPixel(x, y);

              psdFile.ImageData[0][pos] = pixelColor.R;
              psdFile.ImageData[1][pos] = pixelColor.G;
              psdFile.ImageData[2][pos] = pixelColor.B;
              //psdFile.ImageData[3][pos] = pixelColor.A;
            }
              }

              //-----------------------------------------------------------------------

              psdFile.ImageCompression = ImageCompression.Rle;

              psdFile.Save(Path.Combine(Path.GetDirectoryName(m_fileName.Text), Path.GetFileNameWithoutExtension(m_fileName.Text) + "-saved.psd"));
        }
Beispiel #40
0
        /// <summary>
        /// Loads the next LayerInfo record.
        /// </summary>
        /// <param name="reader">The file reader</param>
        /// <param name="psdFile">The PSD file.</param>
        /// <param name="globalLayerInfo">True if the LayerInfo record is being
        ///   loaded from the end of the Layer and Mask Information section;
        ///   false if it is being loaded from the end of a Layer record.</param>
        public static LayerInfo Load(PsdBinaryReader reader, PsdFile psdFile,
                                     bool globalLayerInfo, long fileEndPos)
        {
            Util.DebugMessage(reader.BaseStream, "Load, Begin, LayerInfo");

            // Some keys use a signature of 8B64, but the identity of these keys
            // is undocumented.  We will therefore accept either signature.
            var signature = reader.ReadAsciiChars(4);

            if ((signature != "8BIM") && (signature != "8B64"))
            {
                throw new PsdInvalidException(
                          "LayerInfo signature invalid, must be 8BIM or 8B64.");
            }

            var       key           = reader.ReadAsciiChars(4);
            var       hasLongLength = LayerInfoUtil.HasLongLength(key, psdFile.IsLargeDocument);
            LayerInfo result        = new RawLayerInfo("dummy");
            bool      breakFromLoop = false;

            while (!breakFromLoop)
            {
                var baseStartPosition = reader.BaseStream.Position;
                var length            = hasLongLength
                    ? reader.ReadInt64()
                    : reader.ReadInt32();
                var startPosition = reader.BaseStream.Position;


                switch (key)
                {
                case "Layr":
                case "Lr16":
                case "Lr32":
                    result = new InfoLayers(reader, psdFile, key, length);
                    break;

                case "lsct":
                case "lsdk":
                    result = new LayerSectionInfo(reader, key, (int)length);
                    break;

                case "luni":
                    result = new LayerUnicodeName(reader);
                    break;

                case "lyid":
                    result = new LayerId(reader, key, length);
                    break;

                default:
                    result = new RawLayerInfo(reader, signature, key, length);
                    break;
                }

                // May have additional padding applied.
                var endPosition = startPosition + length;
                if (reader.BaseStream.Position < endPosition)
                {
                    reader.BaseStream.Position = endPosition;
                }

                // Documentation states that the length is even-padded.  Actually:
                //   1. Most keys have 4-padded lengths.
                //   2. However, some keys (LMsk) have even-padded lengths.
                //   3. Other keys (Txt2, Lr16, Lr32) have unpadded lengths.
                //
                // Photoshop writes data that is always 4-padded, even when the stated
                // length is not a multiple of 4.  The length mismatch seems to occur
                // only on global layer info.  We do not read extra padding in other
                // cases because third-party programs are likely to follow the spec.

                if (globalLayerInfo)
                {
                    reader.ReadPadding(startPosition, 4);
                }

                //try if we can read the next signature
                if (reader.BaseStream.Position < fileEndPos)
                {
                    var nowPosition = reader.BaseStream.Position;
                    signature = reader.ReadAsciiChars(4);
                    if ((signature != "8BIM") && (signature != "8B64"))
                    {
                        hasLongLength = true;
                        reader.BaseStream.Position = baseStartPosition;
                    }
                    else
                    {
                        reader.BaseStream.Position = nowPosition;
                        breakFromLoop = true;
                    }
                }
                else
                {
                    breakFromLoop = true;
                }
            }


            Util.DebugMessage(reader.BaseStream, "Load, End, LayerInfo, {0}, {1}",
                              result.Signature, result.Key);
            return(result);
        }
Beispiel #41
0
        private void OnOpenClick(object sender, EventArgs e)
        {
            string fileName = m_fileName.Text;
              if (File.Exists(fileName))
              {
            UpdateFileLst(fileName);

            PsdFile pt = new PsdFile();

            this.Cursor = Cursors.WaitCursor;
            pt.Load(fileName);

            m_fileStructure.Nodes.Clear();

            TreeNode fileNode = new TreeNode("PSD File");
            fileNode.Tag = pt;

            m_fileStructure.Nodes.Add(fileNode);

            foreach (Layer layer in pt.Layers)
            {
              TreeNode layerNode = new TreeNode("Layer Name=" + layer.Name);
              layerNode.Tag = layer;
              fileNode.Nodes.Add(layerNode);

              foreach (Layer.Channel ch in layer.Channels)
              {
            TreeNode chNode = new TreeNode("Channel ID=" + ch.ID.ToString());
            chNode.Tag = ch;
            layerNode.Nodes.Add(chNode);
              }

              TreeNode maskNode = new TreeNode("Mask");
              maskNode.Tag = layer.MaskData;
              layerNode.Nodes.Add(maskNode);

              TreeNode blendingNode = new TreeNode("BlendingRangesData");
              blendingNode.Tag = layer.BlendingRangesData;
              layerNode.Nodes.Add(blendingNode);

              foreach (Layer.AdjustmentLayerInfo adjInfo in layer.AdjustmentInfo)
              {
            TreeNode node = new TreeNode(adjInfo.Key);
            node.Tag = adjInfo;
            layerNode.Nodes.Add(node);
              }
            }

            m_fileStructure.SelectedNode = fileNode;

            this.Cursor = Cursors.Default;

            //pt.Save(Path.Combine(Path.GetDirectoryName(m_fileName.Text), Path.GetFileNameWithoutExtension(m_fileName.Text) + "-s.psd"));
              }
        }
        /////////////////////////////////////////////////////////////////////////// 

        // fix for performance
        private static void SetDestinationColor(PsdFile psdFile, byte[] arrayARGB, int nOutputOffset,
            int nSourcePosition)
        {
            Color c = Color.White;

            switch (psdFile.ColorMode)
            {
                case PsdFile.ColorModes.RGB:
                    // can take advantage of a direct copy of the bytes
                    arrayARGB[nOutputOffset + 3] = (3 < psdFile.ImageData.Length
                        ? psdFile.ImageData[3][nSourcePosition]
                        : (byte) 255);
                    // ABGR - apparently
                    arrayARGB[nOutputOffset + 2] = psdFile.ImageData[0][nSourcePosition];
                    arrayARGB[nOutputOffset + 1] = psdFile.ImageData[1][nSourcePosition];
                    arrayARGB[nOutputOffset + 0] = psdFile.ImageData[2][nSourcePosition];
                    return;
                case PsdFile.ColorModes.CMYK:
                    c = CMYKToRGB(psdFile.ImageData[0][nSourcePosition],
                        psdFile.ImageData[1][nSourcePosition],
                        psdFile.ImageData[2][nSourcePosition],
                        psdFile.ImageData[3][nSourcePosition]);
                    break;
                case PsdFile.ColorModes.Multichannel:
                    c = CMYKToRGB(psdFile.ImageData[0][nSourcePosition],
                        psdFile.ImageData[1][nSourcePosition],
                        psdFile.ImageData[2][nSourcePosition],
                        0);
                    break;
                case PsdFile.ColorModes.Grayscale:
                case PsdFile.ColorModes.Duotone:
                    // can take advantage of a direct copy of the bytes
                    // TODO: can alpha channel be used?
                    arrayARGB[nOutputOffset + 3] = 0xff;
                    arrayARGB[nOutputOffset + 0] = psdFile.ImageData[0][nSourcePosition];
                    arrayARGB[nOutputOffset + 1] = psdFile.ImageData[0][nSourcePosition];
                    arrayARGB[nOutputOffset + 2] = psdFile.ImageData[0][nSourcePosition];
                    return;
                case PsdFile.ColorModes.Indexed:
                {
                    var index = (int) psdFile.ImageData[0][nSourcePosition];
                    c = Color.FromArgb(psdFile.ColorModeData[index],
                        psdFile.ColorModeData[index + 256],
                        psdFile.ColorModeData[index + 2*256]);
                }
                    break;
                case PsdFile.ColorModes.Lab:
                {
                    c = LabToRGB(psdFile.ImageData[0][nSourcePosition],
                        psdFile.ImageData[1][nSourcePosition],
                        psdFile.ImageData[2][nSourcePosition]);
                }
                    break;
            }

            // populate the color data
            // ABGR - apparently
            arrayARGB[nOutputOffset + 3] = c.A;
            arrayARGB[nOutputOffset + 0] = c.B;
            arrayARGB[nOutputOffset + 1] = c.G;
            arrayARGB[nOutputOffset + 2] = c.R;
        }
		public PsdExportSettings(Texture2D image)
		{
			string path = AssetDatabase.GetAssetPath(image);
			if (!path.ToUpper().EndsWith(".PSD"))
				return;

			Psd = new PsdFile(path, Encoding.Default);
			Filename = Path.GetFileNameWithoutExtension(path);
			Image = image;

			ScaleBy = 0;
			Pivot = SpriteAlignment.Center;
			PixelsToUnitSize = 100f;

			LoadMetaData();
		}
        private static Color GetColor(PsdFile psdFile, int pos)
        {
            Color c = Color.White;

            switch (psdFile.ColorMode)
            {
                case PsdFile.ColorModes.RGB:
                    c = Color.FromArgb(
                        // read alpha if that channel is available (otherwise default to full alpha)
                        (3 < psdFile.ImageData.Length ? psdFile.ImageData[3][pos] : 255),
                        psdFile.ImageData[0][pos],
                        psdFile.ImageData[1][pos],
                        psdFile.ImageData[2][pos]);
                    break;
                case PsdFile.ColorModes.CMYK:
                    c = CMYKToRGB(psdFile.ImageData[0][pos],
                        psdFile.ImageData[1][pos],
                        psdFile.ImageData[2][pos],
                        psdFile.ImageData[3][pos]);
                    break;
                case PsdFile.ColorModes.Multichannel:
                    c = CMYKToRGB(psdFile.ImageData[0][pos],
                        psdFile.ImageData[1][pos],
                        psdFile.ImageData[2][pos],
                        0);
                    break;
                case PsdFile.ColorModes.Grayscale:
                case PsdFile.ColorModes.Duotone:
                    c = Color.FromArgb(psdFile.ImageData[0][pos],
                        psdFile.ImageData[0][pos],
                        psdFile.ImageData[0][pos]);
                    break;
                case PsdFile.ColorModes.Indexed:
                {
                    int index = (int) psdFile.ImageData[0][pos];
                    c = Color.FromArgb((int) psdFile.ColorModeData[index],
                        psdFile.ColorModeData[index + 256],
                        psdFile.ColorModeData[index + 2*256]);
                }
                    break;
                case PsdFile.ColorModes.Lab:
                {
                    c = LabToRGB(psdFile.ImageData[0][pos],
                        psdFile.ImageData[1][pos],
                        psdFile.ImageData[2][pos]);
                }
                    break;
            }

            return c;
        }
        /////////////////////////////////////////////////////////////////////////// 

        public static Bitmap DecodeImage(PsdFile psdFile)
        {
            var bitmap = new Bitmap(psdFile.Columns, psdFile.Rows, PixelFormat.Format32bppArgb);
            // Fix to support different pixel resolutions
            bitmap.SetResolution(psdFile.Resolution.HRes, psdFile.Resolution.VRes);

#if TEST
      for (int y = 0; y < psdFile.Rows; y++)
      {
        int rowIndex = y * psdFile.Columns;

        for (int x = 0; x < psdFile.Columns; x++)
        {
          int pos = rowIndex + x;

          Color pixelColor=GetColor(psdFile,pos);

          bitmap.SetPixel(x, y, pixelColor);
        }
      }

#else
#if true // fix remove unsafeness (admittedly slower)
#if false // safe + slow 
        for (int y = 0; y < psdFile.Rows; y++)
        {
            int rowIndex = y * psdFile.Columns;
            for (int x = 0; x < psdFile.Columns; x++)
            {
                int pos = rowIndex + x;

                Color pixelColor = GetColor(psdFile, pos);

                bitmap.SetPixel(x, y, pixelColor/*Color.FromArgb(255, pixelColor)*/);
            }
        }
#else // safe + fast
            // based on MSDN -- Bitmap.LockBits
            // Lock the bitmap's bits.  
            var bmpData = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadWrite,
                bitmap.PixelFormat);

            // Get the address of the first line.
            var ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            var nDestLength = Math.Abs(bmpData.Stride)*bitmap.Height;
            var arrayOutputARGB = new byte[nDestLength];

            // Copy the RGB values into the array.
            System.Runtime.InteropServices.Marshal.Copy(ptr, arrayOutputARGB, 0, nDestLength);

            var nOutputOffset = 0;
            for (var y = 0; y < psdFile.Rows; y++)
            {
                var rowIndex = y*psdFile.Columns;
                for (var x = 0; x < psdFile.Columns; x++)
                {
                    var nSourcePosition = rowIndex + x;
                    SetDestinationColor(psdFile, arrayOutputARGB, nOutputOffset, nSourcePosition);
                    nOutputOffset += 4;
                }
            }

            // Copy the RGB values back to the bitmap
            System.Runtime.InteropServices.Marshal.Copy(arrayOutputARGB, 0, ptr, nDestLength);

            // Unlock the bits.
            bitmap.UnlockBits(bmpData);
#endif
#else
      Rectangle r = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
      BitmapData bd = bitmap.LockBits(r, ImageLockMode.ReadWrite, bitmap.PixelFormat);

      unsafe
      {
        byte* pCurrRowPixel = (byte*)bd.Scan0.ToPointer();

        for (int y = 0; y < psdFile.Rows; y++)
        {
          int rowIndex = y * psdFile.Columns;
          PixelData* pCurrPixel = (PixelData*)pCurrRowPixel;
          for (int x = 0; x < psdFile.Columns; x++)
          {
            int pos = rowIndex + x;

            Color pixelColor = GetColor(psdFile, pos);

            pCurrPixel->Alpha = 255;
            pCurrPixel->Red = pixelColor.R;
            pCurrPixel->Green = pixelColor.G;
            pCurrPixel->Blue = pixelColor.B;

            pCurrPixel += 1;
          }
          pCurrRowPixel += bd.Stride;
        }
      }

      bitmap.UnlockBits(bd);
#endif
#endif

            return bitmap;
        }
Beispiel #46
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Layer"/> class using the provided reader containing the PSD file data.
        /// </summary>
        /// <param name="reader">The reader containing the PSD file data.</param>
        /// <param name="psdFile">The PSD file to set as the parent.</param>
        public Layer(BinaryReverseReader reader, PsdFile psdFile)
        {
            Children = new List <Layer>();
            PsdFile  = psdFile;

            // read the rect
            Rect rect = new Rect();

            rect.y      = reader.ReadInt32();
            rect.x      = reader.ReadInt32();
            rect.height = reader.ReadInt32() - rect.y;
            rect.width  = reader.ReadInt32() - rect.x;
            Rect        = rect;

            // read the channels
            int channelCount = reader.ReadUInt16();

            Channels       = new List <Channel>();
            SortedChannels = new SortedList <short, Channel>();
            for (int index = 0; index < channelCount; ++index)
            {
                Channel channel = new Channel(reader, this);
                Channels.Add(channel);
                SortedChannels.Add(channel.ID, channel);
            }

            // read the header and verify it
            if (new string(reader.ReadChars(4)) != "8BIM")
            {
                throw new IOException("Layer Channelheader error!");
            }

            // read the blend mode key (unused) (defaults to "norm")
            reader.ReadChars(4);

            // read the opacity
            Opacity = reader.ReadByte();

            // read the clipping (unused) (< 0 = base, > 0 = non base)
            reader.ReadByte();

            // read all of the flags (protectTrans, visible, obsolete, ver5orLater, pixelDataIrrelevant)
            flags = new BitVector32(reader.ReadByte());

            // skip a padding byte
            reader.ReadByte();

            uint num3      = reader.ReadUInt32();
            long position1 = reader.BaseStream.Position;

            MaskData           = new Mask(reader, this);
            BlendingRangesData = new BlendingRanges(reader);
            long position2 = reader.BaseStream.Position;

            // read the name
            Name = reader.ReadPascalString();

            // read the adjustment info
            int count = (int)((reader.BaseStream.Position - position2) % 4L);

            reader.ReadBytes(count);
            AdjustmentInfo = new List <AdjustmentLayerInfo>();
            long num4 = position1 + num3;

            while (reader.BaseStream.Position < num4)
            {
                try
                {
                    AdjustmentInfo.Add(new AdjustmentLayerInfo(reader, this));
                }
                catch
                {
                    reader.BaseStream.Position = num4;
                }
            }

            foreach (AdjustmentLayerInfo adjustmentLayerInfo in AdjustmentInfo)
            {
                if (adjustmentLayerInfo.Key == "TySh")
                {
                    ReadTextLayer(adjustmentLayerInfo.DataReader);
                }
                else if (adjustmentLayerInfo.Key == "luni")
                {
                    // read the unicode name
                    BinaryReverseReader dataReader = adjustmentLayerInfo.DataReader;
                    dataReader.ReadBytes(3);
                    dataReader.ReadByte();
                    Name = dataReader.ReadString().TrimEnd(new char[1]);
                }
            }

            reader.BaseStream.Position = num4;
        }
Beispiel #47
0
        public Layer(PsdBinaryReader reader, PsdFile psdFile)
            : this(psdFile)
        {
            IsText = false;
            Rect   = reader.ReadRectangle();

            //-----------------------------------------------------------------------
            // Read channel headers.  Image data comes later, after the layer header.

            int numberOfChannels = reader.ReadUInt16();
            for (int channel = 0; channel < numberOfChannels; channel++)
            {
                var ch = new Channel(reader, this);
                Channels.Add(ch);
            }

            //-----------------------------------------------------------------------
            //

            var signature = reader.ReadAsciiChars(4);
            if (signature != "8BIM")
            {
                throw (new PsdInvalidException("Invalid signature in layer header."));
            }

            BlendModeKey = reader.ReadAsciiChars(4);
            Opacity      = reader.ReadByte();
            Clipping     = reader.ReadBoolean();

            var flagsByte = reader.ReadByte();
            flags = new BitVector32(flagsByte);
            reader.ReadByte();             //padding

            //-----------------------------------------------------------------------

            // This is the total size of the MaskData, the BlendingRangesData, the
            // Name and the AdjustmentLayerInfo.
            var extraDataSize          = reader.ReadUInt32();
            var extraDataStartPosition = reader.BaseStream.Position;

            Masks = new MaskInfo(reader, this);
            BlendingRangesData = new BlendingRanges(reader, this);
            Name = reader.ReadPascalString(4);

            //-----------------------------------------------------------------------
            // Process Additional Layer Information

            long adjustmentLayerEndPos = extraDataStartPosition + extraDataSize;
            while (reader.BaseStream.Position < adjustmentLayerEndPos)
            {
                var layerInfo = LayerInfoFactory.Load(reader);
                AdditionalInfo.Add(layerInfo);
            }

            foreach (var adjustmentInfo in AdditionalInfo)
            {
                switch (adjustmentInfo.Key)
                {
                case "luni":
                    Name = ((LayerUnicodeName)adjustmentInfo).Name;
                    break;

                case "TySh":
                    IsText    = true;
                    LayerText = (LayerText)adjustmentInfo;
                    break;

                case "lrFX":
                    Effects = (EffectsLayer)adjustmentInfo;
                    break;

                case "lfx2":
                    BaseEffect = (ObjectBasedEffect)adjustmentInfo;
                    break;
                }
            }
        }