读PSD图片

longzhongyang 2007-01-21 02:38:49
在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;
}
...全文
521 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
longzhongyang 2007-03-31
  • 打赏
  • 举报
回复
Useful Site:
http://www.15seconds.com/issue/040511.htm
http://msdn2.microsoft.com/en-us/library/ms916799.aspx
longzhongyang 2007-03-03
  • 打赏
  • 举报
回复
How to get IPTC from PSD files:
case 1028:
{
int flag;
for (int i = 1; i < m_ImageResource.nSize; )
{
binReader.ReadBytes(2);
byte c = binReader.ReadByte();
binReader.ReadByte();

int iptcLength = binReader.ReadByte();
nBytesRead += 5;

byte[] iptc = binReader.ReadBytes(iptcLength);
nBytesRead += iptcLength;

if (c == 120)
{
description = encoding.GetString(iptc);
}
else if (c == 80)
{
creator = encoding.GetString(iptc);
}
else if (c == 25)
{
keywords = encoding.GetString(iptc);
}
else
{
// Nothing need to do.
}
i += 5 + iptcLength;
}
if ((binReader.BaseStream.Position % 2) != 0)
{
binReader.ReadByte();
nBytesRead += 1;
}
}
break;
longzhongyang 2007-02-06
  • 打赏
  • 举报
回复
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
//The texture used is in the "Managed" pool, meaning that it will automatically
//restore itself on a Device.Reset(). This kind of texture requires less manual management than
//a default pool texture.66666666666666
//Texture tileTexture = TextureLoader.FromFile(null, openFileDialog1.FileName, 320, 64, 1,
// Usage.None, Format.A8R8G8B8, Pool.Managed, Filter.None, Filter.None, Color.FromArgb(255, 0, 0, 0).ToArgb());


try
{
ImageInformation information = TextureLoader.ImageInformationFromFile(openFileDialog1.FileName);
Format fileFormat = information.Format;
ImageFileFormat imageFileFormat = information.ImageFileFormat;
int mipLevels = information.MipLevels;
ResourceType resourceType = information.ResourceType;

Device device = null; // Create rendering device
PresentParameters presentParams = new PresentParameters();

//device = new Device(0, DeviceType.Software, this,
// CreateFlags.SoftwareVertexProcessing |
// CreateFlags.FpuPreserve, presentParams);

//device = new Device(0, DeviceType.DeviceType,
// State.WindowFocus, newDeviceSettings.BehaviorFlags,
// newDeviceSettings.presentParams);

presentParams.MultiSampleQuality = 0;
presentParams.PresentationInterval = PresentInterval.Immediate;
presentParams.FullScreenRefreshRateInHz = 0;
presentParams.PresentFlag = PresentFlag.DiscardDepthStencil;
presentParams.AutoDepthStencilFormat = DepthFormat.D24X8;
presentParams.EnableAutoDepthStencil = true;
presentParams.Windowed = true;
//presentParams.DeviceWindowHandle = 1639856;
presentParams.DeviceWindow = this;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.MultiSample = MultiSampleType.None;
presentParams.BackBufferCount = 2;
presentParams.BackBufferFormat = Format.X8R8G8B8;
presentParams.BackBufferHeight = 480;
presentParams.BackBufferWidth = 640;
presentParams.ForceNoMultiThreadedFlag = true;


device = new Microsoft.DirectX.Direct3D.Device(0,
Microsoft.DirectX.Direct3D.DeviceType.Hardware, this,
CreateFlags.HardwareVertexProcessing | CreateFlags.PureDevice, presentParams);
Surface surface = null;

if (resourceType == ResourceType.CubeTexture)
{
CubeTexture cube = TextureLoader.FromCubeFile(device, openFileDialog1.FileName);

if (resourceType == ResourceType.CubeTexture)
{
surface = cube.GetCubeMapSurface(CubeMapFace.PositiveX, 0);
}
cube.Dispose();
}
else
{
Texture texture = TextureLoader.FromFile(device, openFileDialog1.FileName);
surface = texture.GetSurfaceLevel(0);

}

SurfaceLoader.Save(@"D:\target.jpg", ImageFileFormat.Jpg, surface);

}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
gameboy766 2007-02-06
  • 打赏
  • 举报
回复
mark
ACCP4_0 2007-01-31
  • 打赏
  • 举报
