• C# 读写 Photoshop PSD文件 操作类


    分析了PSD的文件....才发现PSD的RGB色彩保存也是 先红 蓝 绿 这样保存的 ....麻烦的..
    
    另外8BIM好象没什么用..可以直接跳过..直接获取最后的图形信息就可以了.. 我只对一些PSD文件进行了解析如果大家使用中碰到不能识别的请告诉我.发送信息到zgke@Sina.com 或则给我留言就可以了。
    
     
    
    另外这个BLOG的插入代码我不用了...太郁闷了...
    
     
    
    使用方法
    
    显示PSD
    
                OpenFileDialog _Dialog = new OpenFileDialog();
                _Dialog.Filter = "*.psd|*.psd";
    
                if (_Dialog.ShowDialog() == DialogResult.OK)
                {
                    Zgke.MyImage.ImageFile.ImagePsd _Psd = new Zgke.MyImage.ImageFile.ImagePsd(_Dialog.FileName);
                    pictureBox1.Image = _Psd.PSDImage;
                }
    
     
    
     
    
     
    
    保存PSD
    
      Zgke.MyImage.ImageFile.ImagePsd _Psd = new Zgke.MyImage.ImageFile.ImagePsd();
                _Psd.PSDImage = this.Icon.ToBitmap();
                _Psd.Save(@"C:/Temp/1.psd");           
    
     
    
     
    
    下面是全部的类
    
     using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Drawing.Imaging;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.IO;
    
    namespace Zgke.MyImage.ImageFile
    {
        /// <summary>
        /// Photoshop PSD文件
        /// zgke@sina.com
        /// qq:116149
        /// </summary>
        public class ImagePsd
        {
            private class PSDHEAD
            {
                private byte[] m_HeadBytes = new byte[26];
    
                public byte[] GetBytes()
                {
                    return m_HeadBytes;
                }
    
                public PSDHEAD(byte[] p_Data)
                {
                    m_HeadBytes = p_Data;
                }
    
                /// <summary>
                /// 版本
                /// </summary>
                public byte Version { get { return m_HeadBytes[5]; } set { m_HeadBytes[5] = value; } }
    
                /// <summary>
                /// 颜色数  3为24位  4位23位
                /// </summary>
                public ushort Channels
                {
                    get
                    {
                        return BitConverter.ToUInt16(new byte[] { m_HeadBytes[13], m_HeadBytes[12] }, 0);
                    }
                    set
                    {
                        byte[] _Value = BitConverter.GetBytes(value);
                        m_HeadBytes[13] = _Value[1];
                        m_HeadBytes[12] = _Value[0];
                    }
                }
    
                /// <summary>
                /// 
                /// </summary>
                public uint Height
                {
                    get
                    {
                        return BitConverter.ToUInt32(new byte[] { m_HeadBytes[17], m_HeadBytes[16], m_HeadBytes[15], m_HeadBytes[14] }, 0);
                    }
                    set
                    {
                        byte[] _Value = BitConverter.GetBytes(value);
                        m_HeadBytes[17] = _Value[0];
                        m_HeadBytes[16] = _Value[1];
                        m_HeadBytes[15] = _Value[2];
                        m_HeadBytes[14] = _Value[3];
                    }
                }
    
                /// <summary>
                /// 
                /// </summary>
                public uint Width
                {
                    get
                    {
                        return BitConverter.ToUInt32(new byte[] { m_HeadBytes[21], m_HeadBytes[20], m_HeadBytes[19], m_HeadBytes[18] }, 0);
                    }
                    set
                    {
                        byte[] _Value = BitConverter.GetBytes(value);
                        m_HeadBytes[21] = _Value[0];
                        m_HeadBytes[20] = _Value[1];
                        m_HeadBytes[19] = _Value[2];
                        m_HeadBytes[18] = _Value[3];
                    }
                }
    
                public ushort BitsPerPixel
                {
                    get
                    {
                        return BitConverter.ToUInt16(new byte[] { m_HeadBytes[23], m_HeadBytes[22] }, 0);
                    }
                    set
                    {
                        byte[] _Value = BitConverter.GetBytes(value);
                        m_HeadBytes[23] = _Value[1];
                        m_HeadBytes[22] = _Value[0];
                    }
    
                }
    
                public ushort ColorMode
                {
                    get
                    {
                        return BitConverter.ToUInt16(new byte[] { m_HeadBytes[25], m_HeadBytes[24] }, 0);
                    }
                    set
                    {
                        byte[] _Value = BitConverter.GetBytes(value);
                        m_HeadBytes[25] = _Value[1];
                        m_HeadBytes[24] = _Value[0];
                    }
                }
    
                public PSDHEAD()
                {
                    m_HeadBytes[0] = 0x38;
                    m_HeadBytes[1] = 0x42;
                    m_HeadBytes[2] = 0x50;
                    m_HeadBytes[3] = 0x53;
                    m_HeadBytes[5] = 0x01;
    
                    ColorMode = 3;
                    BitsPerPixel = 8;
                }
            }
            private class ColorModel
            {
                private byte[] m_ColorData;
    
                public ColorPalette ColorData
                {
                    get
                    {
                        Bitmap _Bitmap = new Bitmap(1, 1, PixelFormat.Format8bppIndexed);
                        ColorPalette _ColorPalette = _Bitmap.Palette;
                        if (m_ColorData.Length == 0) return _ColorPalette;
                        for (int i = 0; i != 256; i++)
                        {
                            _ColorPalette.Entries[i] = Color.FromArgb(m_ColorData[i], m_ColorData[i + 256], m_ColorData[i + 512]);
                        }
                        return _ColorPalette;
                    }
                    set
                    {
                        m_ColorData = new byte[768];
                        for (int i = 0; i != 256; i++)
                        {
                            m_ColorData[i] = value.Entries[i].R;
                            m_ColorData[i + 256] = value.Entries[i].G;
                            m_ColorData[i + 512] = value.Entries[i].B;
                        }
                    }
                }
    
                private byte[] m_BIMSize = new byte[4];
    
                public uint BIMSize
                {
                    get
                    {
                        return BitConverter.ToUInt32(new byte[] { m_BIMSize[3], m_BIMSize[2], m_BIMSize[1], m_BIMSize[0] }, 0);
                    }
                    set
                    {
                        byte[] _Value = BitConverter.GetBytes(value);
                        m_BIMSize[0] = _Value[3];
                        m_BIMSize[1] = _Value[2];
                        m_BIMSize[2] = _Value[1];
                        m_BIMSize[3] = _Value[0];
                    }
                }
    
                public ColorModel(FileStream p_FileStream)
                {
                    byte[] _CountByte = new byte[4];
                    p_FileStream.Read(_CountByte, 0, 4);
                    Array.Reverse(_CountByte);
                    int _Count = BitConverter.ToInt32(_CountByte, 0);
                    m_ColorData = new byte[_Count];
                    if (_Count != 0) p_FileStream.Read(m_ColorData, 0, _Count);
                    p_FileStream.Read(m_BIMSize, 0, 4);
                }
    
                public ColorModel()
                {
                    m_ColorData = new byte[0];
                }
    
                public byte[] GetBytes()
                {
                    MemoryStream _Memory = new MemoryStream();
                    byte[] _Value = BitConverter.GetBytes(m_ColorData.Length);
                    Array.Reverse(_Value);
                    _Memory.Write(_Value, 0, _Value.Length);
                    _Memory.Write(m_ColorData, 0, m_ColorData.Length);
                    _Memory.Write(m_BIMSize, 0, 4);
                    return _Memory.ToArray();
                }
            }
            private class BIM
            {
                private byte[] m_Data = new byte[] { 0x38, 0x42, 0x49, 0x4D };
                private byte[] m_TypeID = new byte[2];
                private byte[] m_Name = new byte[0];
    
                public ushort TypeID
                {
                    get
                    {
                        return BitConverter.ToUInt16(new byte[] { m_TypeID[1], m_TypeID[0] }, 0);
                    }
                    set
                    {
                        byte[] _Value = BitConverter.GetBytes(value);
                        m_TypeID[0] = _Value[1];
                        m_TypeID[1] = _Value[0];
                    }
                }
    
                public byte[] m_Value;
    
                public BIM(FileStream p_FileStream)
                {
                    byte[] _Type = new byte[4];
                    p_FileStream.Read(_Type, 0, 4);
                    if (m_Data[0] == _Type[0] && m_Data[1] == _Type[1] && m_Data[2] == _Type[2] && m_Data[3] == _Type[3])
                    {
                        p_FileStream.Read(m_TypeID, 0, 2);
                        int _SizeOfName = p_FileStream.ReadByte();
                        int _nSizeOfName = (int)_SizeOfName;
                        if (_nSizeOfName > 0)
                        {
                            if ((_nSizeOfName % 2) != 0) { _SizeOfName = p_FileStream.ReadByte(); }
                            m_Name = new byte[_nSizeOfName];
                            p_FileStream.Read(m_Name, 0, _nSizeOfName);
                        }
                        _SizeOfName = p_FileStream.ReadByte();
                        byte[] _CountByte = new byte[4];
                        p_FileStream.Read(_CountByte, 0, 4);
                        Array.Reverse(_CountByte);
                        int _DataCount = BitConverter.ToInt32(_CountByte, 0);
                        if (_DataCount % 2 != 0) _DataCount++;
                        m_Value = new byte[_DataCount];
                        p_FileStream.Read(m_Value, 0, _DataCount);
                        m_Read = true;
                    }
                }
    
                private bool m_Read = false;
    
                public bool Read
                {
                    get { return m_Read; }
                    set { m_Read = value; }
                }
    
                #region Type=1005
                public ushort hRes
                {
                    get
                    {
                        return BitConverter.ToUInt16(new byte[] { m_Value[1], m_Value[0] }, 0);
                    }
                    set
                    {
                        byte[] _Value = BitConverter.GetBytes(value);
                        m_Value[0] = _Value[1];
                        m_Value[1] = _Value[0];
                    }
                }
                public uint hResUnit
                {
                    get
                    {
                        return BitConverter.ToUInt32(new byte[] { m_Value[5], m_Value[4], m_Value[3], m_Value[2] }, 0);
                    }
                    set
                    {
                        byte[] _Value = BitConverter.GetBytes(value);
                        m_Value[2] = _Value[3];
                        m_Value[3] = _Value[2];
                        m_Value[4] = _Value[1];
                        m_Value[5] = _Value[0];
                    }
                }
                public ushort widthUnit
                {
                    get
                    {
                        return BitConverter.ToUInt16(new byte[] { m_Value[7], m_Value[6] }, 0);
                    }
                    set
                    {
                        byte[] _Value = BitConverter.GetBytes(value);
                        m_Value[6] = _Value[1];
                        m_Value[7] = _Value[0];
                    }
                }
                public ushort vRes
                {
                    get
                    {
                        return BitConverter.ToUInt16(new byte[] { m_Value[9], m_Value[8] }, 0);
                    }
                    set
                    {
                        byte[] _Value = BitConverter.GetBytes(value);
                        m_Value[8] = _Value[1];
                        m_Value[9] = _Value[0];
                    }
                }
                public uint vResUnit
                {
                    get
                    {
                        return BitConverter.ToUInt32(new byte[] { m_Value[13], m_Value[12], m_Value[11], m_Value[10] }, 0);
                    }
                    set
                    {
                        byte[] _Value = BitConverter.GetBytes(value);
                        m_Value[10] = _Value[3];
                        m_Value[11] = _Value[2];
                        m_Value[12] = _Value[1];
                        m_Value[13] = _Value[0];
                    }
                }
                public ushort heightUnit
                {
                    get
                    {
                        return BitConverter.ToUInt16(new byte[] { m_Value[15], m_Value[14] }, 0);
                    }
                    set
                    {
                        byte[] _Value = BitConverter.GetBytes(value);
                        m_Value[14] = _Value[1];
                        m_Value[15] = _Value[0];
                    }
                }
                #endregion
    
            }
            private class LayerMaskInfo
            {
    
                public byte[] m_Data = new byte[0];
    
                public LayerMaskInfo(FileStream p_Stream)
                {
                    byte[] _Count = new byte[4];
                    p_Stream.Read(_Count, 0, 4);
                    Array.Reverse(_Count);
    
                    int _ReadCount = BitConverter.ToInt32(_Count, 0);
    
                    m_Data = new byte[_ReadCount];
                    if (_ReadCount != 0) p_Stream.Read(m_Data, 0, _ReadCount);
                }
    
                public LayerMaskInfo()
                {
                }
    
                public byte[] GetBytes()
                {
                    MemoryStream _Memory = new MemoryStream();
                    byte[] _Value = BitConverter.GetBytes(m_Data.Length);
                    Array.Reverse(_Value);
                    _Memory.Write(_Value, 0, _Value.Length);
                    if (m_Data.Length != 0) _Memory.Write(m_Data, 0, m_Data.Length);
                    return _Memory.ToArray();
                }
            }
            private class ImageData
            {
                private ushort p_Type = 0;
    
                private PSDHEAD m_HeaderInfo;
    
                public ImageData()
                {
                }
                public ImageData(FileStream p_FileStream, PSDHEAD p_HeaderInfo)
                {
                    m_HeaderInfo = p_HeaderInfo;
                    byte[] _ShortBytes = new byte[2];
                    p_FileStream.Read(_ShortBytes, 0, 2);
                    Array.Reverse(_ShortBytes);
                    p_Type = BitConverter.ToUInt16(_ShortBytes, 0);
                    switch (p_Type)
                    {
                        case 0: //RAW DATA
                            RawData(p_FileStream);
                            break;
                        case 1:
                            RleData(p_FileStream);
                            break;
                        default:
                            throw new Exception("Type =" + p_Type.ToString());
                    }
                }
    
                #region RLE数据
                private void RleData(FileStream p_Stream)
                {
                    switch (m_HeaderInfo.ColorMode)
                    {
                        case 3:  //RGB 
                            LoadRLERGB(p_Stream);
                            break;
                        case 4:  //CMYK
                            LoadRLECMYK(p_Stream);
                            break;
                        default:
                            throw new Exception("RLE ColorMode =" + m_HeaderInfo.ColorMode.ToString());
                    }
                }
    
                private void LoadRLERGB(FileStream p_Stream)
                {
                    int _Width = (int)m_HeaderInfo.Width;
                    int _Height = (int)m_HeaderInfo.Height;
                    m_PSDImage = new Bitmap(_Width, _Height, PixelFormat.Format24bppRgb);
                    BitmapData _PSDImageData = m_PSDImage.LockBits(new Rectangle(0, 0, m_PSDImage.Width, m_PSDImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                    byte[] _ImageBytes = new byte[_PSDImageData.Stride * _PSDImageData.Height];
                    int _WriteIndex = 0;
                    int _EndIndex = _PSDImageData.Stride * _PSDImageData.Height;
                    p_Stream.Position += _Height * m_HeaderInfo.Channels * 2;
    
                    int _Count = _Width * _Height;
                    int _WrtieType = 0;
                    int _HeightIndex = 0;
                    int _WidthIndex = 0;
                    int _Index = 0;
    
                    while (true)
                    {
                        if (_WriteIndex > _EndIndex - 1) break;
                        byte _Read = (byte)p_Stream.ReadByte();
                        if (_Read == 128) continue; //Erroe
                        if (_Read > 128)
                        {
                            _Read ^= 0x0FF;
                            _Read += 2;
                            byte _ByteValue = (byte)p_Stream.ReadByte();
    
                            for (byte i = 0; i != _Read; i++)
                            {
                                _WrtieType = _WriteIndex / _Count;
                                switch (_WrtieType)
                                {
                                    case 0: //Red
                                        _HeightIndex = _WriteIndex / _Width;
                                        _WidthIndex = _WriteIndex % _Width;
                                        _Index = (_PSDImageData.Stride * _HeightIndex) + (_WidthIndex * 3) + 2;
                                        _ImageBytes[_Index] = _ByteValue;
                                        break;
                                    case 1: //Green
                                        _HeightIndex = (_WriteIndex - _Count) / _Width;
                                        _WidthIndex = (_WriteIndex - _Count) % _Width;
                                        _Index = (_PSDImageData.Stride * _HeightIndex) + (_WidthIndex * 3) + 1;
                                        _ImageBytes[_Index] = _ByteValue;
                                        break;
                                    case 2:
                                        _HeightIndex = (_WriteIndex - _Count - _Count) / _Width;
                                        _WidthIndex = (_WriteIndex - _Count - _Count) % _Width;
                                        _Index = (_PSDImageData.Stride * _HeightIndex) + (_WidthIndex * 3);
                                        _ImageBytes[_Index] = _ByteValue;
                                        break;
                                }
                                //_ImageBytes[_WriteIndex] = _ByteValue;
                                _WriteIndex++;
                            }
                        }
                        else
                        {
                            _Read++;
                            for (byte i = 0; i != _Read; i++)
                            {
                                _WrtieType = _WriteIndex / _Count;
                                switch (_WrtieType)
                                {
                                    case 0: //Red
                                        _HeightIndex = _WriteIndex / _Width;
                                        _WidthIndex = _WriteIndex % _Width;
                                        _Index = (_PSDImageData.Stride * _HeightIndex) + (_WidthIndex * 3) + 2;
                                        _ImageBytes[_Index] = (byte)p_Stream.ReadByte();
                                        break;
                                    case 1: //Green
                                        _HeightIndex = (_WriteIndex - _Count) / _Width;
                                        _WidthIndex = (_WriteIndex - _Count) % _Width;
                                        _Index = (_PSDImageData.Stride * _HeightIndex) + (_WidthIndex * 3) + 1;
                                        _ImageBytes[_Index] = (byte)p_Stream.ReadByte();
                                        break;
                                    case 2:
                                        _HeightIndex = (_WriteIndex - _Count - _Count) / _Width;
                                        _WidthIndex = (_WriteIndex - _Count - _Count) % _Width;
                                        _Index = (_PSDImageData.Stride * _HeightIndex) + (_WidthIndex * 3);
                                        _ImageBytes[_Index] = (byte)p_Stream.ReadByte();
                                        break;
                                }
                                //_ImageBytes[_WriteIndex] = (byte)p_Stream.ReadByte();
                                _WriteIndex++;
                            }
                        }
                    }
                    Marshal.Copy(_ImageBytes, 0, _PSDImageData.Scan0, _ImageBytes.Length);
                    m_PSDImage.UnlockBits(_PSDImageData);
                }
    
                private void LoadRLECMYK(FileStream p_Stream)
                {
    
                    int _Width = (int)m_HeaderInfo.Width;
                    int _Height = (int)m_HeaderInfo.Height;
    
                    int _Count = _Width * _Height * (m_HeaderInfo.BitsPerPixel / 8) * m_HeaderInfo.Channels;
                    p_Stream.Position += _Height * m_HeaderInfo.Channels * 2;
                    byte[] _ImageBytes = new byte[_Count];
    
                    int _WriteIndex = 0;
                    while (true)
                    {
                        if (_WriteIndex > _Count - 1) break;
                        byte _Read = (byte)p_Stream.ReadByte();
                        if (_Read == 128) continue; //Erroe
                        if (_Read > 128)
                        {
                            _Read ^= 0x0FF;
                            _Read += 2;
                            byte _ByteValue = (byte)p_Stream.ReadByte();
    
                            for (byte i = 0; i != _Read; i++)
                            {
                                _ImageBytes[_WriteIndex] = _ByteValue;
                                _WriteIndex++;
                            }
                        }
                        else
                        {
                            _Read++;
                            for (byte i = 0; i != _Read; i++)
                            {
                                _ImageBytes[_WriteIndex] = (byte)p_Stream.ReadByte();
                                _WriteIndex++;
                            }
                        }
                    }
    
                    m_PSDImage = new Bitmap(_Width, _Height, PixelFormat.Format24bppRgb);
                    BitmapData _PSDImageData = m_PSDImage.LockBits(new Rectangle(0, 0, m_PSDImage.Width, m_PSDImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                    byte[] _WriteBytes = new byte[_PSDImageData.Stride * _PSDImageData.Height];
    
                    int _StarIndex = 0;
                    int _Index = 0;
                    int _Size = _Width * _Height;
                    double C;
                    double M;
                    double Y;
                    double K;
                    double _MaxColours = Math.Pow(2, m_HeaderInfo.BitsPerPixel);
                    int _Size2 = _Size * 2;
                    int _Size3 = _Size * 3;
                    for (int i = 0; i != _PSDImageData.Height; i++)
                    {
                        _StarIndex = _PSDImageData.Stride * i;
                        _Index = i * _Width;
                        for (int z = 0; z != _PSDImageData.Width; z++)
                        {
                            C = 1.0 - (double)_ImageBytes[_Index + z] / _MaxColours;
                            M = 1.0 - (double)_ImageBytes[_Index + z + _Size] / _MaxColours;
                            Y = 1.0 - (double)_ImageBytes[_Index + z + _Size2] / _MaxColours;
                            K = 1.0 - (double)_ImageBytes[_Index + z + _Size3] / _MaxColours;
                            ConvertCMYKToRGB(C, M, Y, K, _WriteBytes, _StarIndex + z * 3);
                        }
                    }
    
                    Marshal.Copy(_WriteBytes, 0, _PSDImageData.Scan0, _WriteBytes.Length);
                    m_PSDImage.UnlockBits(_PSDImageData);
                }
                #endregion
    
                #region RAW数据
                private void RawData(FileStream p_Stream)
                {
                    switch (m_HeaderInfo.ColorMode)
                    {
                        case 2: //Index
                            LoadRAWIndex(p_Stream);
                            return;
                        case 3:  //RGB    
                            LoadRAWRGB(p_Stream);
                            return;
                        case 4: //CMYK
                            LoadRAWCMYK(p_Stream);
                            return;
                        default:
                            throw new Exception("RAW ColorMode =" + m_HeaderInfo.ColorMode.ToString());
                    }
    
                }
    
                private void LoadRAWCMYK(FileStream p_Stream)
                {
                    int _Width = (int)m_HeaderInfo.Width;
                    int _Height = (int)m_HeaderInfo.Height;
                    m_PSDImage = new Bitmap(_Width, _Height, PixelFormat.Format24bppRgb);
                    BitmapData _PSDImageData = m_PSDImage.LockBits(new Rectangle(0, 0, m_PSDImage.Width, m_PSDImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                    byte[] _WriteBytes = new byte[_PSDImageData.Stride * _PSDImageData.Height];
                    int _PerPixel = m_HeaderInfo.BitsPerPixel / 8;
                    int _PixelsCount = _Width * _Height;
                    int _BytesCount = _PixelsCount * 4 * _PerPixel;
                    byte[] _ImageBytes = new byte[_BytesCount];
                    p_Stream.Read(_ImageBytes, 0, _BytesCount);
    
                    int _StarIndex = 0;
                    int _Index = 0;
                    int _Size = _Width * _Height;
                    double C;
                    double M;
                    double Y;
                    double K;
                    double _MaxColours = Math.Pow(2, m_HeaderInfo.BitsPerPixel);
                    int _Size2 = _Size * 2;
                    int _Size3 = _Size * 3;
    
                    if (_PerPixel == 2)
                    {
                        _Size *= 2;
                        _Size2 *= 2;
                        _Size3 *= 2;
                    }
                    for (int i = 0; i != _PSDImageData.Height; i++)
                    {
                        _StarIndex = _PSDImageData.Stride * i;
    
                        _Index = i * _Width;
                        if (_PerPixel == 2) _Index *= 2;
                        for (int z = 0; z != _PSDImageData.Width; z++)
                        {
                            switch (_PerPixel)
                            {
                                case 1:
                                    C = 1.0 - (double)_ImageBytes[_Index + z] / _MaxColours;
                                    M = 1.0 - (double)_ImageBytes[_Index + z + _Size] / _MaxColours;
                                    Y = 1.0 - (double)_ImageBytes[_Index + z + _Size2] / _MaxColours;
                                    K = 1.0 - (double)_ImageBytes[_Index + z + _Size3] / _MaxColours;
                                    ConvertCMYKToRGB(C, M, Y, K, _WriteBytes, _StarIndex + z * 3);
                                    break;
                                case 2:
                                    C = 1.0 - (double)BitConverter.ToUInt16(_ImageBytes, _Index + z * 2) / _MaxColours;
                                    M = 1.0 - (double)BitConverter.ToUInt16(_ImageBytes, _Index + z * 2 + _Size) / _MaxColours;
                                    Y = 1.0 - (double)BitConverter.ToUInt16(_ImageBytes, _Index + z * 2 + _Size2) / _MaxColours;
                                    K = 1.0 - (double)BitConverter.ToUInt16(_ImageBytes, _Index + z * 2 + _Size3) / _MaxColours;
                                    ConvertCMYKToRGB(C, M, Y, K, _WriteBytes, _StarIndex + z * 3);
                                    break;
                            }
    
    
                        }
                    }
                    Marshal.Copy(_WriteBytes, 0, _PSDImageData.Scan0, _WriteBytes.Length);
                    m_PSDImage.UnlockBits(_PSDImageData);
                }
    
                /// <summary>
                /// 直接获取RGB 256色图
                /// </summary>
                /// <param name="p_Stream"></param>
                private void LoadRAWIndex(FileStream p_Stream)
                {
                    int _Width = (int)m_HeaderInfo.Width;
                    int _Height = (int)m_HeaderInfo.Height;
                    m_PSDImage = new Bitmap(_Width, _Height, PixelFormat.Format8bppIndexed);
                    BitmapData _PSDImageData = m_PSDImage.LockBits(new Rectangle(0, 0, m_PSDImage.Width, m_PSDImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
                    byte[] _ImageBytes = new byte[_PSDImageData.Stride * _PSDImageData.Height];
    
                    int _PixelsCount = _Width * _Height;
                    byte[] _Data = new byte[_PixelsCount];
                    p_Stream.Read(_Data, 0, _PixelsCount);
    
                    int _ReadIndex = 0;
                    int _WriteIndex = 0;
                    for (int i = 0; i != _Height; i++)
                    {
                        _WriteIndex = i * _PSDImageData.Stride;
                        for (int z = 0; z != _Width; z++)
                        {
                            _ImageBytes[z + _WriteIndex] = _Data[_ReadIndex];
                            _ReadIndex++;
                        }
                    }
    
                    Marshal.Copy(_ImageBytes, 0, _PSDImageData.Scan0, _ImageBytes.Length);
                    m_PSDImage.UnlockBits(_PSDImageData);
                }
    
                /// <summary>
                /// 获取图形24B   Photo里对应为 
                /// </summary>
                /// <param name="p_Stream"></param>
                private void LoadRAWRGB(FileStream p_Stream)
                {
                    int _Width = (int)m_HeaderInfo.Width;
                    int _Height = (int)m_HeaderInfo.Height;
                    m_PSDImage = new Bitmap(_Width, _Height, PixelFormat.Format24bppRgb);
                    BitmapData _PSDImageData = m_PSDImage.LockBits(new Rectangle(0, 0, m_PSDImage.Width, m_PSDImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                    byte[] _ImageBytes = new byte[_PSDImageData.Stride * _PSDImageData.Height];
    
                    int _PixelsCount = _Width * _Height;
                    int _BytesCount = _PixelsCount * 3 * (m_HeaderInfo.BitsPerPixel / 8);
                    byte[] _Data = new byte[_BytesCount];
                    p_Stream.Read(_Data, 0, _BytesCount);
    
                    int _Red = 0;
                    int _Green = _PixelsCount;
                    int _Blue = _PixelsCount + _PixelsCount;
                    int _ReadIndex = 0;
                    int _WriteIndex = 0;
    
                    if (m_HeaderInfo.BitsPerPixel == 16)
                    {
                        _Green *= m_HeaderInfo.BitsPerPixel / 8;
                        _Blue *= m_HeaderInfo.BitsPerPixel / 8;
                    }
    
                    for (int i = 0; i != _Height; i++)
                    {
                        _WriteIndex = i * _PSDImageData.Stride;
                        for (int z = 0; z != _Width; z++)
                        {
                            _ImageBytes[(z * 3) + 2 + _WriteIndex] = _Data[_ReadIndex + _Red];
                            _ImageBytes[(z * 3) + 1 + _WriteIndex] = _Data[_ReadIndex + _Green];
                            _ImageBytes[(z * 3) + _WriteIndex] = _Data[_ReadIndex + _Blue];
                            _ReadIndex += m_HeaderInfo.BitsPerPixel / 8;
                        }
                    }
                    Marshal.Copy(_ImageBytes, 0, _PSDImageData.Scan0, _ImageBytes.Length);
                    m_PSDImage.UnlockBits(_PSDImageData);
                }
                #endregion
    
                private Bitmap m_PSDImage;
    
                public Bitmap PSDImage
                {
                    get { return m_PSDImage; }
                    set { m_PSDImage = value; }
                }
    
    
                private void ConvertCMYKToRGB(double p_C, double p_M, double p_Y, double p_K, byte[] p_DataBytes, int p_Index)
                {
                    int _Red = (int)((1.0 - (p_C * (1 - p_K) + p_K)) * 255);
                    int _Green = (int)((1.0 - (p_M * (1 - p_K) + p_K)) * 255);
                    int _Blue = (int)((1.0 - (p_Y * (1 - p_K) + p_K)) * 255);
    
                    if (_Red < 0) _Red = 0;
                    else if (_Red > 255) _Red = 255;
                    if (_Green < 0) _Green = 0;
                    else if (_Green > 255) _Green = 255;
                    if (_Blue < 0) _Blue = 0;
                    else if (_Blue > 255) _Blue = 255;
    
                    p_DataBytes[p_Index] = (byte)_Blue;
                    p_DataBytes[p_Index + 1] = (byte)_Green;
                    p_DataBytes[p_Index + 2] = (byte)_Red;
                }
            }
    
            private PSDHEAD m_Head;
            private ColorModel m_ColorModel;
            private IList<BIM> m_8BIMList = new List<BIM>();
            private LayerMaskInfo m_LayerMaskInfo;
            private ImageData m_ImageData;
    
            public ImagePsd(string p_FileFullPath)
            {
                if (!File.Exists(p_FileFullPath)) return;
                FileStream _PSD = File.Open(p_FileFullPath, FileMode.Open);
                byte[] _HeadByte = new byte[26];
                _PSD.Read(_HeadByte, 0, 26);
                m_Head = new PSDHEAD(_HeadByte);
                m_ColorModel = new ColorModel(_PSD);
    
                long _ReadCount = _PSD.Position;
                while (true)
                {
                    BIM _Bim = new BIM(_PSD);
                    if (!_Bim.Read || _PSD.Position - _ReadCount >= m_ColorModel.BIMSize) break;
                    m_8BIMList.Add(_Bim);
                }
                m_LayerMaskInfo = new LayerMaskInfo(_PSD);
                m_ImageData = new ImageData(_PSD, m_Head);
                if (m_Head.ColorMode == 2) m_ImageData.PSDImage.Palette = m_ColorModel.ColorData;
                _PSD.Close();
            }
    
            public ImagePsd()
            {
                NewPsd();
            }
    
            public void NewPsd()
            {
                m_Head = new PSDHEAD(new byte[] { 0x38, 0x42, 0x50, 0x53, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x2C, 0x00, 0x00, 0x01, 0xB4, 0x00, 0x08, 0x00, 0x03 });
                m_ColorModel = new ColorModel();
                m_ImageData = new ImageData();
                m_LayerMaskInfo = new LayerMaskInfo();
            }          
    
            /// <summary>
            /// 保存成PSD 注意这里保存成PSD文件的BIM信息是没用的.如果你用该类打开PSD文件.如果保存到原文件上会丢失Photoshop的设置
            /// </summary>
            /// <param name="p_FileFullName">文件路径</param>
            public void Save(string p_FileFullName)
            {
                if (PSDImage != null)
                {
                    Image _SetImage = PSDImage;
                    NewPsd();
                    PSDImage = (Bitmap)_SetImage;      //保存需要重新在载 
                    int _Width = PSDImage.Width;
                    int _Height = PSDImage.Height;
    
                    m_Head.Height = (uint)_Height;
                    m_Head.Width = (uint)_Width;             
    
                    byte[] _Bim = new byte[] { 0x38, 0x42, 0x49, 0x4D, 0x03, 0xED, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x96, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x96, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x38, 0x42, 0x49, 0x4D, 0x03, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x42, 0x49, 0x4D, 0x27, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 };
                    m_ColorModel.BIMSize = (uint)_Bim.Length;
    
                    FileStream _SaveFile = new FileStream(p_FileFullName, FileMode.Create, FileAccess.Write);
                    byte[] _Bytes = m_Head.GetBytes();
                    _SaveFile.Write(_Bytes, 0, _Bytes.Length);
                    _Bytes = m_ColorModel.GetBytes();
                    _SaveFile.Write(_Bytes, 0, _Bytes.Length);
                    _SaveFile.Write(_Bim, 0, _Bim.Length);
                    _SaveFile.Write(new byte[2], 0, 2);
                    _Bytes = m_LayerMaskInfo.GetBytes();
                    _SaveFile.Write(_Bytes, 0, _Bytes.Length);
                    Bitmap _Bitmap = new Bitmap(_Width, _Height, PixelFormat.Format24bppRgb);
                    Graphics _Graphics = Graphics.FromImage(_Bitmap);
                    _Graphics.DrawImage(PSDImage, 0, 0, _Width, _Height);
                    _Graphics.Dispose();
    
                    BitmapData _SaveData = _Bitmap.LockBits(new Rectangle(0, 0, _Width, _Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                    byte[] _ReadByte = new byte[_SaveData.Stride * _Height];
                    Marshal.Copy(_SaveData.Scan0, _ReadByte, 0, _ReadByte.Length);
                    byte[] _WriteByte = new byte[_Bitmap.Width * _Bitmap.Height * 3];
                    int _Size = _Width * _Height;
                    int _Size2 = _Size * 2;
                    for (int i = 0; i != _Height; i++)
                    {
                        int _Index = i * _SaveData.Stride;
                        int _WriteIndex = i * _Width;
                        for (int z = 0; z != _Width; z++)
                        {
                            _WriteByte[_WriteIndex + z] = _ReadByte[_Index + (z * 3) + 2];
                            _WriteByte[_WriteIndex + _Size + z] = _ReadByte[_Index + (z * 3) + 1];
                            _WriteByte[_WriteIndex + _Size2 + z] = _ReadByte[_Index + (z * 3) + 0];
                        }
                    }
                    _Bitmap.UnlockBits(_SaveData);
                    _Bitmap.Dispose();
    
                    _SaveFile.Write(_WriteByte, 0, _WriteByte.Length);
                    _SaveFile.Close();
                }
            }
    
            /// <summary>
            /// PSD图形
            /// </summary>
            public Bitmap PSDImage
            {
                get { return m_ImageData.PSDImage; }
                set { m_ImageData.PSDImage = value; }
            }
        }
    }

    原文:http://blog.csdn.net/zgke/article/details/4213443

  • 相关阅读:
    Java序列化和反序列化
    SSH框架下载地址
    rdf-3x简要使用
    【opencv基础】imread-第二个参数
    【linux基础】查看硬盘位置信息
    【linux基础】重命名文件和文件夹
    【linux基础】生成目录下所有图片的路径
    【linux】wifi不能使用的问题
    【linux基础】ubuntu如何查看linux的内核版本和系统版本
    【error】select timeout问题
  • 原文地址:https://www.cnblogs.com/qq1223558/p/3409939.html
Copyright © 2020-2023  润新知