解析JPGE文件 获取文件像素尺寸


SIZE GetJPGEImagePiex(LPCTSTR szFileName)
{
  SIZE sizePiex={0,0};

  HANDLE hFile = INVALID_HANDLE_VALUE;
  
  do 
  {
    hFile = CreateFile(szFileName,
      GENERIC_READ, 
      FILE_SHARE_WRITE,
      NULL,
      OPEN_EXISTING,
      0,
      NULL);

    if(hFile == INVALID_HANDLE_VALUE)
    {
      DWORD dwErr = GetLastError();
      _ASSERT(FALSE);
    }
    
   #pragma pack(push, 1)
    struct _tagImgSection_t
    {
      BYTE SectionStart; //必须为0xFF
      BYTE SectionID; //段标识
      BYTE SectionLenH, SectionLenL; //段长度高8位//段长度低8位
    }ImgSection;
   #pragma pack(pop)

    DWORD dwReaded = 0;

    //图像头SOI标识
    if((!ReadFile(hFile, &ImgSection, 2, &dwReaded, NULL))
      || (dwReaded != 2)
      || (ImgSection.SectionStart != 0xFF) //非标记
      || (ImgSection.SectionID != 0xD8)//非SOI起始头
      || 0)
    {
      _ASSERT(FALSE);
      break;
    }

    BOOL bDone = FALSE;
    
    while(! bDone)
    {      
      memset(&ImgSection, 0, sizeof(ImgSection));

      if((! ReadFile(hFile, &ImgSection, sizeof(ImgSection), &dwReaded, NULL))
        || (dwReaded != sizeof(ImgSection))
        || 0)
        break; //读入出错
      
      if(ImgSection.SectionStart != 0xFF) //非段标识标记
        break;

      switch(ImgSection.SectionID)
      {
      case(0xFF): //当前标识为数据
        {
          continue;
        }
      case(0xD9): // EOI,End of Image,图像结束
        {
          bDone = TRUE;
          break;
        }
      case(0xC0): //SOF0,Start of Frame,帧图像开始
        {
         #pragma pack(push, 1) //结构体一个字节对齐
          typedef struct _tagSOF0STRUCT_t
          {
            struct _tagHead_t
            {
              //BYTE wLenH, wLenL; //① 数据长度  2字节     ①~⑥六个字段的总长度
              BYTE Sample_precision; //② 精度  1字节     每个数据样本的位数
              BYTE HighPiexsH, HighPiexsL; //③ 图像高度   图像高度(单位:像素)
              BYTE WidthPiexsH, WidthPiexsL; //④ 图像宽度  图像宽度(单位:像素)
              BYTE ColorTabNums; // ⑤ 颜色分量数 
            }Head;
            //而JFIF中使用YCrCb,故这里颜色分量数恒为3
            struct _ColorTab 
            { // ⑥颜色分量信息      颜色分量数×3字节(通常为9字节)
              
              BYTE tabID; //a)         颜色分量ID  1字节    
              BYTE vSampFactor:4;  //低4位:垂直采样因子
              BYTE hSampFactory:4; //高4位:水平采样因子
              BYTE curTabID;       //当前分量使用的量化表的ID
            }ColorTag[1];
          }SOF0STRUCT;
         #pragma pack(pop) //恢复结构体对齐长度
          
          SOF0STRUCT sofoData = {0};
          int headLen = sizeof(sofoData.Head);
          if( (!ReadFile(hFile, &sofoData, headLen, &dwReaded, NULL))
            || dwReaded != sizeof(sofoData.Head))  
            break;
          
          sizePiex.cx = MAKEWORD(sofoData.Head.WidthPiexsL, sofoData.Head.WidthPiexsH);
          sizePiex.cy = MAKEWORD(sofoData.Head.HighPiexsL, sofoData.Head.HighPiexsH);
          
          //后续的略……

          bDone = TRUE;
          break;
        }
      default:
        {
          LONG iSeek = (LONG)MAKEWORD(ImgSection.SectionLenL, ImgSection.SectionLenH) - 2;
          SetFilePointer(hFile, iSeek, NULL, FILE_CURRENT);
          break;
        }
      } 
    }
   
  } while (0);
  

  if(hFile != INVALID_HANDLE_VALUE)
  {
    CloseHandle(hFile);
  }

  return sizePiex;
}


//测试
  CFileDialog fileDlg(TRUE);
  if(fileDlg.DoModal() == IDOK)
  {
    SIZE imgPiex = GetJPGEImagePiex(fileDlg.GetPathName());

    CString szMsg;
    szMsg.Format(_T("%s\n(width=%d height=%d)"),
      fileDlg.GetFileName(),
      imgPiex.cx, imgPiex.cy);
    AfxMessageBox(szMsg);
  }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值