回复
dd
Red_angelX 2007-01-31
  • 打赏
  • 举报
回复
mark
oldmoon 2007-01-31
  • 打赏
  • 举报
回复
收藏一下
ACCP4_0 2007-01-30
  • 打赏
  • 举报
回复
ff
longzhongyang 2007-01-30
  • 打赏
  • 举报
回复
; The GIMP -- an image manipulation program
; Copyright (C) 1995 Spencer Kimball and Peter Mattis
;
; Continuous Save --- save the file which named "base-name_(number).(type)"
; Copyright (C) 2001 Iccii <iccii@hotmail.com>
;
; Modified by Tamubun <http://bunysmc.exblog.jp/>
;
; This script was born of miyoken's idea.
;
; Modified by helge kippenberg
;
; --------------------------------------------------------------------
; - Changelog -
; version 0.1 2001/05/20 iccii <iccii@hotmail.com>
; - Initial relase
; version 0.2 2001/05/24 iccii <iccii@hotmail.com>
; - Make better
; version 0.3 2001/05/24 iccii <iccii@hotmail.com>
; - Chose the filename with directory
; - Saved image type equal to original image type
; version 0.3a 2001/09/26 iccii <iccii@hotmail.com>
; - Bug fixed in checking the file type
;
; ====
;
; version 0.4-tamubun
; 2005/03/11 tamubun <http://bunysmc.exblog.jp/>
; - Added "Digits" option, and changed the file names for each layer.
; - Added "Reverse Order" option, to control output ordering.
; (To use the original ordering, i.e. from top layer to bottom
; layer, "Reverse Ordering" must be checked.)
; - Unified "JPEG Compression" option and "PNG Compression" option
; to single "Quality" option.
; - Deleted "Interactive" option.
; version 0.5-tamubun
; 2005/03/29 tamubun <http://bunysmc.exblog.jp/>
; - Added "Start Number" option.
; version 0.6-tamubun
; 2005/04/06 tamubun <http://bunysmc.exblog.jp/>
; - Added "#" convention.
;
; ====
;
; version 0.6.1-kippenberg
; 2005/05/03
; - Added tif output
;
; version 0.6.2-kippenberg
; 2005/05/05
; - Added compression options for tif output
;
; --------------------------------------------------------------------
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
;


(define (script-fu-continuous-save
img ; IMAGE
drawable ; DRAWABLE (no need)
save-type ; saving image type
file-name ; base file name with directory
digits ; trailing 0's
start ; start number
reverse ; If true, order from top to bottom
quality ; compression quality for JPG, PNG
tif-compression ; compression type for tif
)

(define (floor x) (- x (fmod x 1)))

(define (div x y) (floor (/ x y)))

(define (to-save-bmp img layer file-name)
(file-bmp-save 1 img (car (gimp-image-flatten img)) file-name ""))

(define (to-save-jpg img layer file-name jpg-comp)
(file-jpeg-save 1 img (car (gimp-image-flatten img)) file-name ""
(/ jpg-comp 100) 0.0 1 0 "" 0 0 0 1))

(define (to-save-png img layer file-name png-comp)
(file-png-save 1 img layer file-name "" 0 png-comp 1 1 1 1 1))

(define (to-save-tif img layer file-name tif-comp)
(file-tiff-save2 1 img layer file-name "" tif-comp 0))


(define (gen-name count ext)
(let* ((zeros "0000000000")
(str (number->string (+ start count)))
(num (string-append zeros str))
(pos (- (string-length num) (max digits (string-length str)))))
(string-append file-name (substring num pos) ext)))

(let* (
(layers (gimp-image-get-layers img))
(count 0)
(number (car layers))
(image-type (car (gimp-image-base-type img)))
(len (string-length file-name))
(png-comp (- 9 (div quality 12)))

) ; end variable definition

(if (and (> len 0)
(not (= 47 (aref file-name (- len 1)))) ;always true (maybe)
(equal? (car (last (strbreakup file-name "/"))) "#"))
(set! file-name (substring file-name 0 (- len 1))))

(while (< count number)
(let* (
(tmp-image-type
(cond
((and (eqv? save-type 0) (eqv? image-type 2))
0) ;; convert to RGB because BMP can't treat INDEXED image
((and (eqv? save-type 1) (or (eqv? image-type 1) (eqv? image-type 2)))
0) ;; convert to RGB because JPEG can't treat INDEXED and GRAY image
(image-type))) ;; otherwise, equal to origianl image type
(layer (aref (cadr layers) (if (= reverse 1) count (- number 1 count))))
(tmp-img (car (gimp-image-new (car (gimp-drawable-width layer))
(car (gimp-drawable-height layer))
tmp-image-type)))
(tmp-layer (car (gimp-layer-new tmp-img
(car (gimp-drawable-width layer))
(car (gimp-drawable-height layer))
(+ 1 (* 2 tmp-image-type)) "Temp Layer" 100 NORMAL)))
)

;; create an image with single layer, and remove the layer mask (if exists)
(gimp-image-add-layer tmp-img tmp-layer 0)
(gimp-edit-copy layer)
(gimp-floating-sel-anchor (car (gimp-edit-paste tmp-layer 0)))
(if (< 0 (car (gimp-layer-mask layer)))
(let* ((tmp-mask (car (gimp-layer-create-mask tmp-layer 0))))
(gimp-edit-copy (car (gimp-layer-mask layer)))
(gimp-floating-sel-anchor (car (gimp-edit-paste tmp-layer 0)))
(gimp-image-remove-layer-mask tmp-img tmp-layer APPLY)
(gimp-displays-flush)))
;(set! tmp-display (car (gimp-display-new tmp-img)))
;(gimp-displays-flush)


;; save a resulting image by specified image type
(cond
((eqv? save-type 0)
(to-save-bmp tmp-img tmp-layer (gen-name count ".bmp")))
((eqv? save-type 1)
(to-save-jpg tmp-img tmp-layer (gen-name count ".jpg") quality))
((eqv? save-type 2)
(to-save-png tmp-img tmp-layer (gen-name count ".png") png-comp))
((eqv? save-type 3)
(to-save-tif tmp-img tmp-layer (gen-name count ".tif") tif-compression))
)
(gimp-image-delete tmp-img)
;(gimp-display-delete tmp-display)
)
(set! count (+ count 1))
) ;; repeat until all layer is saved
)
)

