读PSD图片

longzhongyang 2007-01-21 02:39:11
在CodeProject里发现一个读取的方法. 作者只要求在使用的时候保留Assembly的名称"SimplePsd.dll".
下面是全部原代码.
CPSD.cs:
using System;
using System.IO;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace SimplePsd
{
/// <summary>
/// Main class is for opening Adobe Photoshop files
/// </summary>
public class CPSD
{

private HeaderInfo m_HeaderInfo;
private ColorModeData m_ColorModeData;
private ImageResource m_ImageResource;
private ResolutionInfo m_ResolutionInfo;
private DisplayInfo m_DisplayInfo;
private ThumbNail m_ThumbNail;

private bool m_bResolutionInfoFilled;
private bool m_bThumbnailFilled;
private bool m_bCopyright;

private short m_nColourCount;
private short m_nTransparentIndex;
private int m_nGlobalAngle;
private int m_nCompression;
private IntPtr m_hBitmap;

public CPSD()
{
m_bResolutionInfoFilled = false;
m_bThumbnailFilled = false;
m_bCopyright = false;
m_nColourCount = -1;
m_nTransparentIndex = -1;
m_nGlobalAngle = 30;
m_nCompression = -1;
m_hBitmap = IntPtr.Zero;
}
// construction, destruction

public int Load(string strPathName)
{
int nErrorCode = 0; // No errors

FileStream stream = new FileStream(strPathName, FileMode.Open, FileAccess.Read, FileShare.Read);

if(!stream.Handle.Equals(0))
{
bool bSuccessHeader = false;
bool bSuccessColourModeData = false;
bool bSuccessImageResource = false;
bool bSuccessLayerMaskInfo = false;

try
{
bSuccessHeader = ReadHeader(stream);
if(bSuccessHeader == false)
nErrorCode = -2; // Error in header
}
catch(Exception)
{
bSuccessHeader = false;
nErrorCode = -2;
}

if(bSuccessHeader)
{
try
{
bSuccessColourModeData = ReadColourModeData(stream);
if (bSuccessColourModeData == false)
nErrorCode = -3; // Error in ColourMode Data
}
catch(Exception)
{
bSuccessColourModeData = false;
nErrorCode = -3;
}
}

if(bSuccessColourModeData)
{
try
{
bSuccessImageResource = ReadImageResource(stream);
if (bSuccessImageResource == false)
nErrorCode = -4; // Error in Image Resource
}
catch(Exception)
{
bSuccessImageResource = false;
nErrorCode = -4;
}
}

if(bSuccessImageResource)
{
try
{
bSuccessLayerMaskInfo = ReadLayerAndMaskInfoSection(stream);
if ( false == bSuccessLayerMaskInfo )
nErrorCode = -5; // Error in Mask Info
}
catch (Exception)
{
bSuccessLayerMaskInfo = false;
nErrorCode = -5;
}
}

if(bSuccessImageResource)
{
try
{
nErrorCode = ReadImageData(stream);
}
catch(Exception)
{
nErrorCode = -6; // Error in Image Data
}
}
}
else
nErrorCode = -1; // Cannot open file

return nErrorCode;
}
...全文
296 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
SeeSunSet 2007-01-21
  • 打赏
  • 举报
回复
读它做什么? 能修改其某个图层中的字体吗?
longzhongyang 2007-01-21
  • 打赏
  • 举报
回复
case 1036:
{
m_bThumbnailFilled = true;

IntValue = binReader.ReadBytes(4);
if(SwapBytes(IntValue,4)) m_ThumbNail.nFormat = BitConverter.ToInt32(IntValue,0);
nBytesRead += 4;

IntValue = binReader.ReadBytes(4);
if(SwapBytes(IntValue,4)) m_ThumbNail.nWidth = BitConverter.ToInt32(IntValue,0);
nBytesRead += 4;

IntValue = binReader.ReadBytes(4);
if(SwapBytes(IntValue,4)) m_ThumbNail.nHeight = BitConverter.ToInt32(IntValue,0);
nBytesRead += 4;

IntValue = binReader.ReadBytes(4);
if(SwapBytes(IntValue,4)) m_ThumbNail.nWidthBytes = BitConverter.ToInt32(IntValue,0);
nBytesRead += 4;

IntValue = binReader.ReadBytes(4);
if(SwapBytes(IntValue,4)) m_ThumbNail.nSize = BitConverter.ToInt32(IntValue,0);
nBytesRead += 4;

IntValue = binReader.ReadBytes(4);
if(SwapBytes(IntValue,4)) m_ThumbNail.nCompressedSize = BitConverter.ToInt32(IntValue,0);
nBytesRead += 4;

ShortValue = binReader.ReadBytes(2);
nBytesRead += 2;
if(SwapBytes(ShortValue,2)) m_ThumbNail.nBitPerPixel = BitConverter.ToInt16(ShortValue,0);

ShortValue = binReader.ReadBytes(2);
nBytesRead += 2;
if(SwapBytes(ShortValue,2)) m_ThumbNail.nPlanes = BitConverter.ToInt16(ShortValue,0);

int nTotalData = m_ImageResource.nSize - 28; // header

byte [] buffer = new byte[nTotalData];
byte c;
if(m_ImageResource.nID == 1033)
{
// In BGR format
for(int n=0; n<nTotalData; n=n+3)
{
c = binReader.ReadByte();
nBytesRead += 1;
buffer[n+2] = c;
c = binReader.ReadByte();
nBytesRead += 1;
buffer[n+1] = c;
c = binReader.ReadByte();
nBytesRead += 1;
buffer[n] = c;
}
}
else if(m_ImageResource.nID == 1036)
{
// In RGB format
for (int n=0; n<nTotalData; ++n)
{
c = binReader.ReadByte();
nBytesRead += 1;
buffer[n] = c;
}
}
}
break;
case 1037:
{
IntValue = binReader.ReadBytes(4);
if(SwapBytes(IntValue,4)) m_nGlobalAngle = BitConverter.ToInt32(IntValue,0);
nBytesRead += 4;
}
break;
case 1046:
{
ShortValue = binReader.ReadBytes(2);
nBytesRead += 2;
if(SwapBytes(ShortValue,2)) m_nColourCount = BitConverter.ToInt16(ShortValue,0);
}
break;
case 1047:
{
ShortValue = binReader.ReadBytes(2);
nBytesRead += 2;
if(SwapBytes(ShortValue,2)) m_nTransparentIndex = BitConverter.ToInt16(ShortValue,0);
}
break;
default:
{
byte c;
for(int n=0; n<m_ImageResource.nSize; ++n )
{
c = binReader.ReadByte();
nBytesRead += 1;
}
}
break;
}
}
}
}
bSuccess = true;
}
catch(EndOfStreamException e)
{
bSuccess = false;
MessageBox.Show("Exception occurs while reading image resources: {0}", e.GetType().Name);
}


