EMF 文件分析

 

EMF文件结构
Emf 主要由 Emf 头记录、描述和记录构成:
Emf头
typedef struct tagENHMETAHEADER { 
  DWORD iType; 应该为1(EMR_HEADER)
 DWORD nSize; Header大小,不包括描述
 RECTL rclBounds; 图像的边框尺寸(设备单位)
 RECTL rclFrame; 图像的边框尺寸0.01 mm为单位)
 DWORD dSignature; 0x464d4520(EMF标志)
 DWORD nVersion; 0x10000
 DWORD nBytes; 元文件的尺寸(整个文件大小)
 DWORD nRecords; Emf记录数(包括头,描述数据头记录)
 WORD nHandles; 
  WORD sReserved; 
  DWORD nDescription; 描述长度,以byte为单位
 DWORD offDescription; 描述存放地方,文件开始为0开始计算
 DWORD nPalEntries; 
  SIZEL szlDevice; 原始设备分辩率(像素单位)
 SIZEL szlMillimeters;原始设备分辩率mm单位)
#if (WINVER >= 0x0400)
 DWORD cbPixelFormat;
 DWORD offPixelFormat;
 DWORD bOpenGL;
#endif /* WINVER >= 0x0400 */
#if (WINVER >= 0x0500)
 SIZEL szlMicrometers; szlMillimeters*1000
#endif /* WINVER >= 0x0500 */
} ENHMETAHEADER, *PENHMETAHEADER; 
EMF描述
如果头记录的 nDescription 大于 0 则表示有内容,否则为空,一般紧接在 EMR_HEADER 后面
EMF记录
记录格式:
DWORD iType; 类型,如EMR_HEADER, EMR_EOF
 DWORD nSize;长度,包括iType,nSize,内容
 具体内容
EMF最后记录
 EMR     emr;EMF记录(iType和nSize)
 DWORD   nPalEntries; 调色板数
 DWORD   offPalEntries; 调色板位置,从iType开始计算
 DWORD   nSizeLast;  nSize大小,如果有调色板,则调色版在nSizeLast前面
 
例子
//打开Emf文件
if (!m_File.Open(strFileName ,CFile::modeRead , &m_FileException))
     {
         TCHAR szError[1024];
         m_FileException.GetErrorMessage(szError, 1024);
         TRACE(L"Couldn't open source file::%s,errormsg:s/n",strFileName,szError) ;
         return ;
     }
     DWORD dwReaded ;
// 读取Emf Header
     dwReaded = m_File.Read( &m_EnhMetaHeader , sizeof( ENHMETAHEADER ) ) ;
     if( dwReaded < sizeof( ENHMETAHEADER ) )
     {
         TRACE("Read meta header error!/n") ;
         m_File.Close() ;
         return ;
     }
     if( m_EnhMetaHeader.dSignature!=0x464d4520)
     {
         TRACE("This file is not emf file./n");
         m_File.Close() ;
         return;
     }
// 读取描述
     if ( m_EnhMetaHeader.nDescription > 0 )
     {
         //file.Seek(eh.offDescription,CFile::begin);
         TCHAR *szDesciption ;
         szDesciption = new TCHAR[m_EnhMetaHeader.nDescription+1] ;
         memset( szDesciption , 0 , sizeof( TCHAR) * (m_EnhMetaHeader.nDescription+1));
         dwReaded = m_File.Read(szDesciption , m_EnhMetaHeader.nDescription * sizeof( TCHAR) ) ;
         if( dwReaded == m_EnhMetaHeader.nDescription * sizeof( TCHAR) )
         {
              TRACE(L"description:%s/n",szDesciption);
         }
         //file.Seek( sizeof( ENHMETAHEADER ) , CFile::begin) ;
         delete szDesciption ;
     }
     m_dwEmfRecord = 0 ;
// 读取记录
DWORD dwReaded = m_File.Read( &iType , 4 ) ;
     if( dwReaded < 4 )
         return ;
     dwReaded = m_File.Read( &nSize , 4 ) ;
     if( dwReaded < 4 )
         return ;
     lpParam = new BYTE[nSize ];
     memset( lpParam , 0 , nSize ) ;
     memcpy( lpParam , &iType , 4 ) ;
     memcpy( lpParam + 4 , &nSize , 4 ) ;
     if( lpParam == NULL )
         return ;
     if( nSize > 8 )
     {
         dwReaded = m_File.Read(lpParam + 8, nSize - 8 ) ;
         if( dwReaded < nSize - 8 )
              return ;
     }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值