(script-fu-register
"script-fu-continuous-save"
"<Image>/Script-Fu/Utils/Continuous Save..."
"Save an Image by single layer with continuous number"
"@hk, originals: Tamubun <http://bunysmc.exblog.jp/>, Original: Iccii <iccii@hotmail.com>"
"Iccii"
"May, 2005"
"RGB* INDEXED* GRAY*"
SF-IMAGE "Image" 0
SF-DRAWABLE "Drawable" 0
SF-OPTION "Saved File Type" '("BMP" "JPG" "PNG" "TIF")
SF-FILENAME "Base File Name" "MyPicture_"
SF-ADJUSTMENT "Digits" '(8 1 10 1 5 0 1)
SF-ADJUSTMENT "Start Number" '(1 1 9999999 10 5 0 1)
SF-TOGGLE "Reverse Order" FALSE
SF-ADJUSTMENT "Quality" '(75 0 100 1 5 0 0)
SF-OPTION "TIFF Compression Type" '("NONE" "LZW" "Packbits" "Deflate" "JPG")
)
longzhongyang 2007-01-26
  • 打赏
  • 举报
回复
http://partners.adobe.com/public/developer/tiff/index.html#spec
http://tiki-lounge.com/~raf/tiff/fields.html
http://www.fileformat.info/format/psd/#ADOBEPHO-DMYID.2


