MFC上显示摄像头JPEG图片数据的两种方法

  其一是借助opencv,其二是利用流对象。

方法一:

CvMat *mat;                                        //创建矩阵
mat = cvCreateMat(640,480,CV_8UC1); //指定分配内存大小
cvInitMatHeader(mat,640,480,CV_8UC1,JPEGBuf);   
/*初始化矩阵信息头,这里的JPEGBuf就是JPEG图像数据的地址。现在很多摄像头是支持JPEG输出的,而且JPEG图像输出节 省宽带。640*480大小的图片大小仅在20K以内。网上提到的什么视频采集卡,提供的SDK也基本提供JPEG数据,它获得的数 据就是图像数据,而不是图像文件。*/
IplImage *pIplImage = cvDecodeImage(mat,CV_LOAD_IMAGE_COLOR); //这里将JPEG图像数组转化为IplImage类,这里自动包含了解压JPEG格式图片功能。 if(pIplImage != NULL) //如果解压失败得到的是NULL {   CvvImage cimg; //CvvImage类在opencv 2.2以后没有CvvImage类了,网上搜索这个类,有低版本的源代码,直接添加到工程里就可以用了。   cimg.CopyOf( pIplImage); //复制图像   cimg.DrawToHDC(pMainDlg->m_DispHDC, &pMainDlg->m_DispRECT); //显示图像   cvReleaseImage(&pIplImage);//释放图像 }
cvReleaseMat(
&mat); //释放矩阵

    下面这个是个学习资料。  

  利用opencv读取图片并在MFC上显示,链接地址:http://licong1018.blog.163.com/blog/static/9026978420129239178934/

      更新:因为自己需要,想要弄这个还要去翻看原来的工程文件。索性把CvvImage类贴在这里:

一、CvvImage.h

 1 #pragma once
 2 
 3 #ifndef CVVIMAGE_CLASS_DEF
 4 #define CVVIMAGE_CLASS_DEF
 5 
 6 #include "opencv.hpp"
 7 
 8 /* CvvImage class definition */
 9 class  CvvImage
10 {
11 public:
12    CvvImage();
13    virtual ~CvvImage();
14 
15    /* Create image (BGR or grayscale) */
16    virtual bool  Create( int width, int height, int bits_per_pixel, int image_origin = 0 );
17 
18    /* Load image from specified file */
19    virtual bool  Load( const char* filename, int desired_color = 1 );
20 
21    /* Load rectangle from the file */
22    virtual bool  LoadRect( const char* filename,
23       int desired_color, CvRect r );
24 
25 #if defined WIN32 || defined _WIN32
26    virtual bool  LoadRect( const char* filename,
27       int desired_color, RECT r )
28    {
29       return LoadRect( filename, desired_color,
30          cvRect( r.left, r.top, r.right - r.left, r.bottom - r.top ));
31    }
32 #endif
33 
34    /* Save entire image to specified file. */
35    virtual bool  Save( const char* filename );
36 
37    /* Get copy of input image ROI */
38    virtual void  CopyOf( CvvImage& image, int desired_color = -1 );
39    virtual void  CopyOf( IplImage* img, int desired_color = -1 );
40 
41    IplImage* GetImage() { return m_img; };
42    virtual void  Destroy(void);
43 
44    /* width and height of ROI */
45    int Width() { return !m_img ? 0 : !m_img->roi ? m_img->width : m_img->roi->width; };
46    int Height() { return !m_img ? 0 : !m_img->roi ? m_img->height : m_img->roi->height;};
47    int Bpp() { return m_img ? (m_img->depth & 255)*m_img->nChannels : 0; };
48 
49    virtual void  Fill( int color );
50 
51    /* draw to highgui window */
52    virtual void  Show( const char* window );
53 
54 #if defined WIN32 || defined _WIN32
55    /* draw part of image to the specified DC */
56    virtual void  Show( HDC dc, int x, int y, int width, int height,
57       int from_x = 0, int from_y = 0 );
58    /* draw the current image ROI to the specified rectangle of the destination DC */
59    virtual void  DrawToHDC( HDC hDCDst, RECT* pDstRect );
60 #endif
61 
62 protected:
63 
64    IplImage*  m_img;
65 };
66 
67 typedef CvvImage CImage;
68 
69 #endif
View Code