return bSuccess;
}

protected bool ReadLayerAndMaskInfoSection(FileStream stream) // currently ignore it
{
bool bSuccess = false;

BinaryReader binReader = new BinaryReader(stream);
try
{
byte [] DataLength = new byte[4];
int nTotalBytes = 0;

DataLength = binReader.ReadBytes(4);
if(SwapBytes(DataLength,4)) nTotalBytes = BitConverter.ToInt32(DataLength,0);

if(stream.Position+nTotalBytes < stream.Length) stream.Position += nTotalBytes;

// byte c = 0x00;
// for(int i=0;i<nTotalBytes;i++)
// {
// if(binReader.PeekChar() == -1) break;
// c = binReader.ReadByte();
// }

bSuccess = true;
}
catch(EndOfStreamException e)
{
bSuccess = false;
MessageBox.Show("Exception occurs while reading layer and mask section: {0}", e.GetType().Name);
}

return bSuccess;
}
longzhongyang 2007-01-21
  • 打赏
  • 举报
回复

protected bool ReadImageResource(FileStream stream)
{
bool bSuccess = false;

BinaryReader binReader = new BinaryReader(stream);
try
{
int nLength = 0;

byte [] Length = binReader.ReadBytes(4);

m_ImageResource = new ImageResource();
m_ResolutionInfo = new ResolutionInfo();
m_DisplayInfo = new DisplayInfo();
m_ThumbNail = new ThumbNail();

if(SwapBytes(Length,4)) nLength = BitConverter.ToInt32(Length,0);
m_ImageResource.nLength = nLength;

int nBytesRead = 0;
int nTotalBytes = m_ImageResource.nLength;
long nStreamLen = stream.Length;

while(stream.Position < nStreamLen && nBytesRead < nTotalBytes)
{
m_ImageResource.Reset();
m_ImageResource.OSType = binReader.ReadBytes(4);
nBytesRead += 4;

ASCIIEncoding encoding = new ASCIIEncoding();

if(encoding.GetString(m_ImageResource.OSType).Equals("8BIM"))
{
byte [] ID = binReader.ReadBytes(2);
nBytesRead += 2;

if(SwapBytes(ID,2)) m_ImageResource.nID = BitConverter.ToInt16(ID,0);

byte SizeOfName = binReader.ReadByte();
nBytesRead += 1;

int nSizeOfName = (int)SizeOfName;
if(nSizeOfName>0)
{
if((nSizeOfName % 2)!=0) // must read 1 more byte to make size even
{
SizeOfName = binReader.ReadByte();
nBytesRead += 1;
}

m_ImageResource.Name = new byte[nSizeOfName];
m_ImageResource.Name = binReader.ReadBytes(nSizeOfName);
nBytesRead += nSizeOfName;
}

SizeOfName = binReader.ReadByte();
nBytesRead += 1;

byte [] Size = binReader.ReadBytes(4);
if(SwapBytes(Size,4)) m_ImageResource.nSize = BitConverter.ToInt32(Size,0);
nBytesRead += 4;

if((m_ImageResource.nSize % 2) != 0) // resource data must be even
m_ImageResource.nSize++;

if(m_ImageResource.nSize>0)
{
byte [] IntValue = new byte[4];
byte [] ShortValue = new byte[2];

switch(m_ImageResource.nID)
{
case 1005:
{
m_bResolutionInfoFilled = true;

ShortValue = binReader.ReadBytes(2);
if(SwapBytes(ShortValue,2)) m_ResolutionInfo.hRes = BitConverter.ToInt16(ShortValue,0);
nBytesRead += 2;
IntValue = binReader.ReadBytes(4);
if(SwapBytes(IntValue,4)) m_ResolutionInfo.hResUnit = BitConverter.ToInt32(IntValue,0);
nBytesRead += 4;
ShortValue = binReader.ReadBytes(2);
if(SwapBytes(ShortValue,2)) m_ResolutionInfo.widthUnit = BitConverter.ToInt16(ShortValue,0);
nBytesRead += 2;
ShortValue = binReader.ReadBytes(2);
if(SwapBytes(ShortValue,2)) m_ResolutionInfo.vRes = BitConverter.ToInt16(ShortValue,0);
nBytesRead += 2;
IntValue = binReader.ReadBytes(4);
if(SwapBytes(IntValue,4)) m_ResolutionInfo.vResUnit = BitConverter.ToInt32(IntValue,0);
nBytesRead += 4;
ShortValue = binReader.ReadBytes(2);
if(SwapBytes(ShortValue,2)) m_ResolutionInfo.heightUnit = BitConverter.ToInt16(ShortValue,0);
nBytesRead += 2;
}
break;
case 1007:
{
ShortValue = binReader.ReadBytes(2);
nBytesRead += 2;
if(SwapBytes(ShortValue,2)) m_DisplayInfo.ColourSpace = BitConverter.ToInt16(ShortValue,0);

for(int n=0; n<4; ++n)
{
ShortValue = binReader.ReadBytes(2);
nBytesRead += 2;
if(SwapBytes(ShortValue,2)) m_DisplayInfo.Colour[n] = BitConverter.ToInt16(ShortValue,0);
}

ShortValue = binReader.ReadBytes(2);
nBytesRead += 2;
if(SwapBytes(ShortValue,2)) m_DisplayInfo.Opacity = BitConverter.ToInt16(ShortValue,0);
if(m_DisplayInfo.Opacity<0 || m_DisplayInfo.Opacity>100) m_DisplayInfo.Opacity = 100;

byte c = binReader.ReadByte();
nBytesRead += 1;
if(c == 0x00) m_DisplayInfo.kind = false;
else m_DisplayInfo.kind = true;

nBytesRead += 1;
m_DisplayInfo.padding = binReader.ReadByte();
}
break;
case 1034:
{
ShortValue = binReader.ReadBytes(2);
nBytesRead += 2;
int nCopyright = 0;
if(SwapBytes(ShortValue,2)) nCopyright = BitConverter.ToInt16(ShortValue,0);
if(nCopyright>0) m_bCopyright = true;
else m_bCopyright = false;
}
break;
case 1033:
longzhongyang 2007-01-21
  • 打赏
  • 举报
回复

public bool IsThumbnailIncluded()
{
return m_bThumbnailFilled;
}

public int GetBitsPerPixel()
{
return m_HeaderInfo.nBitsPerPixel;
}

public int GlobalAngle()
{
return m_nGlobalAngle;
}

public bool IsCopyrighted()
{
return m_bCopyright;
}

public IntPtr GetHBitmap()
{
return m_hBitmap;
}

public int GetWidth()
{
return m_HeaderInfo.nWidth;
}

public int GetHeight()
{
return m_HeaderInfo.nHeight;
}

public int GetXResolution()
{
return m_ResolutionInfo.hRes;
}

public int GetYResolution()
{
return m_ResolutionInfo.vRes;
}

public int GetCompression()
{
return m_nCompression;
}

protected bool ReadHeader(FileStream stream)
{
bool bSuccess = false;

BinaryReader binReader = new BinaryReader(stream);
try
{
// Set Position to the beginning of the stream.
binReader.BaseStream.Position = 0;
byte [] Signature = binReader.ReadBytes(4); // always equal 8BPS, do not read file if not
byte [] Version = binReader.ReadBytes(2); // always equal 1, do not read file if not
byte [] Reserved = binReader.ReadBytes(6); // must be zero
byte [] Channels = binReader.ReadBytes(2); // numer of channels including any alpha channels, supported range 1 to 24
byte [] Rows = binReader.ReadBytes(4); // height in PIXELS, supported range 1 to 30000
byte [] Columns = binReader.ReadBytes(4); // width in PIXELS, supported range 1 to 30000
byte [] Depth = binReader.ReadBytes(2); // number of bpp
byte [] Mode = binReader.ReadBytes(2); // colour mode of the file
// Btmap=0, Grayscale=1, Indexed=2, RGB=3,
// CMYK=4, Multichannel=7, Duotone=8, Lab=9
ASCIIEncoding encoding = new ASCIIEncoding();

if( encoding.GetString(Signature).Equals("8BPS") && Version[1] == 0x01)
{
m_HeaderInfo = new HeaderInfo();

if(SwapBytes(Channels,2)) m_HeaderInfo.nChannels = BitConverter.ToInt16(Channels,0);
if(SwapBytes(Rows,4)) m_HeaderInfo.nHeight = BitConverter.ToInt32(Rows,0);
if(SwapBytes(Columns,4)) m_HeaderInfo.nWidth = BitConverter.ToInt32(Columns,0);
if(SwapBytes(Depth,2)) m_HeaderInfo.nBitsPerPixel = BitConverter.ToInt16(Depth,0);
if(SwapBytes(Mode,2)) m_HeaderInfo.nColourMode = BitConverter.ToInt16(Mode,0);

if(m_HeaderInfo.nChannels != -1 && m_HeaderInfo.nHeight != -1 && m_HeaderInfo.nWidth != -1 && m_HeaderInfo.nBitsPerPixel != -1 && m_HeaderInfo.nColourMode != -1) bSuccess = true;
}
}
catch(EndOfStreamException e)
{
System.Windows.Forms.MessageBox.Show("Exception occurs while reading file header: {0}", e.GetType().Name);
}

return bSuccess;
}

protected bool ReadColourModeData(FileStream stream)
{
bool bSuccess = false;

// Only indexed colour and duotone have colour mode data,
// for all other modes this section is 4 bytes length, the length field is set to zero

// For indexed color images, the length will be equal to 768, and the color
// will contain the color table for the image, in non杋nterleaved order.

// For duotone images, the color data will contain the duotone specification,
// the format of which is not documented. Other applications that read
// Photoshop files can treat a duotone image as a grayscale image, and just
// preserve the contents of the duotone information when reading and writing
// the file.

BinaryReader binReader = new BinaryReader(stream);
try
{
// Set Position to the beginning of the stream + size of HeaderInfo.
binReader.BaseStream.Position = 26;
byte [] ColorMode = binReader.ReadBytes(4);

int nLength = 0;

m_ColorModeData = new ColorModeData();
if(SwapBytes(ColorMode,4)) nLength = BitConverter.ToInt32(ColorMode,0);
m_ColorModeData.nLength = nLength;

if(nLength>0)
{
m_ColorModeData.ColourData = new byte[nLength];
m_ColorModeData.ColourData = binReader.ReadBytes(nLength);
}

bSuccess = true;
}
catch(EndOfStreamException e)
{
MessageBox.Show("Exception occurs while reading color mode data: {0}", e.GetType().Name);
}

return bSuccess;
}
Ashampoo 是德国的一家公司,公司成立于1999年,国人戏称其译名为(阿香婆),这家公司的产品线很长,出的软件五花八门,至少也有20多款软件。Ashampoo 是软件开发、销售和 Web 门户站点领域的全球领先互联网企业之一。Ashampoo 制造的众多革新软件产品自始自终代表着最先进的技术标准,其以先进的功能、成熟的技术和良好的可用性而深为人知。软件界面一般都比较华丽,但并非华而不实,有很多软件愈加受到国人的喜爱。Ashampoo Photo Recovery 中文版可以恢复您丢失的图片 – 支持任何设备! 阿香婆照片数据恢复工具 Ashampoo Photo Recovery 中文版阿香婆照片数据恢复工具 Ashampoo Photo Recovery 中文版 误删除了照片?记忆卡不出来了? 珍贵的照片是无价的,无可替代的。婚礼、假期、度假或是儿时的照片,都时时提醒着我们人生中最值得回忆的场景。如果由于失误或是设备故障而丢失了,那损失都是无法衡量的。这时就您会需要 Ashampoo Photo Recovery,它就是您的照片恢复专家! 恢复已删除或已损坏的图片 Ashampoo Photo Recovery 能恢复各种丢失的图片 – 无需专业知识!此程序让您可以从各种类型的磁盘和文件中恢复图片,一切都只需几下点击。 这些情况都可能造成数码照片丢失: 图片被误删除了 数码相机或手机的记忆卡不能工作了 U 盘被格式化了或不能工作了 手机记忆卡被格式化了 文件系统损坏了 预置多种场景条件,使用更方便 新的搜索功能让您不光能选择要搜索的格式,还能指定具体的大小和尺寸。 Ashampoo Photo Recovery 亮点功能: 查找 PDF、ExE 及 Word 文件中的图片 从已损坏的 RAW 文件中恢复照片 支持 20 多种 RAW 格式 搜索特定罕见格式(如:APCDOC、PSD、TGA、PCX、SGI) 从多页的图片(动画等)中恢复单个帧 预置多种场景条件,使用更方便 专为 Windows 10 优化,支持高分辨率显示 按大小、分辨率进行搜索 支持最新的格式(JPEG 2000、WebP、JPEG XR) 恢复已删除或已损坏的图片 扫描所有可用磁盘 从已格式化的磁盘中恢复照片

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