private void GetLayer(FileStream stream, ref int layer)
{
BinaryReader binReader = new BinaryReader(stream);
byte[] binEntries = new byte[2];
binEntries = binReader.ReadBytes(2);
int entries = BitConverter.ToInt16(binEntries, 0);

long currentPosition = binReader.BaseStream.Position;

ASCIIEncoding encoding = new ASCIIEncoding();
for (int i = 0; i < entries; i++)
{
binReader.BaseStream.Position = currentPosition + i * 12;
byte[] binTag = binReader.ReadBytes(2);

int tag = 0;
//if (SwapBytes(binTag, 2))
//{
tag = BitConverter.ToInt16(binTag, 0);
//}
byte[] binType = binReader.ReadBytes(2);
string type = encoding.GetString(binType);
byte[] binCount = binReader.ReadBytes(4);
int count = BitConverter.ToInt32(binCount, 0);
byte[] binOffset = binReader.ReadBytes(4);
//if (Math.Abs(tag) == 31159)
//{
int offset = BitConverter.ToInt32(binOffset, 0);

binReader.BaseStream.Position = offset;

//byte[] binDes = binReader.ReadBytes(33);
//string des = encoding.GetString(binDes);

byte[] binSignature = binReader.ReadBytes(4);
string signature = encoding.GetString(binSignature);

if (signature == "8BIM")
{

byte[] binLayerLength = binReader.ReadBytes(4);
int layerLength = BitConverter.ToInt32(binLayerLength, 0);

//binReader.ReadBytes(4);

byte[] binLayer = binReader.ReadBytes(2);
int layerCount = BitConverter.ToInt16(binLayer, 0);


binLayer = binReader.ReadBytes(2);
layerCount = BitConverter.ToInt16(binLayer, 0);

binLayer = binReader.ReadBytes(2);
layerCount = BitConverter.ToInt16(binLayer, 0);

binReader.BaseStream.Position -= 10;

binLayer = binReader.ReadBytes(33);
signature = encoding.GetString(binLayer);
}
//}
}

binReader.BaseStream.Position = currentPosition + entries * 12;

byte[] binNextIfd = new byte[4];
binNextIfd = binReader.ReadBytes(4);
int nextIfd = BitConverter.ToInt32(binNextIfd, 0);

if (nextIfd > 0)
{
layer++;
binReader.BaseStream.Position = nextIfd;
GetLayer(stream, ref layer);
}
}
longzhongyang 2007-01-25
  • 打赏
  • 举报
回复

byte[] layerValue = new byte[2];

layerValue = binReader.ReadBytes(2);
if (SwapBytes(layerValue, 2))
layer = BitConverter.ToInt16(layerValue, 0);

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


/// <summary>
/// Extracts layer metadata from tiff file.
/// </summary>
/// <param name="fileName">The file name to be extracted.</param>
public void ExtractTiffData(string fileName)
{
int layer = 1;
FileStream fileStream = new FileStream(fileName, FileMode.Open);
BinaryReader binReader = new BinaryReader(fileStream);

byte[] binOrder = new byte[2];
binOrder = binReader.ReadBytes(2);
string order = BitConverter.ToString(binOrder, 0);

byte[] binTag = new byte[2];
binTag = binReader.ReadBytes(2);
short tag = BitConverter.ToInt16(binTag, 0);

byte[] firstIfd = new byte[4];
firstIfd = binReader.ReadBytes(4);
int firstOffset = BitConverter.ToInt32(firstIfd, 0);

binReader.BaseStream.Position = firstOffset;
GetLayer(fileStream, ref layer);
}

private void GetLayer(FileStream stream, ref int layer)
{
BinaryReader binReader = new BinaryReader(stream);
byte[] binEntries = new byte[2];
binEntries = binReader.ReadBytes(2);
int entries = BitConverter.ToInt16(binEntries, 0);

binReader.BaseStream.Position += entries * 12;

byte[] binNextIfd = new byte[4];
binNextIfd = binReader.ReadBytes(4);
int nextIfd = BitConverter.ToInt32(binNextIfd, 0);

if (nextIfd > 0)
{
layer++;
binReader.BaseStream.Position = nextIfd;
GetLayer(stream, ref layer);
}
}
snow_sky 2007-01-24
  • 打赏
  • 举报
回复
mark & up
longzhongyang 2007-01-24
  • 打赏
  • 举报
回复
http://files.codes-sources.com/fichier.aspx?id=38026&f=esieaChess%5cDirectInput.cs

http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_m_dec_2004/directx/ref/ns/microsoft.directx.direct3d/c/textureloader/m/imageinformationfromfile.asp
longzhongyang 2007-01-24
  • 打赏
  • 举报
回复
Bitmap bitmap = System.Drawing.Image.FromHbitmap(psd.GetHBitmap);
pictureBox1.Image = bitmap;

FrameDimension frameDimension = new FrameDimension(bitmap.FrameDimensionsList[0]);
int frameCount = bitmap.GetFrameCount(frameDimension);
for (int i = 0; i < frameCount; i++)
{
bitmap.SelectActiveFrame(frameDimension, i);
bitmap.Save(openFileDialog.FileName + "_" + i.ToString() + ".Tiff", ImageFormat.Tiff);

}
bbwolfcool 2007-01-22
  • 打赏
  • 举报
回复
mark

110,535

社区成员

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

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

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