二、CvvImage.cpp

  1 #include "StdAfx.h"
  2 #include "CvvImage.h"
  3 
  4 //////////////////////////////////////////////////////////////////////
  5 // Construction/Destruction
  6 //////////////////////////////////////////////////////////////////////
  7 
  8 CV_INLINE RECT NormalizeRect( RECT r );
  9 CV_INLINE RECT NormalizeRect( RECT r )
 10 {
 11    int t;
 12 
 13    if( r.left > r.right )
 14    {
 15       t = r.left;
 16       r.left = r.right;
 17       r.right = t;
 18    }
 19 
 20    if( r.top > r.bottom )
 21    {
 22       t = r.top;
 23       r.top = r.bottom;
 24       r.bottom = t;
 25    }
 26 
 27    return r;
 28 }
 29 
 30 CV_INLINE CvRect RectToCvRect( RECT sr );
 31 CV_INLINE CvRect RectToCvRect( RECT sr )
 32 {
 33    sr = NormalizeRect( sr );
 34    return cvRect( sr.left, sr.top, sr.right - sr.left, sr.bottom - sr.top );
 35 }
 36 
 37 CV_INLINE RECT CvRectToRect( CvRect sr );
 38 CV_INLINE RECT CvRectToRect( CvRect sr )
 39 {
 40    RECT dr;
 41    dr.left = sr.x;
 42    dr.top = sr.y;
 43    dr.right = sr.x + sr.width;
 44    dr.bottom = sr.y + sr.height;
 45 
 46    return dr;
 47 }
 48 
 49 CV_INLINE IplROI RectToROI( RECT r );
 50 CV_INLINE IplROI RectToROI( RECT r )
 51 {
 52    IplROI roi;
 53    r = NormalizeRect( r );
 54    roi.xOffset = r.left;
 55    roi.yOffset = r.top;
 56    roi.width = r.right - r.left;
 57    roi.height = r.bottom - r.top;
 58    roi.coi = 0;
 59 
 60    return roi;
 61 }
 62 
 63 void  FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp, int origin )
 64 {
 65    assert( bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32));
 66 
 67    BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
 68 
 69    memset( bmih, 0, sizeof(*bmih));
 70    bmih->biSize = sizeof(BITMAPINFOHEADER);
 71    bmih->biWidth = width;
 72    bmih->biHeight = origin ? abs(height) : -abs(height);
 73    bmih->biPlanes = 1;
 74    bmih->biBitCount = (unsigned short)bpp;
 75    bmih->biCompression = BI_RGB;
 76 
 77    if( bpp == 8 )
 78    {
 79       RGBQUAD* palette = bmi->bmiColors;
 80       int i;
 81       for( i = 0; i < 256; i++ )
 82       {
 83          palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
 84          palette[i].rgbReserved = 0;
 85       }
 86    }
 87 }
 88 
 89 CvvImage::CvvImage()
 90 {
 91    m_img = 0;
 92 }
 93 
 94 void CvvImage::Destroy()
 95 {
 96    cvReleaseImage( &m_img );
 97 }
 98 
 99 CvvImage::~CvvImage()
