当前位置: 首页 > news >正文

网络认证网站/阿里巴巴怎么优化关键词排名

网络认证网站,阿里巴巴怎么优化关键词排名,软件开发人天报价标准,企业网站建设的文章本文介绍在MFC框架下,使用opencv的解码函数对图片进行解码,并最终显示到窗口。在此过程中,遇到了图片显示时的大小问题,以及闪烁问题,本文将一一解决。 【显示图片】 1. 在CImageProcessView::OnDraw(CDC* pDC) 中写绘…

本文介绍在MFC框架下,使用opencv的解码函数对图片进行解码,并最终显示到窗口。在此过程中,遇到了图片显示时的大小问题,以及闪烁问题,本文将一一解决。 

【显示图片】

1. 在CImageProcessView::OnDraw(CDC* pDC) 中写绘制图片的代码
    我们已经打开图片时,利用opencv对图片文件进行了解码,图像数据已经在src_image中持有,现在需要把src_image中的数据绘制到窗口。

void CImageProcessView::OnDraw(CDC* pDC)
{CImageProcessDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return;// TODO: add draw code for native data hereMat & image = pDoc->src_image;
}

2. 将Mat转化成CImage

       Mat是表示图像数据的一个矩阵,它不能直接绘制到窗口DC,通过google,我发现atl的一个类CImage有绘制到DC的方法,所以只需要把Mat在显示之前先转化成CImage,代码如下:

void ImageUtility::MatToCImage( Mat &mat, CImage &cImage)  
{  int width    = mat.cols;  int height   = mat.rows;  int channels = mat.channels();  cImage.Destroy(); cImage.Create(width,   height,   8*channels ); uchar* ps;  uchar* pimg = (uchar*)cImage.GetBits(); int step = cImage.GetPitch();  for (int i = 0; i < height; ++i)  {  ps = (mat.ptr<uchar>(i));  for ( int j = 0; j < width; ++j )  {  if ( channels == 1 ) //gray  {  *(pimg + i*step + j) = ps[j];  }  else if ( channels == 3 ) //color  {  for (int k = 0 ; k < 3; ++k )  {  *(pimg + i*step + j*3 + k ) = ps[j*3 + k];  }             }  }     }  }

3. 将图片显示在窗口DC

Mat & image = pDoc->src_image;if (image.empty()){return;}CImage cimage;ImageUtility::MatToCImage(image,cimage);cimage.Draw(pDC->GetSafeHdc(),0,0,cimage.GetWidth(),cimage.GetHeight(),0,0,cimage.GetWidth(),cimage.GetHeight());

终于图片可以显示出来了,如下图:

                                   

 

【fit图片到窗口大小】

          从上面的结果来看,显示是显示出来了,但是效果不好,因为图片比较大,超过了窗口大小,所以在绘制时,需要做一个缩放,缩放到适合窗口显示的大小,缩放之前,需要先得到窗口大小。
 1. override CImageProcessView的OnSize

void CImageProcessView::OnSize(UINT nType, int cx, int cy)
{nWidth = cx;nHeight = cy;CView::OnSize(nType, cx, cy);// TODO: Add your message handler code here
}

 2. 将图像缩放到适合窗口显示的大小

int fixed_width = min(cimage.GetWidth(),nWidth);int fixed_height = min(cimage.GetHeight(),nHeight);double ratio_w = fixed_width / (double)cimage.GetWidth();double ratio_h = fixed_height / (double)cimage.GetHeight();double ratio = min(ratio_w,ratio_h);int show_width = (int)(ratio * cimage.GetWidth());int show_height = (int)(ratio * cimage.GetHeight());int offsetx = (nWidth - show_width) / 2;int offsety = (nHeight - show_height) / 2;::SetStretchBltMode(pDC->GetSafeHdc(),   COLORONCOLOR); cimage.StretchBlt(pDC->GetSafeHdc(),offsetx,offsety,show_width,show_height,0,0,cimage.GetWidth(),cimage.GetHeight(),SRCCOPY);

这些图片能完整显示了,而且是显示在窗口的中间,如图

                        

 

【双缓存去闪烁】

当我们resize窗口时,上面的程序会有剧烈的闪动,这谁能受得了了, 为了改进这一体验,我们使用双缓存方案。

1. override CImageProcessView的OnEraseBkgnd
    这样就不再画背景画刷到窗口DC了。

BOOL CImageProcessView::OnEraseBkgnd(CDC* pDC)
{// TODO: Add your message handler code here and/or call default//return CView::OnEraseBkgnd(pDC);return TRUE;
}

2. 加入双缓存
首先写一个双缓存类DoubleBufferSys 

#pragma once
#include <windows.h>
class DoubleBufferSys
{
public:DoubleBufferSys();~DoubleBufferSys();void Resize(int width,int height);void SetCDC(CDC * pDC);CDC& GetMemDC();void Present();
private:CDC MemDC; //首先定义一个显示设备对象  CBitmap MemBitmap;//定义一个位图对象  CDC * pDC;int width;int height;};

实现代码如下

#include "stdafx.h"
#include "DoubleBufferSys.h"
DoubleBufferSys::DoubleBufferSys()
{MemDC.CreateCompatibleDC(NULL);
}DoubleBufferSys::~DoubleBufferSys()
{MemBitmap.DeleteObject();  MemDC.DeleteDC();  
}
void DoubleBufferSys::Present()
{pDC->BitBlt(0,0,width,height,&MemDC,0,0,SRCCOPY);  
}
void DoubleBufferSys::Resize(int _width,int _height)
{if (_width <=0 || _height <=0){return;}width = _width;height = _height;MemBitmap.DeleteObject();  MemBitmap.CreateCompatibleBitmap(pDC,width,height);  CBitmap *pOldBit = MemDC.SelectObject(&MemBitmap);  MemDC.FillSolidRect(0,0,width,height,RGB(0,0,0));
}void DoubleBufferSys::SetCDC(CDC *_pDC)
{pDC = _pDC;
}CDC& DoubleBufferSys::GetMemDC()
{return MemDC;
}

然后在CImageProcessView类中定义一个双缓存系统对象DoubleBufferSys dbbufSys; 并在绘制函数中如下调用

dbbufSys.SetCDC(pDC);
dbbufSys.Resize(nWidth,nHeight);Mat & image = pDoc->src_image;
if (image.empty())
{dbbufSys.Present();return;
}.................    ::SetStretchBltMode(dbbufSys.GetMemDC(),   COLORONCOLOR); 
cimage.StretchBlt(dbbufSys.GetMemDC(),offsetx,offsety,show_width,show_height,0,0,cimage.GetWidth(),cimage.GetHeight(),SRCCOPY);dbbufSys.Present();

 这样就不会出现讨厌的闪烁了,另外,DoubleBufferSys这个类可以复用,使用时按照如下流程即可

   1. 设置CDC指针到DoubleBufferSys

   2. Resize 双缓存大小

   3. 在双缓存中的缓存中绘制

   4. 将缓存中的内容Present(也就是拷贝到)显存

 

这样,一个比较完整的利用opencv解码jpeg,并在窗口中显示的小程序就完成了,以后可以基于此实现一些数字处理的算法。 

转载于:https://www.cnblogs.com/young525/p/5873830.html

http://www.lbrq.cn/news/1558099.html

相关文章:

  • 盐城网站建设案例/如何搭建企业网站
  • 老网站做成适合手机端的网站怎么做/湖南百度推广开户
  • 口碑最好的旅游网站/百度优化推广
  • 做旅游网站的社会效益可行性/谷歌浏览器chrome官网
  • 长沙城乡建设网站首页/整合营销传播理论
  • 网站程序如何制作/seo刷排名软件
  • 网站推广做多大尺寸/成都网站推广
  • 网站编辑 seo/站长工具搜索
  • 美食鉴赏国内网站/流量平台排名
  • 太原网站推广怎么做/网址链接生成器
  • 珠海专业做网站的公司/百度主页
  • 网站推广优势/产品网络推广方案
  • 网站title在哪里/网上营销是做什么的
  • 二级网站建设方案模板/深圳aso优化
  • 深圳网站建设app开发/广西关键词优化公司
  • 用自己网站做淘宝客/百度云盘资源搜索
  • 做微网站用什么框架/网络营销自学网站
  • seo一级域名和二级域名/长沙网站优化培训
  • 做方案的网站/唐山网站建设方案优化
  • 宁波建设网站/比优化更好的词是
  • 开发帮官方网站/营销推广计划怎么写
  • 深圳龙华新区住房和建设局网站/营销推广活动策划
  • 乌鲁木齐企业网站建设/上海整站seo
  • 怎么做百度搜到的网站免费的/可以发外链的平台
  • 连锁酒店网站建设公司/国内seo做最好的公司
  • 大连网站建设1000元/公关
  • 网页设计专业设计课程/百度优化软件
  • 如何做一个个人网站/网站推广策划书范文
  • 南通企业网站/企业网站有哪些平台
  • 什么东西可以做网站/网络营销文案策划都有哪些
  • Linux中聚合链路与软件网桥配置指南
  • Java增强for循环(小白友好版)
  • Python异常、模块与包(五分钟小白从入门)
  • 软件需求管理过程详解
  • Python 数据可视化:柱状图/热力图绘制实例解析
  • Vue模板引用(Template Refs)全解析1