delphi 读取psd[photoshop格式]图片图层(50)

  • 主题发起人 主题发起人 zhtiger126
  • 开始时间 开始时间
Z

zhtiger126

Unregistered / Unconfirmed
GUEST, unregistred user!
我想写一个小程序,可以读取psd格式图片图层.然后我可以分别显示各个图层.
 
GraphicEx这个东西是否可以把psd文件里边的图层一层层地读出来呢?如果可以,怎么读呢?
 
Signature:8BPSVersion:1Reserved:----------------------------000000----------------------------Channels:3Rows:2181234688Columns:4026793984----------------------------Depth:8Mode:3.................................................................PSD头部信息我可以读到了,不晓得下面怎么做,呵呵...我自己顶一吧谁给我个delphi的demo给分啊...!!!!!
 
高手都学会潜伏了....:(((
 
读psd很难的难题啊?怎么大富翁没有人会啊????
 
我在一步步地实现,,,,但是很痛苦,,,那位大侠帮帮忙呀..累死人了...
 
http://dev.gameres.com/Program/Visual/Other/ReadPSD.htm
 
谢谢wangdonghai..不过,那好象是C代码,不会翻译,我想用delphi做...[:)]
 
http://dev.gameres.com/Program/Visual/Other/ReadPSD.htm这这个代码好象是读取所有图层,合并了的.我要分别读出图层来..要求高了.呵呵...
 
PhotoShop读取方法m_Rect 为目标区域m_lpDDS7 为目标DirectDraw表面m_pbAlphaMask 为目标Aplha通告指针Read16(函数) 为从指定文件当前位置读取一个WORDRead32(函数) 为从指定文件当前位置读取一个DWORDMAX_PSD_CHANNELS 为24以下就是*.PSD文件的读取方法,有兴趣的朋友可以继续深入研究,到时可别忘了发我一份。--------------------------------------------------------------------------------  HRESULT LoadPSD( LPSTR strFilename ) // 读取PSD文件  {    DWORD dwWidth, dwHeight; // 宽高    long lSurfWidth = m_Rect.right - m_Rect.left;    long lSurfHeight = m_Rect.bottom - m_Rect.top;    WORD CompressionType; // 压缩类型    HDC hDC;    FILE *fpPSD;    WORD ChannelCount; // 通道数    // 打开PSD文件    if ( ( fpPSD = fopen ( strFilename, "rb" ) ) == NULL ) {      return E_FAIL;    }    // 头四个字节为"8BPS"    char signature[5];    signature[0] = fgetc( fpPSD );    signature[1] = fgetc( fpPSD );    signature[2] = fgetc( fpPSD );    signature[3] = fgetc( fpPSD );    signature[4] = '/0';    if ( strcmp( signature,"8BPS" ) != 0 ) {      return E_FAIL;    }    // 版本必须为1    if ( Read16( fpPSD ) != 1 ) {      return E_FAIL;    }    // 跳过一些数据 (总是0)    Read32( fpPSD );    Read16( fpPSD );    // 读取通道数    ChannelCount = Read16( fpPSD );    // 确定至少有一个通道    if ( ( ChannelCount < 0 ) || ( ChannelCount > MAX_PSD_CHANNELS ) ) {      return E_FAIL;    }    // 读入宽和高    dwHeight = Read32( fpPSD );    dwWidth = Read32( fpPSD );    if ( dwWidth != ( DWORD )lSurfWidth || dwHeight != ( DWORD )lSurfHeight ) {      return E_FAIL;    }    // 只读入8位通道    if ( Read16( fpPSD ) != 8 ) {      return E_FAIL;    }    // 确定模式为RGB.    // 可能值:    // 0: 位图    // 1: 灰阶    // 2: 索引    // 3: RGB    // 4: CMYK    // 7: Multichannel    // 8: Duotone    // 9: Lab    if ( Read16( fpPSD ) != 3 ) {      return E_FAIL;    }    // 跳过数据(如调色板)    int ModeDataCount = Read32( fpPSD );    if ( ModeDataCount )      fseek( fpPSD, ModeDataCount, SEEK_CUR );    // 跳过数据(如:pen tool paths, etc)    int ResourceDataCount = Read32( fpPSD );    if ( ResourceDataCount )      fseek( fpPSD, ResourceDataCount, SEEK_CUR );    // 跳过保留数据    int ReservedDataCount = Read32( fpPSD );    if ( ReservedDataCount )      fseek( fpPSD, ReservedDataCount, SEEK_CUR );    // 0: 非压缩    // 1: RLE压缩    CompressionType = Read16( fpPSD );    if ( CompressionType > 1 ) {      return E_FAIL;    }    BYTE* PSDPixels = new BYTE[ ( lSurfWidth * lSurfHeight ) * 4 ];    //解包数据=============================================================================    UnPackPSD( fpPSD, lSurfWidth, lSurfHeight, PSDPixels, ChannelCount, CompressionType );    fclose( fpPSD );    // 复制信息    BITMAPINFO BitmapInfo;    ZeroMemory( &BitmapInfo, sizeof( BitmapInfo ) );    BitmapInfo.bmiHeader.biSize = sizeof( BitmapInfo.bmiHeader );    BitmapInfo.bmiHeader.biWidth = lSurfWidth;    BitmapInfo.bmiHeader.biHeight = -lSurfHeight;    BitmapInfo.bmiHeader.biPlanes = 1;    BitmapInfo.bmiHeader.biBitCount = 32;    m_lpDDS7->GetDC( &hDC );    int rc = StretchDIBits( hDC,                0,                0,                lSurfWidth,                lSurfHeight,                0,                0,                lSurfWidth,                lSurfHeight,                PSDPixels,                &BitmapInfo,                DIB_RGB_COLORS,                SRCCOPY );    m_lpDDS7->ReleaseDC( hDC );    if ( rc == GDI_ERROR ) {      H_ARRAY_DELETE( PSDPixels );  #ifdef _DEBUG    g_pHERR->OutDebugMsg( 3, H2DSERR_INVALID_PSD );  #endif    return E_FAIL;    }    // 是否读取Alpha混合通道    if( ChannelCount > 3 ) {      m_pbAlphaMask = new BYTE[ lSurfWidth * lSurfHeight ];    for ( int x = 0; x < lSurfWidth; x++ )      for ( int y = 0; y < lSurfHeight; y++ ) {        m_pbAlphaMask[ ( y * lSurfWidth ) + x ] =                PSDPixels[ ( ( ( y * lSurfHeight ) + x ) * 4 ) + 3 ];      }    }    else {      m_pbAlphaMask = NULL;    }    H_ARRAY_DELETE( PSDPixels );    return DD_OK;  }  //PSD文件解包=========================================================================  void CHades2DSurface::UnPackPSD( FILE *fp,     // fp为PSD文件指针,                   DWORD dwWidth,   // dwWidth、dwHeight为宽高,                   DWORD dwHeight,                   BYTE* pixels,   // pixels为解包目标指针,                   WORD ChannelCnt,  // ChannelCnt为通道数,                   WORD Compression ) // Compression位压缩类型。                                    {    int Default[4] = { 0, 0, 0, 255 };    int chn[4] = { 2, 1, 0, 3};    int PixelCount = dwWidth * dwHeight;    if ( Compression ) {      fseek( fp, dwHeight * ChannelCnt * 2, SEEK_CUR );      for ( int c = 0; c < 4; c++ ) {        int pn = 0;        int channel = chn[c];        if ( channel >= ChannelCnt ) {          for ( pn=0; pn < PixelCount ;pn++ ) {            pixels[ ( pn * 4 ) + channel ] = Default[ channel ];          }        }        else // 非压缩        {          int count = 0;          while( count < PixelCount ) {            int len = fgetc( fp );            if( len == 128 ) { }            else if ( len < 128 ) // 非RLE            {              len++;              count += len;              while(len) {                pixels[ ( pn * 4 ) + channel ] = fgetc( fp );                pn++;                len--;              }            }             else if ( len > 128 ) // RLE打包            {              len ^= 0x0FF;              len += 2;              unsigned char val = fgetc( fp );              count += len;              while( len ) {                pixels[ ( pn * 4 ) + channel ] = val;                pn++;                len--;              }            }          }        }      }    }    else    {      for ( int c=0; c < 4; c++ ) {        int channel = chn[c];        if ( channel > ChannelCnt ) {          for( int pn = 0; pn < PixelCount; pn++ ) {            pixels[ ( pn * 4 ) + channel ] = Default[ channel ];          }        }        else {          for( int n = 0; n < PixelCount; n++ ) {            pixels[ ( n * 4 ) + channel ] = fgetc( fp );          }        }      }    }  } --------------------------------------------------------------------------------
 
这是C的pad读取方法有谁可以把它翻译成delphi代码呢???
 
对于这个问题,楼主给的分数太少了。下面给你一个读取并显示PSD文件的代码(只处理压缩方法为RLE,且象素格式为RGB的PSD文件,代码参考http://www.codeproject.com/bitmap/MyPSD.asp)type TPSDFileHeader=record Signature:array[0..3] of char; Version:Word; Reserved:array[0..5] of Byte; Channels:Word; Height:Integer; Width:Integer; BitsPerPixel:Word; ColorMode:Word;end;function Calc(c:array of Byte;nDigits:integer):integer;var n,nValue:integer;begin nValue:=0; for n:=0 to nDigits-1 do nValue:=nValue shl 8 or c[n]; result:=nValue;end;procedure TForm1.Button1Click(Sender: TObject);var fs:TFileStream; PSDFH:TPSDFileHeader; TmpBuf:array[0..5] of Byte; i,iLen,iValue,Count,iTotalBytes,iPixels:Integer; pData,p,pDest:PByte; hMemDC:HDC; BmpInfo:BITMAPINFO; pp:Pointer; hBmp:HBitmap;begin fs:=TFileStream.Create('1.psd',fmOpenRead); try //Read File Header fs.ReadBuffer(PSDFH.Signature,sizeof(PSDFH.Signature)); fs.ReadBuffer(TmpBuf,2); PSDFH.Version:=Calc(TmpBuf,2); fs.ReadBuffer(PSDFH.Reserved,sizeof(PSDFH.Reserved)); fs.ReadBuffer(TmpBuf,2); PSDFH.Channels:=Calc(TmpBuf,2); fs.ReadBuffer(TmpBuf,4); PSDFH.Height:=Calc(TmpBuf,4); fs.ReadBuffer(TmpBuf,4); PSDFH.Width:=Calc(TmpBuf,4); fs.ReadBuffer(TmpBuf,2); PSDFH.BitsPerPixel:=Calc(TmpBuf,2); fs.ReadBuffer(TmpBuf,2); PSDFH.ColorMode:=Calc(TmpBuf,2); //Read Color fs.ReadBuffer(TmpBuf,4); iLen:=Calc(TmpBuf,4); fs.Seek(iLen,soFromCurrent); //Read Image Source fs.ReadBuffer(TmpBuf,4); iLen:=Calc(TmpBuf,4); fs.Seek(iLen,soFromCurrent); //Read Layer fs.ReadBuffer(TmpBuf,4); iLen:=Calc(TmpBuf,4); fs.Seek(iLen,soFromCurrent); //压缩方法 fs.ReadBuffer(TmpBuf,2); iLen:=Calc(TmpBuf,2); if (iLen=1) and (PSDFH.ColorMode=3) then begin iPixels:=PSDFH.Width*PSDFH.Height; iTotalBytes:=iPixels*PSDFH.BitsPerPixel div 8*PSDFH.Channels; GetMem(pData,iTotalBytes); p:=pData; fs.Seek(PSDFH.Height*PSDFH.Channels*2,soFromCurrent); for i:=0 to PSDFH.Channels-1 do begin Count:=0; while Count<iPixels do begin fs.ReadBuffer(TmpBuf,1); iLen:=Calc(TmpBuf,1); if 128>iLen then begin inc(iLen); inc(Count,iLen); while iLen<>0 do begin fs.ReadBuffer(TmpBuf,1); iValue:=Calc(TmpBuf,1); p^:=iValue; inc(p); dec(iLen); end; end else if 128<iLen then begin iLen:=iLen xor $FF; inc(iLen,2); fs.ReadBuffer(TmpBuf,1); iValue:=Calc(TmpBuf,1); inc(Count,iLen); while iLen<>0 do begin p^:=iValue; inc(p); dec(iLen); end; end; end; end; p:=pData; GetMem(pDest,iTotalBytes); for i:=0 to PSDFH.Channels-1 do begin Count:=i; for iLen:=0 to iPixels-1 do begin PByte(Integer(pDest)+Count)^:=p^; inc(p); inc(Count,3); end; end; BmpInfo.bmiHeader.biSize:=sizeof(BITMAPINFOHEADER); BmpInfo.bmiHeader.biWidth:=PSDFH.Width; BmpInfo.bmiHeader.biHeight:=-PSDFH.Height; BmpInfo.bmiHeader.biPlanes:=1; BmpInfo.bmiHeader.biBitCount:=24; BmpInfo.bmiHeader.biCompression:=BI_RGB; BmpInfo.bmiHeader.biSizeImage:=0; BmpInfo.bmiHeader.biXPelsPerMeter:=0; BmpInfo.bmiHeader.biYPelsPerMeter:=0; BmpInfo.bmiHeader.biClrImportant:=0; BmpInfo.bmiHeader.biClrUsed:=0; hBmp:=CreateDIBSection(GetDC(0),BmpInfo, DIB_RGB_COLORS,pp,0,0); hMemDC:=CreateCompatibleDC(0); SelectObject(hMemDC,hBmp); Count:=0; while Count<iTotalBytes do //Swap b to r begin iLen:=PByte(Integer(pDest)+Count+2)^; PByte(Integer(pDest)+Count+2)^:=PByte(Integer(pDest)+Count)^; PByte(Integer(pDest)+Count)^:=iLen; inc(Count,3); end; Move(pDest^,pp^,iTotalBytes); BitBlt(Canvas.Handle,0,0,PSDFH.Width,PSDFH.Height, hMemDC,0,0,SRCCOPY); DeleteDC(hMemDC); FreeMem(pDest); FreeMem(pData); end; finally fs.Free; end;end;
 
wangdonghai~..谢谢你! 你的代码对我很有用,我想你一定能做出我所要的,我是想一层层地读出来,并分别显示不同的image中...50分先给你,,我看看我还有多少分,只要有,,,我是舍得的..呵呵...感谢感谢!
 
wangdonghai~ 我想一层层地把psd的图层读出来,可以帮我写一个吗? 分我可以再给...拜托!!!
 
后退
顶部