IplImage与BMP相互转换

在windows编程中,很多图片信息,都是基于windows系统所谓的DIB(设备无关位图)的结构,其定义在结构体 BITMAPINFOHEADER 中。

将windows 定义的DIB 结构和Opencv内部定义的IPLImage结构做相互转化。参考代码如下所示。

头文件bmp2ipl.h

#ifndef BMP2IPL_H
#define BMP2IPL_H
 
    class BMP {
    public:
       BMP():bmpData(NULL) {
          memset(&biHeader, 0, sizeof(biHeader));
       }
       BMP(const BMP & img);
       BMP(const IplImage &img);
       BMP(int width, int height, int bitCount);
       ~BMP(){ delete [] bmpData; }
 
       bool CreateImage(const BITMAPINFOHEADER &biHeader);
 
       IplImage * BMP2Ipl();
       void ReSize(int newW, int newH);
 
    private:
       void CopyData(char *dest, const char *src, int dataByteSize,
          bool isConvert, int height);
       // isConvert=true 进行顶左和底左之间的转换(顶左到底左或底左到顶左),否则不转换
 
       // biSizeImage may be set to zero for BI_RGB bitmaps, so calculate it.
       int ImgSize() {
          return (biHeader.biHeight*((biHeader.biWidth*biHeader.biBitCount/8+3)&(-4)));
       }
 
    public:
       void Clear();
       BITMAPINFOHEADER biHeader;
       unsigned char * bmpData;
    };
#endif
实现文件bmp2ipl.cpp
#include "bmp2ipl.h"

    BMP::BMP(const BMP & img){   
       if(!IsSupport(img)) {
          BMP();
          return;
       }
 
       //biHeader = img.biHeader;
       PBITMAPINFOHEADER  pBmpH = (PBITMAPINFOHEADER)&img.biHeader;
       memcpy(&biHeader, pBmpH, sizeof(BITMAPINFOHEADER));
       biHeader.biSizeImage = ImgSize();
       bool isLowerLeft = biHeader.biHeight>0;
       //int rowSize=0;
       if(!isLowerLeft)  biHeader.biHeight=-biHeader.biHeight;
 
       if(bmpData!=NULL) delete[] bmpData;
       bmpData = new unsigned char [biHeader.biSizeImage];
       //memcpy(bmpData, img.bmpData, img.biHeader.biSizeImage);
       CopyData((char *)bmpData, (char*)img.bmpData, biHeader.biSizeImage,
          !isLowerLeft, biHeader.biHeight);
    }
 
    BMP::BMP(const IplImage &img) {
       if(!IsSupport(img)) {
          BMP();
          return;
       }
       bool isTopLeft = (img.origin == IPL_ORIGIN_TL);
 
       biHeader.biSize = sizeof(BITMAPINFOHEADER);
       biHeader.biWidth = img.width;
       biHeader.biHeight = img.height;
       biHeader.biPlanes = 1;
       biHeader.biBitCount = img.depth * img.nChannels;
       biHeader.biCompression = BI_RGB;
       biHeader.biSizeImage = img.imageSize;
       biHeader.biXPelsPerMeter = 0;
       biHeader.biYPelsPerMeter = 0;
       biHeader.biClrUsed = 0;
       biHeader.biClrImportant = 0;
 
       if(bmpData!=NULL) delete[] bmpData;
       bmpData = new unsigned char [img.imageSize];
       //memcpy(bmpData, img.ImageData, img.imageSize);
       CopyData((char*)bmpData, (char*)img.imageData, img.imageSize,
          isTopLeft, img.height);
    }
 
    BMP::BMP(int width, int height, int bitCount) {
       if(bitCount!=8 && bitCount!=24) return;
 
       biHeader.biSize = sizeof(BITMAPINFOHEADER);
       biHeader.biWidth = width;
       biHeader.biHeight = height;
       biHeader.biPlanes = 1;
       biHeader.biBitCount = bitCount;
       biHeader.biCompression = BI_RGB;
       biHeader.biSizeImage = ImgSize();
       biHeader.biXPelsPerMeter = 0;
       biHeader.biYPelsPerMeter = 0;
       biHeader.biClrUsed = 0;
       biHeader.biClrImportant = 0;
 
       if(bmpData!=NULL) delete[] bmpData;
       bmpData = new unsigned char [biHeader.biSizeImage];
       Clear();
    }
 
    void BMP::CopyData(char *dest, const char *src, int dataByteSize,
                   bool isConvert, int height) {
       char * p = dest;
       if(!isConvert) {   
          memcpy(dest, src, dataByteSize);
          return;
       }
       if(height<=0) return;
       int rowByteSize = dataByteSize / height;
       src = src + dataByteSize - rowByteSize ;
       for(int i=0; i<height; i++) {
          memcpy(dest, src, rowByteSize);
          dest += rowByteSize;
          src  -= rowByteSize;
       }   
    }
 
    IplImage * BMP::BMP2Ipl() {
       if(!IsSupport(*this)) return NULL;
 
       IplImage *iplImg;
       int height;
       bool isLowerLeft = biHeader.biHeight>0;
       height = (biHeader.biHeight>0) ? biHeader.biHeight : -biHeader.biHeight;
       iplImg = cvCreateImage(cvSize(biHeader.biWidth,height),IPL_DEPTH_8U,biHeader.biBitCount/8);
 
       CopyData( iplImg->imageData, (char*)bmpData, biHeader.biSizeImage,
          isLowerLeft, height);
       return iplImg;
    }
 
    void BMP::Clear() {
       if(bmpData == NULL) return;
       memset(bmpData, 0, ImgSize());
    }
 
    void BMP::ReSize(int newW, int newH) {
       biHeader.biWidth = newW;
       biHeader.biHeight = newH;
       biHeader.biSizeImage = ImgSize();
       if(bmpData!=NULL) delete[] bmpData;
       bmpData = new unsigned char [biHeader.biSizeImage];
       Clear();
    }
 
    bool BMP::CreateImage(const BITMAPINFOHEADER &bih) {
       memset(&biHeader,0,sizeof(BITMAPINFOHEADER));
       delete[] bmpData;
       bmpData = NULL;
 
       memcpy(&biHeader, &bih, sizeof(BITMAPINFOHEADER));
       biHeader.biSizeImage = ImgSize();
       bmpData = new unsigned char [ biHeader.biSizeImage ];
       if(bmpData == NULL) return false;
       else{
          Clear();
          return true;
       }
    }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值