100 {
101    Destroy();
102 }
103 
104 bool  CvvImage::Create( int w, int h, int bpp, int origin )
105 {
106    const unsigned max_img_size = 10000;
107 
108    if( (bpp != 8 && bpp != 24 && bpp != 32) ||
109       (unsigned)w >=  max_img_size || (unsigned)h >= max_img_size ||
110       (origin != IPL_ORIGIN_TL && origin != IPL_ORIGIN_BL))
111    {
112       assert(0); // most probably, it is a programming error
113       return false;
114    }
115 
116    if( !m_img || Bpp() != bpp || m_img->width != w || m_img->height != h )
117    {
118       if( m_img && m_img->nSize == sizeof(IplImage))
119          Destroy();
120 
121       /* prepare IPL header */
122       m_img = cvCreateImage( cvSize( w, h ), IPL_DEPTH_8U, bpp/8 );
123    }
124 
125    if( m_img )
126       m_img->origin = origin == 0 ? IPL_ORIGIN_TL : IPL_ORIGIN_BL;
127 
128    return m_img != 0;
129 }
130 
131 void  CvvImage::CopyOf( CvvImage& image, int desired_color )
132 {
133    IplImage* img = image.GetImage();
134    if( img )
135    {
136       CopyOf( img, desired_color );
137    }
138 }
139 
140 
141 #define HG_IS_IMAGE(img)                                                  
142    ((img) != 0 && ((const IplImage*)(img))->nSize == sizeof(IplImage) && 
143    ((IplImage*)img)->imageData != 0)
144 
145 
146 void  CvvImage::CopyOf( IplImage* img, int desired_color )
147 {
148    if( HG_IS_IMAGE(img) )
149    {
150       int color = desired_color;
151       CvSize size = cvGetSize( img ); 
152 
153       if( color < 0 )
154          color = img->nChannels > 1;
155 
156       if( Create( size.width, size.height,
157          (!color ? 1 : img->nChannels > 1 ? img->nChannels : 3)*8,
158          img->origin ))
159       {
160          cvConvertImage( img, m_img, 0 );
161       }
162    }
163 }
164 
165 
166 bool  CvvImage::Load( const char* filename, int desired_color )
167 {
168    IplImage* img = cvLoadImage( filename, desired_color );
169    if( !img )
170       return false;
171 
172    CopyOf( img, desired_color );
173    cvReleaseImage( &img );
174 
175    return true;
176 }
177 
178 
179 bool  CvvImage::LoadRect( const char* filename,
180                    int desired_color, CvRect r )
181 {
182    if( r.width < 0 || r.height < 0 ) return false;
183 
184    IplImage* img = cvLoadImage( filename, desired_color );
185    if( !img )
186       return false;
187 
188    if( r.width == 0 || r.height == 0 )
189    {
190       r.width = img->width;
191       r.height = img->height;
192       r.x = r.y = 0;
193    }
194 
195    if( r.x > img->width || r.y > img->height ||
196       r.x + r.width < 0 || r.y + r.height < 0 )
197    {
198       cvReleaseImage( &img );
199       return false;
200    }
201 
202    /* truncate r to source image */
203    if( r.x < 0 )
204    {
205       r.width += r.x;
206       r.x = 0;
207    }
208    if( r.y < 0 )
209    {
210       r.height += r.y;
211       r.y = 0;
212    }
213 
214    if( r.x + r.width > img->width )
215       r.width = img->width - r.x;
216 
217    if( r.y + r.height > img->height )
218       r.height = img->height - r.y;
219 
220    cvSetImageROI( img, r );
221    CopyOf( img, desired_color );
222 
223    cvReleaseImage( &img );
224    return true;
225 }
226 
227 
228 bool  CvvImage::Save( const char* filename )
229 {
230    if( !m_img )
231       return false;
232    cvSaveImage( filename, m_img );
233    return true;
234 }
235 
236 
237 void  CvvImage::Show( const char* window )
238 {
239    if( m_img )
240       cvShowImage( window, m_img );
241 }
242 
243 
244 void  CvvImage::Show( HDC dc, int x, int y, int w, int h, int from_x, int from_y )
245 {
246    if( m_img && m_img->depth == IPL_DEPTH_8U )
247    {
248       uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
249       BITMAPINFO* bmi = (BITMAPINFO*)buffer;
250       int bmp_w = m_img->width, bmp_h = m_img->height;
251 
252       FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(), m_img->origin );
253 
254       from_x = MIN( MAX( from_x, 0 ), bmp_w - 1 );
255       from_y = MIN( MAX( from_y, 0 ), bmp_h - 1 );
256 
257       int sw = MAX( MIN( bmp_w - from_x, w ), 0 );
258       int sh = MAX( MIN( bmp_h - from_y, h ), 0 );
259 
260       SetDIBitsToDevice(
261          dc, x, y, sw, sh, from_x, from_y, from_y, sh,
262          m_img->imageData + from_y*m_img->widthStep,
263          bmi, DIB_RGB_COLORS );
264    }
265 }
266 
267 
268 void  CvvImage::DrawToHDC( HDC hDCDst, RECT* pDstRect ) 
269 {
270    if( pDstRect && m_img && m_img->depth == IPL_DEPTH_8U && m_img->imageData )
271    {
272       uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
273       BITMAPINFO* bmi = (BITMAPINFO*)buffer;
274       int bmp_w = m_img->width, bmp_h = m_img->height;
275 
276       CvRect roi = cvGetImageROI( m_img );
277       CvRect dst = RectToCvRect( *pDstRect );
278 
279       if( roi.width == dst.width && roi.height == dst.height )
280       {
281          Show( hDCDst, dst.x, dst.y, dst.width, dst.height, roi.x, roi.y );
282          return;
283       }
284 
285       if( roi.width > dst.width )
286       {
287          SetStretchBltMode(
288             hDCDst,           // handle to device context
289             HALFTONE );
290       }
291       else
292       {
293          SetStretchBltMode(
294             hDCDst,           // handle to device context
295             COLORONCOLOR );
296       }
297 
298       FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(), m_img->origin );
299 
300       ::StretchDIBits(
301          hDCDst,
302          dst.x, dst.y, dst.width, dst.height,
303          roi.x, roi.y, roi.width, roi.height,
304          m_img->imageData, bmi, DIB_RGB_COLORS, SRCCOPY );
305    }
306 }
307 
308 
309 void  CvvImage::Fill( int color )
310 {
311    cvSet( m_img, cvScalar(color&255,(color>>8)&255,(color>>16)&255,(color>>24)&255) );
312 }
View Code

