• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            c++初學(xué)者

            專注技術(shù)開發(fā)

            [轉(zhuǎn)]PSD格式文件的讀取

             PhotoShop,我想沒有人會不知道吧。如今最新的版本是6.0,其圖象文件*.PSD和5.5相比變化并不太大。以下我就介紹*.PSD文件的讀取方法,并提供完整讀取函數(shù)。其中:m_Rect為目標(biāo)區(qū)域,m_lpDDS7為目標(biāo)DirectDraw表面,m_pbAlphaMask為目標(biāo)Aplha通告指針。Read16函數(shù)為從指定文件當(dāng)前位置讀取一個WORD,Read32函數(shù)為從指定文件當(dāng)前位置讀取一個DWORD。MAX_PSD_CHANNELS為24。以下就是*.PSD文件的讀取方法,有興趣的朋友可以繼續(xù)深入研究,到時可別忘了發(fā)我一份。

              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;
            // 通道數(shù)

                // 打開PSD文件
                if ( ( fpPSD = fopen ( strFilename, "rb" ) ) == NULL ) {
                  return E_FAIL;
                }

                // 頭四個字節(jié)為"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;
                }

                // 跳過一些數(shù)據(jù) (總是0)
                Read32( fpPSD );
                Read16( fpPSD );

                // 讀取通道數(shù)
                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;
                }

                // 跳過數(shù)據(jù)(如調(diào)色板)
                int ModeDataCount = Read32( fpPSD );
                if ( ModeDataCount )
                  fseek( fpPSD, ModeDataCount, SEEK_CUR );

                // 跳過數(shù)據(jù)(如:pen tool paths, etc)
                int ResourceDataCount = Read32( fpPSD );
                if ( ResourceDataCount )
                  fseek( fpPSD, ResourceDataCount, SEEK_CUR );

                // 條過保留數(shù)據(jù)
                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 ];

                // 解包數(shù)據(jù)
                UnPackPSD( fpPSD, lSurfWidth, lSurfHeight, PSDPixels, ChannelCount, CompressionType );

                fclose( fpPSD );

                // 復(fù)制信息
                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為解包目標(biāo)指針,
                               WORD ChannelCnt,
              // ChannelCnt為通道數(shù),
                               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 );
                      }
                    }
                  }
                }
              }

            posted on 2008-12-26 18:15 大海 閱讀(1413) 評論(0)  編輯 收藏 引用 所屬分類: 圖像

            青青热久久综合网伊人| 国产精品中文久久久久久久 | 东京热TOKYO综合久久精品| 久久se精品一区二区影院 | 亚洲精品无码成人片久久| 亚洲国产精品无码久久久蜜芽| 欧美午夜A∨大片久久 | 色综合合久久天天给综看| 久久久久亚洲精品天堂久久久久久| 久久精品国产一区二区三区不卡| 久久国产影院| 久久亚洲精品人成综合网| 久久精品成人欧美大片| 色诱久久久久综合网ywww| 国产精品久久久久影视不卡| 色播久久人人爽人人爽人人片aV | 久久精品不卡| 久久久久亚洲av无码专区| 亚洲精品无码久久久久AV麻豆| 久久久久久极精品久久久| 久久亚洲欧美国产精品| 久久人妻少妇嫩草AV蜜桃| 久久久国产精品| 国产精品久久久久久搜索| 亚洲精品乱码久久久久久 | yellow中文字幕久久网| 综合久久国产九一剧情麻豆 | 久久香综合精品久久伊人| 国産精品久久久久久久| 中文字幕亚洲综合久久| 久久人人爽人人爽人人av东京热| 久久久久久A亚洲欧洲AV冫| 精品国产乱码久久久久久郑州公司| 日韩va亚洲va欧美va久久| 日韩精品久久久久久| 97久久综合精品久久久综合| 亚洲午夜久久久久久久久久| 国内高清久久久久久| 亚洲国产另类久久久精品| 亚洲女久久久噜噜噜熟女| 一本久久a久久精品亚洲|