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[]; public byte[] GetBytes()
{
return m_HeadBytes;
} public PSDHEAD(byte[] p_Data)
{
m_HeadBytes = p_Data;
} /// <summary>
/// 版本
/// </summary>
public byte Version { get { return m_HeadBytes[]; } set { m_HeadBytes[] = value; } } /// <summary>
/// 颜色数 3为24位 4位23位
/// </summary>
public ushort Channels
{
get
{
return BitConverter.ToUInt16(new byte[] { m_HeadBytes[], m_HeadBytes[] }, );
}
set
{
byte[] _Value = BitConverter.GetBytes(value);
m_HeadBytes[] = _Value[];
m_HeadBytes[] = _Value[];
}
} /// <summary>
///
/// </summary>
public uint Height
{
get
{
return BitConverter.ToUInt32(new byte[] { m_HeadBytes[], m_HeadBytes[], m_HeadBytes[], m_HeadBytes[] }, );
}
set
{
byte[] _Value = BitConverter.GetBytes(value);
m_HeadBytes[] = _Value[];
m_HeadBytes[] = _Value[];
m_HeadBytes[] = _Value[];
m_HeadBytes[] = _Value[];
}
} /// <summary>
///
/// </summary>
public uint Width
{
get
{
return BitConverter.ToUInt32(new byte[] { m_HeadBytes[], m_HeadBytes[], m_HeadBytes[], m_HeadBytes[] }, );
}
set
{
byte[] _Value = BitConverter.GetBytes(value);
m_HeadBytes[] = _Value[];
m_HeadBytes[] = _Value[];
m_HeadBytes[] = _Value[];
m_HeadBytes[] = _Value[];
}
} public ushort BitsPerPixel
{
get
{
return BitConverter.ToUInt16(new byte[] { m_HeadBytes[], m_HeadBytes[] }, );
}
set
{
byte[] _Value = BitConverter.GetBytes(value);
m_HeadBytes[] = _Value[];
m_HeadBytes[] = _Value[];
} } public ushort ColorMode
{
get
{
return BitConverter.ToUInt16(new byte[] { m_HeadBytes[], m_HeadBytes[] }, );
}
set
{
byte[] _Value = BitConverter.GetBytes(value);
m_HeadBytes[] = _Value[];
m_HeadBytes[] = _Value[];
}
} public PSDHEAD()
{
m_HeadBytes[] = 0x38;
m_HeadBytes[] = 0x42;
m_HeadBytes[] = 0x50;
m_HeadBytes[] = 0x53;
m_HeadBytes[] = 0x01; ColorMode = ;
BitsPerPixel = ;
}
}
private class ColorModel
{
private byte[] m_ColorData; public ColorPalette ColorData
{
get
{
Bitmap _Bitmap = new Bitmap(, , PixelFormat.Format8bppIndexed);
ColorPalette _ColorPalette = _Bitmap.Palette;
if (m_ColorData.Length == ) return _ColorPalette;
for (int i = ; i != ; i++)
{
_ColorPalette.Entries[i] = Color.FromArgb(m_ColorData[i], m_ColorData[i + ], m_ColorData[i + ]);
}
return _ColorPalette;
}
set
{
m_ColorData = new byte[];
for (int i = ; i != ; i++)
{
m_ColorData[i] = value.Entries[i].R;
m_ColorData[i + ] = value.Entries[i].G;
m_ColorData[i + ] = value.Entries[i].B;
}
}
} private byte[] m_BIMSize = new byte[]; public uint BIMSize
{
get
{
return BitConverter.ToUInt32(new byte[] { m_BIMSize[], m_BIMSize[], m_BIMSize[], m_BIMSize[] }, );
}
set
{
byte[] _Value = BitConverter.GetBytes(value);
m_BIMSize[] = _Value[];
m_BIMSize[] = _Value[];
m_BIMSize[] = _Value[];
m_BIMSize[] = _Value[];
}
} public ColorModel(FileStream p_FileStream)
{
byte[] _CountByte = new byte[];
p_FileStream.Read(_CountByte, , );
Array.Reverse(_CountByte);
int _Count = BitConverter.ToInt32(_CountByte, );
m_ColorData = new byte[_Count];
if (_Count != ) p_FileStream.Read(m_ColorData, , _Count);
p_FileStream.Read(m_BIMSize, , );
} public ColorModel()
{
m_ColorData = new byte[];
} public byte[] GetBytes()
{
MemoryStream _Memory = new MemoryStream();
byte[] _Value = BitConverter.GetBytes(m_ColorData.Length);
Array.Reverse(_Value);
_Memory.Write(_Value, , _Value.Length);
_Memory.Write(m_ColorData, , m_ColorData.Length);
_Memory.Write(m_BIMSize, , );
return _Memory.ToArray();
}
}
private class BIM
{
private byte[] m_Data = new byte[] { 0x38, 0x42, 0x49, 0x4D };
private byte[] m_TypeID = new byte[];
private byte[] m_Name = new byte[]; public ushort TypeID
{
get
{
return BitConverter.ToUInt16(new byte[] { m_TypeID[], m_TypeID[] }, );
}
set
{
byte[] _Value = BitConverter.GetBytes(value);
m_TypeID[] = _Value[];
m_TypeID[] = _Value[];
}
} public byte[] m_Value; public BIM(FileStream p_FileStream)
{
byte[] _Type = new byte[];
p_FileStream.Read(_Type, , );
if (m_Data[] == _Type[] && m_Data[] == _Type[] && m_Data[] == _Type[] && m_Data[] == _Type[])
{
p_FileStream.Read(m_TypeID, , );
int _SizeOfName = p_FileStream.ReadByte();
int _nSizeOfName = (int)_SizeOfName;
if (_nSizeOfName > )
{
if ((_nSizeOfName % ) != ) { _SizeOfName = p_FileStream.ReadByte(); }
m_Name = new byte[_nSizeOfName];
p_FileStream.Read(m_Name, , _nSizeOfName);
}
_SizeOfName = p_FileStream.ReadByte();
byte[] _CountByte = new byte[];
p_FileStream.Read(_CountByte, , );
Array.Reverse(_CountByte);
int _DataCount = BitConverter.ToInt32(_CountByte, );
if (_DataCount % != ) _DataCount++;
m_Value = new byte[_DataCount];
p_FileStream.Read(m_Value, , _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[], m_Value[] }, );
}
set
{
byte[] _Value = BitConverter.GetBytes(value);
m_Value[] = _Value[];
m_Value[] = _Value[];
}
}
public uint hResUnit
{
get
{
return BitConverter.ToUInt32(new byte[] { m_Value[], m_Value[], m_Value[], m_Value[] }, );
}
set
{
byte[] _Value = BitConverter.GetBytes(value);
m_Value[] = _Value[];
m_Value[] = _Value[];
m_Value[] = _Value[];
m_Value[] = _Value[];
}
}
public ushort widthUnit
{
get
{
return BitConverter.ToUInt16(new byte[] { m_Value[], m_Value[] }, );
}
set
{
byte[] _Value = BitConverter.GetBytes(value);
m_Value[] = _Value[];
m_Value[] = _Value[];
}
}
public ushort vRes
{
get
{
return BitConverter.ToUInt16(new byte[] { m_Value[], m_Value[] }, );
}
set
{
byte[] _Value = BitConverter.GetBytes(value);
m_Value[] = _Value[];
m_Value[] = _Value[];
}
}
public uint vResUnit
{
get
{
return BitConverter.ToUInt32(new byte[] { m_Value[], m_Value[], m_Value[], m_Value[] }, );
}
set
{
byte[] _Value = BitConverter.GetBytes(value);
m_Value[] = _Value[];
m_Value[] = _Value[];
m_Value[] = _Value[];
m_Value[] = _Value[];
}
}
public ushort heightUnit
{
get
{
return BitConverter.ToUInt16(new byte[] { m_Value[], m_Value[] }, );
}
set
{
byte[] _Value = BitConverter.GetBytes(value);
m_Value[] = _Value[];
m_Value[] = _Value[];
}
}
#endregion }
private class LayerMaskInfo
{ public byte[] m_Data = new byte[]; public LayerMaskInfo(FileStream p_Stream)
{
byte[] _Count = new byte[];
p_Stream.Read(_Count, , );
Array.Reverse(_Count); int _ReadCount = BitConverter.ToInt32(_Count, ); m_Data = new byte[_ReadCount];
if (_ReadCount != ) p_Stream.Read(m_Data, , _ReadCount);
} public LayerMaskInfo()
{
} public byte[] GetBytes()
{
MemoryStream _Memory = new MemoryStream();
byte[] _Value = BitConverter.GetBytes(m_Data.Length);
Array.Reverse(_Value);
_Memory.Write(_Value, , _Value.Length);
if (m_Data.Length != ) _Memory.Write(m_Data, , m_Data.Length);
return _Memory.ToArray();
}
}
private class ImageData
{
private ushort p_Type = ; private PSDHEAD m_HeaderInfo; public ImageData()
{
}
public ImageData(FileStream p_FileStream, PSDHEAD p_HeaderInfo)
{
m_HeaderInfo = p_HeaderInfo;
byte[] _ShortBytes = new byte[];
p_FileStream.Read(_ShortBytes, , );
Array.Reverse(_ShortBytes);
p_Type = BitConverter.ToUInt16(_ShortBytes, );
switch (p_Type)
{
case : //RAW DATA
RawData(p_FileStream);
break;
case :
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 : //RGB
LoadRLERGB(p_Stream);
break;
case : //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(, , m_PSDImage.Width, m_PSDImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
byte[] _ImageBytes = new byte[_PSDImageData.Stride * _PSDImageData.Height];
int _WriteIndex = ;
int _EndIndex = _PSDImageData.Stride * _PSDImageData.Height;
p_Stream.Position += _Height * m_HeaderInfo.Channels * ; int _Count = _Width * _Height;
int _WrtieType = ;
int _HeightIndex = ;
int _WidthIndex = ;
int _Index = ; while (true)
{
if (_WriteIndex > _EndIndex - ) break;
byte _Read = (byte)p_Stream.ReadByte();
if (_Read == ) continue; //Erroe
if (_Read > )
{
_Read ^= 0x0FF;
_Read += ;
byte _ByteValue = (byte)p_Stream.ReadByte(); for (byte i = ; i != _Read; i++)
{
_WrtieType = _WriteIndex / _Count;
switch (_WrtieType)
{
case : //Red
_HeightIndex = _WriteIndex / _Width;
_WidthIndex = _WriteIndex % _Width;
_Index = (_PSDImageData.Stride * _HeightIndex) + (_WidthIndex * ) + ;
_ImageBytes[_Index] = _ByteValue;
break;
case : //Green
_HeightIndex = (_WriteIndex - _Count) / _Width;
_WidthIndex = (_WriteIndex - _Count) % _Width;
_Index = (_PSDImageData.Stride * _HeightIndex) + (_WidthIndex * ) + ;
_ImageBytes[_Index] = _ByteValue;
break;
case :
_HeightIndex = (_WriteIndex - _Count - _Count) / _Width;
_WidthIndex = (_WriteIndex - _Count - _Count) % _Width;
_Index = (_PSDImageData.Stride * _HeightIndex) + (_WidthIndex * );
_ImageBytes[_Index] = _ByteValue;
break;
}
//_ImageBytes[_WriteIndex] = _ByteValue;
_WriteIndex++;
}
}
else
{
_Read++;
for (byte i = ; i != _Read; i++)
{
_WrtieType = _WriteIndex / _Count;
switch (_WrtieType)
{
case : //Red
_HeightIndex = _WriteIndex / _Width;
_WidthIndex = _WriteIndex % _Width;
_Index = (_PSDImageData.Stride * _HeightIndex) + (_WidthIndex * ) + ;
_ImageBytes[_Index] = (byte)p_Stream.ReadByte();
break;
case : //Green
_HeightIndex = (_WriteIndex - _Count) / _Width;
_WidthIndex = (_WriteIndex - _Count) % _Width;
_Index = (_PSDImageData.Stride * _HeightIndex) + (_WidthIndex * ) + ;
_ImageBytes[_Index] = (byte)p_Stream.ReadByte();
break;
case :
_HeightIndex = (_WriteIndex - _Count - _Count) / _Width;
_WidthIndex = (_WriteIndex - _Count - _Count) % _Width;
_Index = (_PSDImageData.Stride * _HeightIndex) + (_WidthIndex * );
_ImageBytes[_Index] = (byte)p_Stream.ReadByte();
break;
}
//_ImageBytes[_WriteIndex] = (byte)p_Stream.ReadByte();
_WriteIndex++;
}
}
}
Marshal.Copy(_ImageBytes, , _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 / ) * m_HeaderInfo.Channels;
p_Stream.Position += _Height * m_HeaderInfo.Channels * ;
byte[] _ImageBytes = new byte[_Count]; int _WriteIndex = ;
while (true)
{
if (_WriteIndex > _Count - ) break;
byte _Read = (byte)p_Stream.ReadByte();
if (_Read == ) continue; //Erroe
if (_Read > )
{
_Read ^= 0x0FF;
_Read += ;
byte _ByteValue = (byte)p_Stream.ReadByte(); for (byte i = ; i != _Read; i++)
{
_ImageBytes[_WriteIndex] = _ByteValue;
_WriteIndex++;
}
}
else
{
_Read++;
for (byte i = ; 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(, , m_PSDImage.Width, m_PSDImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
byte[] _WriteBytes = new byte[_PSDImageData.Stride * _PSDImageData.Height]; int _StarIndex = ;
int _Index = ;
int _Size = _Width * _Height;
double C;
double M;
double Y;
double K;
double _MaxColours = Math.Pow(, m_HeaderInfo.BitsPerPixel);
int _Size2 = _Size * ;
int _Size3 = _Size * ;
for (int i = ; i != _PSDImageData.Height; i++)
{
_StarIndex = _PSDImageData.Stride * i;
_Index = i * _Width;
for (int z = ; 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 * );
}
} Marshal.Copy(_WriteBytes, , _PSDImageData.Scan0, _WriteBytes.Length);
m_PSDImage.UnlockBits(_PSDImageData);
}
#endregion #region RAW数据
private void RawData(FileStream p_Stream)
{
switch (m_HeaderInfo.ColorMode)
{
case : //Index
LoadRAWIndex(p_Stream);
return;
case : //RGB
LoadRAWRGB(p_Stream);
return;
case : //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(, , m_PSDImage.Width, m_PSDImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
byte[] _WriteBytes = new byte[_PSDImageData.Stride * _PSDImageData.Height];
int _PerPixel = m_HeaderInfo.BitsPerPixel / ;
int _PixelsCount = _Width * _Height;
int _BytesCount = _PixelsCount * * _PerPixel;
byte[] _ImageBytes = new byte[_BytesCount];
p_Stream.Read(_ImageBytes, , _BytesCount); int _StarIndex = ;
int _Index = ;
int _Size = _Width * _Height;
double C;
double M;
double Y;
double K;
double _MaxColours = Math.Pow(, m_HeaderInfo.BitsPerPixel);
int _Size2 = _Size * ;
int _Size3 = _Size * ; if (_PerPixel == )
{
_Size *= ;
_Size2 *= ;
_Size3 *= ;
}
for (int i = ; i != _PSDImageData.Height; i++)
{
_StarIndex = _PSDImageData.Stride * i; _Index = i * _Width;
if (_PerPixel == ) _Index *= ;
for (int z = ; z != _PSDImageData.Width; z++)
{
switch (_PerPixel)
{
case :
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 * );
break;
case :
C = 1.0 - (double)BitConverter.ToUInt16(_ImageBytes, _Index + z * ) / _MaxColours;
M = 1.0 - (double)BitConverter.ToUInt16(_ImageBytes, _Index + z * + _Size) / _MaxColours;
Y = 1.0 - (double)BitConverter.ToUInt16(_ImageBytes, _Index + z * + _Size2) / _MaxColours;
K = 1.0 - (double)BitConverter.ToUInt16(_ImageBytes, _Index + z * + _Size3) / _MaxColours;
ConvertCMYKToRGB(C, M, Y, K, _WriteBytes, _StarIndex + z * );
break;
} }
}
Marshal.Copy(_WriteBytes, , _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(, , 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, , _PixelsCount); int _ReadIndex = ;
int _WriteIndex = ;
for (int i = ; i != _Height; i++)
{
_WriteIndex = i * _PSDImageData.Stride;
for (int z = ; z != _Width; z++)
{
_ImageBytes[z + _WriteIndex] = _Data[_ReadIndex];
_ReadIndex++;
}
} Marshal.Copy(_ImageBytes, , _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(, , 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 * * (m_HeaderInfo.BitsPerPixel / );
byte[] _Data = new byte[_BytesCount];
p_Stream.Read(_Data, , _BytesCount); int _Red = ;
int _Green = _PixelsCount;
int _Blue = _PixelsCount + _PixelsCount;
int _ReadIndex = ;
int _WriteIndex = ; if (m_HeaderInfo.BitsPerPixel == )
{
_Green *= m_HeaderInfo.BitsPerPixel / ;
_Blue *= m_HeaderInfo.BitsPerPixel / ;
} for (int i = ; i != _Height; i++)
{
_WriteIndex = i * _PSDImageData.Stride;
for (int z = ; z != _Width; z++)
{
_ImageBytes[(z * ) + + _WriteIndex] = _Data[_ReadIndex + _Red];
_ImageBytes[(z * ) + + _WriteIndex] = _Data[_ReadIndex + _Green];
_ImageBytes[(z * ) + _WriteIndex] = _Data[_ReadIndex + _Blue];
_ReadIndex += m_HeaderInfo.BitsPerPixel / ;
}
}
Marshal.Copy(_ImageBytes, , _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 * ( - p_K) + p_K)) * );
int _Green = (int)((1.0 - (p_M * ( - p_K) + p_K)) * );
int _Blue = (int)((1.0 - (p_Y * ( - p_K) + p_K)) * ); if (_Red < ) _Red = ;
else if (_Red > ) _Red = ;
if (_Green < ) _Green = ;
else if (_Green > ) _Green = ;
if (_Blue < ) _Blue = ;
else if (_Blue > ) _Blue = ; p_DataBytes[p_Index] = (byte)_Blue;
p_DataBytes[p_Index + ] = (byte)_Green;
p_DataBytes[p_Index + ] = (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[];
_PSD.Read(_HeadByte, , );
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 == ) 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, , _Bytes.Length);
_Bytes = m_ColorModel.GetBytes();
_SaveFile.Write(_Bytes, , _Bytes.Length);
_SaveFile.Write(_Bim, , _Bim.Length);
_SaveFile.Write(new byte[], , );
_Bytes = m_LayerMaskInfo.GetBytes();
_SaveFile.Write(_Bytes, , _Bytes.Length);
Bitmap _Bitmap = new Bitmap(_Width, _Height, PixelFormat.Format24bppRgb);
Graphics _Graphics = Graphics.FromImage(_Bitmap);
_Graphics.DrawImage(PSDImage, , , _Width, _Height);
_Graphics.Dispose(); BitmapData _SaveData = _Bitmap.LockBits(new Rectangle(, , _Width, _Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
byte[] _ReadByte = new byte[_SaveData.Stride * _Height];
Marshal.Copy(_SaveData.Scan0, _ReadByte, , _ReadByte.Length);
byte[] _WriteByte = new byte[_Bitmap.Width * _Bitmap.Height * ];
int _Size = _Width * _Height;
int _Size2 = _Size * ;
for (int i = ; i != _Height; i++)
{
int _Index = i * _SaveData.Stride;
int _WriteIndex = i * _Width;
for (int z = ; z != _Width; z++)
{
_WriteByte[_WriteIndex + z] = _ReadByte[_Index + (z * ) + ];
_WriteByte[_WriteIndex + _Size + z] = _ReadByte[_Index + (z * ) + ];
_WriteByte[_WriteIndex + _Size2 + z] = _ReadByte[_Index + (z * ) + ];
}
}
_Bitmap.UnlockBits(_SaveData);
_Bitmap.Dispose(); _SaveFile.Write(_WriteByte, , _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
C# 读写 Photoshop PSD文件 操作类的更多相关文章
- (Unity)XML文件读写与IO文件操作类使用介绍
using System.Xml; //xml文件操作命名空间 #region 写入操作 void WriteXMLFile(string _fileName) { Xm ...
- 文件操作类CFile
CFile file; CString str1= L"写入文件成功!"; wchar_t *str2; if (!file.Open(L"Hello.txt" ...
- android 文件操作类简易总结
android 文件操作类(参考链接) http://www.cnblogs.com/menlsh/archive/2013/04/02/2997084.html package com.androi ...
- Qt5:Qt文件操作类 QFile
在QT中,操作文件一般不使用C++提供的文件操作类 , 因为操作文件的时候,要用到C++提供的 string 类,而在QT中使用的是Qt自己实现的一个string类 QString .在Qt中使用C+ ...
- Android FileUtils 文件操作类
系统路径 Context.getPackageName(); // 用于获取APP的所在包目录 Context.getPackageCodePath(); //来获得当前应用程序对应的apk文件的路径 ...
- VS2010/MFC编程入门之四十五(MFC常用类:CFile文件操作类)
上一节中鸡啄米讲了定时器Timer的用法,本节介绍下文件操作类CFile类的使用. CFile类概述 如果你学过C语言,应该知道文件操作使用的是文件指针,通过文件指针实现对它指向的文件的各种操作.这些 ...
- [C#] 常用工具类——文件操作类
/// <para> FilesUpload:工具方法:ASP.NET上传文件的方法</para> /// <para> FileExists:返回文件是否存在&l ...
- asp.net文件操作类
/** 文件操作类 **/ #region 引用命名空间 using System; using System.Collections.Generic; using System.Text; usin ...
- Ini文件操作类
/// <summary> /// Ini文件操作类 /// </summary> public class Ini { // 声明INI文件的写操作函数 WritePriva ...
随机推荐
- 为什么串行传输时总是LSB在前?
https://superuser.com/questions/1104212/why-do-serial-ports-send-data-least-significant-bit-first 其实 ...
- 两个对象值相同 (x.equals(y) == true),但却可有不同的 hash code,这句话对不对?
不对,如果两个对象x和y满足x.equals(y) == true,它们的哈希码(hash code)应当相同.Java对于eqauls方法和hashCode方法是这样规定的: (1)如果两个对象相同 ...
- SQL Server SQLGetData()
{ /* 语法 C++ SQLRETURN SQLGetData( SQLHSTMT StatementHandle, SQLUSMALLINT Col_or_Param_Num, SQLSMALLI ...
- thinkphp 包含文件
在当前模版文件中包含其他的模版文件使用include标签,标签用法: <include file='模版表达式或者模版文件1,模版表达式或者模版文件2,...' /> 博智达直线电机价格 ...
- MFC基础类及其层次结构
从类CCmdTarget派生出绝大多数MFC中的类,其层次结构如下图: 从根类Cobject层层派生出绝大多数MFC中的类,层次结构如下图: MFC中重点类: CObject类是MFC的绝大部分类的基 ...
- C#获取当前运行的源代码的文件名和当前源代码的行数的方法
在C#中记录日志时,为了以后查找错误或者跟踪的方便,最好能记录下出错的源代码的文件名和出错的源代码的行数. 这2个方法如下: /// <summary> /// 取得当前源 ...
- VS2010-MFC(MFC常用类:CTime类和CTimeSpan类)
转自:http://www.jizhuomi.com/software/230.html 上一节讲了MFC常用类CString类的用法,本节继续讲另外两个MFC常用类-日期和时间类CTime类和CTi ...
- k8s 弹性伸缩
k8s弹性伸缩,需要附加插件heapster 1.安装heapster监控 1:上传并导入镜像,打标签 ls *.tar.gz for n in `ls *.tar.gz`;do docker loa ...
- 【转】5G标准——独立组网(SA)和非独立组网(NSA)
独立组网模式(SA):指的是新建5G网络,包括新基站.回程链路以及核心网.SA引入了全新网元与接口的同时,还将大规模采用网络虚拟化.软件定义网络等新技术,并与5GNR结合,同时其协议开发.网络规划部署 ...
- 5.1_Spring Boot2.x安装Docker
1.简介 Docker是一个开源的应用容器引擎:是一个轻量级容器技术: Docker 是一个开源的应用容器引擎,基于Go 语言并遵从Apache2.0协议开源.Docker 可以让开发者打包他们的应用 ...