方法二:

void CTestDlg::DisplayJPEG(HDC hDC,unsigned char *buf,UINT bufLen,int rectWidth,int rectHeight)
{
    HGLOBAL hImageMemory=GlobalAlloc(GMEM_MOVEABLE, bufLen);//给图片分配全局内存
    void *pImageMemory=GlobalLock(hImageMemory);            //锁定内存
    if(pImageMemory == NULL)
    {
        TRACE("can't Get Global Memory!
");
        goto ret;
    }
    memcpy(pImageMemory,buf,bufLen);                        //读取图片到全局内存当中
    GlobalUnlock(hImageMemory);                             //解锁内存

    IStream *pIStream;                                        //创建一个IStream接口指针,用来保存图片流
    IPicture *pIPicture;                                      //创建一个IPicture接口指针,表示图片对象
    CreateStreamOnHGlobal(hImageMemory, false,&pIStream);     //用全局内存初使化IStream接口指针
    OleLoadPicture(pIStream, 0, false, IID_IPicture,(LPVOID*)&(pIPicture));//用OleLoadPicture获得IPicture接口指针
    if(pIStream == NULL)
    {
        TRACE("can't Get pIStream!
");
        goto ret;
    }

    OLE_XSIZE_HIMETRIC hmWidth;
    OLE_YSIZE_HIMETRIC hmHeight;

    if(pIPicture == NULL)
    {
        TRACE("can't Get Picture Info!
");
        goto ret;
    }

    pIPicture->get_Width(&hmWidth);  //用接口方法获得图片的宽和高
    pIPicture->get_Height(&hmHeight);
    pIPicture->Render(hDC,0,0,rectWidth,rectHeight,0,hmHeight,hmWidth,-hmHeight,NULL);//在指定的DC上绘出图片

    //以下代码为了保存一张图片
    ///////////////////////////////////////////////////////////////////////////////////
    if(m_bSavePic == TRUE)
    {
        m_SaveFile.Open("Hello.jpg",CFile::modeCreate|CFile::modeWrite);           //读写方式打开
        m_SaveFile.Seek(0,CFile::begin);
        m_SaveFile.Write(buf,bufLen);                                             //将文件读入缓存
        m_SaveFile.Close();
        m_bSavePic = FALSE;
    }
    ///////////////////////////////////////////////////////////////////////////////////

    pIStream->Release(); //释放pIStream
    pIPicture->Release(); //释放pIPicture
ret:
    GlobalFree(hImageMemory); //释放全局内存
}
原文地址:https://www.cnblogs.com/kanite/p/5092138.html