2023年12月2日发(作者:)

PSD格式文件的读取  介绍*.PSD文件的读取方法,并提供完整读取函数。其中:m_Rect为目标区域,m_lpDDS7为目标DirectDraw表面,m_pbAlphaMask为目标Aplha通告指针。Read16函数为从指定文件当前位置读取一个WORD,Read32函数为从指定文件当前位置读取一个DWORD。MAX_PSD_CHANNELS为24。以下就是*.PSD文件的读取方法,有兴趣的朋友可以继续深入研究,到时可别忘了发我一份。  HRESULT LoadPSD( LPSTR strFilename ) // 读取PSD文件  {    DWORD dwWidth, dwHeight; // 宽高    long lSurfWidth = m_ - m_;    long lSurfHeight = m_ - m_;    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 ) );     = sizeof( der );    h = lSurfWidth;    ht = -lSurfHeight;    es = 1;    ount = 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 );          }        }      }    }  }