热门标签 | HotTags
当前位置:  开发笔记 > 程序员 > 正文

图像处理打开图片

图像世界是五彩缤纷的,首先需要介绍一下位图和调色板的概念,普通的显示器屏幕是由许许多多点构成的,我们称之为象素。显示时采用扫描的方法&#x

图像世界是五彩缤纷的,首先需要介绍一下位图和调色板的概念,普通的显示器屏幕是由许许多多点构成的,我们称之为象素。显示时采用扫描的方法:电子枪每次从左到右扫描一行,为每个象素着色,然后从上到下这样扫描若干行,就扫过了一屏。为了防止闪烁,每秒要重复上述过程几十次。例如我们常说的屏幕分辨率为640×480,刷新频率为70Hz,意思是说每行要扫描640个象素,一共有480行,每秒重复扫描屏幕70次。

  我们知道,自然界中的所有颜色都可以由红、绿、蓝(R,G,B)组合而成。有的颜色含有红色成分多一些,如深红;有的含有红色成分少一些,如浅红。针对含有红色成分的多少,可以分成0255256个等级,0级表示不含红色成分;255级表示含有100%的红色成分。同样,绿色和蓝色也被分成256级。这种分级概念称为量化。

  这样,根据红、绿、蓝各种不同的组合我们就能表示出256×256×256,约1600万种颜色。这么多颜色对于我们人眼来说已经足够丰富了。

……接下来是倒数第二行左边第一个象素,左边第二个象素……依次类推,最后得到的是最上面一行的最右一个象素。

  接下来就是打开bmp位图了,这里我选择了VC里面的单文档程序,通过打开按钮打开bmp图像。在Doc里面加载图像,在View里面显示图像,下面贴代码:

  Doc.h :

class CMyDoc : public CDocument
{
public://bpm文件的格式:1 文件头 2信息头 (1:真彩色,没有调色板;2:索引图像:有调色板);//3 数据//调色板:BITMAPFILEHEADER *m_FileHeader;//文件头BITMAPINFOHEADER *m_InfoHeader;//信息头RGBQUAD *pallete;//调色板BYTE * bmpdata; //图像数据的缓冲区
  Doc.cpp :

CMyDoc::CMyDoc()
{// TODO: add one-time construction code here//指针初始化m_FileHeader=NULL;m_InfoHeader=NULL;pallete=NULL;bmpdata=NULL;
}

void CMyDoc::OnFileOpen()
{// TODO: Add your command handler code hereCString FileName;//保存文件的文件名static char szFilter[]="Bitmap Files (*.bmp)|*.bmp|All files(*.*)|*.*||"; CFileDialog m_FileDialog(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,("Bitmap File(*.bmp)|*.bmp"),NULL);//文件对话框//加上异常处理CFile m_File;//定义文件类对象try{if(m_FileDialog.DoModal()==IDOK){FileName=m_FileDialog.GetPathName();//获取文件路径//获取文件路径,路径保存在字符串变量里// CFile m_File;//定义文件类对象m_File.Open(FileName,CFile::modeRead,NULL);//文件已打开if(m_FileHeader) delete m_FileHeader;//判断是否存在文件头 存在则删除m_FileHeader=(BITMAPFILEHEADER*)new BYTE[sizeof(BITMAPFILEHEADER)];//给文件头分配内存m_File.Read(m_FileHeader,sizeof(BITMAPFILEHEADER));//读取文件头if(m_InfoHeader) delete m_InfoHeader;//判断是否存在信息头 存在就删除m_InfoHeader=(BITMAPINFOHEADER*)new BYTE[sizeof(BITMAPINFOHEADER)];//给信息头分配内存m_File.Read(m_InfoHeader,sizeof(BITMAPINFOHEADER));//读取信息头/if(m_FileHeader->bfType!=0x4D42) //判断所打开的文件是否为bmp格式的文件{AfxMessageBox("this is not a bitmap!");m_File.Close(); //如果不是bmp格式的文件关闭文件}/if(m_InfoHeader->biBitCount==8)//8位{ if(m_InfoHeader!=NULL)//判断信息头是否为空delete [] m_InfoHeader;//删除信息头指针m_InfoHeader=(BITMAPINFOHEADER*) new BYTE [sizeof (BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]; //分配内存缓冲区m_File.Seek(-sizeof(BITMAPINFOHEADER),CFile::current);//计算当前走过的字节数 m_File.Read(m_InfoHeader,sizeof(BITMAPINFOHEADER));//读取信息头 if(pallete!=NULL)//判断调色板delete []pallete;//删除调色板指针pallete=(RGBQUAD*)new BYTE[sizeof(RGBQUAD)*256];//给调色板分配内存m_File.Read(pallete,sizeof(RGBQUAD)*256);//读取调色板数据memcpy((BYTE*)m_InfoHeader+sizeof(BITMAPINFOHEADER),pallete,sizeof(RGBQUAD)*256);//给信息头分配原来的信息头字节数和调色板的字节数int size = 0;//定义变量size用于计算图像数据大小if(bmpdata)//判读是否存在图像数据delete []bmpdata;//删除数据指针size = m_FileHeader->bfSize - m_FileHeader->bfOffBits;//图像数据的字节大小bmpdata=(BYTE*) new BYTE[size];//给数据指针分配内存m_File.Read(bmpdata,size); //读取数据}else if(m_InfoHeader->biBitCount==24)//24位真彩色图像{if(bmpdata) delete bmpdata;//判读是否存在图像数据bmpdata=(BYTE*)new BYTE[m_InfoHeader->biSizeImage];//给图像数据分配内存m_File.Read(bmpdata,m_InfoHeader->biSizeImage);//读取图像数据}m_File.Close();//文件关闭UpdateAllViews(NULL,0,NULL);//刷新}}catch (CMemoryException* e){AfxMessageBox("e->m_szMessage");e->Delete();}catch (CFileException* e){CString str;str.Format("读取数据失败的原因是:%d",e->m_cause);AfxMessageBox("str");m_File.Abort();e->Delete(); }catch (CUserException* e){CString str;str.Format("资源无法找到!");AfxMessageBox("str");e->Delete(); }
}
  View.h :

class CMyView : public CView
{
public:int Height;int Width;BYTE* m_pImgDib; //定义一个指向图像数据的指针 BITMAPINFO* m_pImgBmi; //文件头CDC *pMemDC1,*pMemDC2; //内存DCCBitmap* pOldBmp; //封装bitmap的类HBITMAP hBmp; //是bitmap的指针 ?BITMAP bmp; //定义一个BITMAP对象CPoint point; //是一个结构体,定义了逻辑位图的一些属性
  View.cpp :

CMyView::CMyView()
{// TODO: add construction code here//构造函数中初始化m_pImgDib=NULL;m_pImgBmi=NULL;pMemDC1=NULL;pMemDC2=NULL;pOldBmp=NULL;hBmp=NULL;Height=600;Width=600;point.x=0;point.y=0;
}
CMyView::~CMyView()
{//析构函数是最后执行的 在此函数里删除指针if(m_pImgDib) delete m_pImgDib;if(m_pImgBmi) delete m_pImgBmi;if(pMemDC1) delete pMemDC1;if(pMemDC2) delete pMemDC2;if(pOldBmp) delete pOldBmp;
}

void CMyView::OnDraw(CDC* pDC)
{CMyDoc* pDoc &#61; GetDocument();//创建文档类的指针if(pDoc->m_InfoHeader)//判断信息头是否存在m_pImgBmi&#61;(BITMAPINFO*)(pDoc->m_InfoHeader);//赋值强制类型转换if(pDoc->bmpdata)//判断图像信息是否存在m_pImgDib&#61;pDoc->bmpdata;ASSERT_VALID(pDoc);// TODO: add draw code for native data hereif(m_pImgBmi&&m_pImgDib){if(pMemDC1&#61;&#61;NULL) //内存DC1{pMemDC1&#61;new CDC; //CDC包含传输数据的设备和成员函数pMemDC1->CreateCompatibleDC(pDC);//使得pMemDC和pDC相兼容}CRect rc; //存储矩形的左上角和右下角的坐标GetClientRect(&rc); //得到客户区的屏幕尺寸//if(pOldBmp!&#61;NULL)//判断原图像数据是否存在pMemDC1->SelectObject(pOldBmp);//将图像数据对象选入内存设备环境中if(hBmp!&#61;NULL)DeleteObject(hBmp);hBmp&#61;CreateDIBitmap(pDC->GetSafeHdc(), //CreateDIBitmap返回值是句柄(BITMAPINFOHEADER*)m_pImgBmi,CBM_INIT,m_pImgDib,m_pImgBmi,DIB_RGB_COLORS);if(hBmp&#61;&#61;NULL)return ;CBitmap *pBmp&#61;CBitmap::FromHandle(hBmp); //得到位图的句柄pOldBmp&#61;pMemDC1->SelectObject(pBmp); //把位图选中到画布一上pBmp->GetBitmap(&bmp);if(hBmp&#61;&#61;NULL)return;float wid,hei;wid&#61;(float)(rc.right-rc.left);//bm.bmWidth://*2;hei&#61;(float)(rc.bottom-rc.top);//bm.bmHeight://*2;int x,y;float hrate,wrate,rate;//保持图像输出比例hrate&#61;(float)hei/(float)bmp.bmHeight;wrate&#61;(float)wid/(float)bmp.bmPlanes;if(hrate<1.0 && wrate<1.0){rate&#61;(hrate1.0 && wrate>1.0){rate&#61;(hrate1.0 && wrate<1.0){rate&#61;wrate;}else{rate&#61;hrate;}x&#61;(int)abs((int)(wid-bmp.bmWidth*rate)/2);y&#61;(int)abs((int)(hei-bmp.bmHeight*rate)/2);//if(pMemDC2&#61;&#61;NULL) //第二个内存DC&#xff08;直接与pDC交换数据&#xff09;{pMemDC2&#61;new CDC;pMemDC2->CreateCompatibleDC(pMemDC1);//pMemDC1相匹配 创建与屏幕兼容pMemDC1}CBitmap myBmp;myBmp.CreateCompatibleBitmap(pDC,rc.right,rc.bottom);//创建与指定的设备环境相关的设备兼容的位图CBitmap* pmyBmp&#61;pMemDC2->SelectObject(&myBmp);//把位图选中到画布中pMemDC2->SetStretchBltMode(HALFTONE);// pMemDC2->FillSolidRect(&rc,RGB(20,20,20));pMemDC2->StretchBlt(0,0,bmp.bmWidth,bmp.bmHeight,pMemDC1,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);//将设备环境1放到设备环境2上// pMemDC2->FillSolidRect(&rc,RGB(20,20,20));pDC->SetStretchBltMode(HALFTONE);pDC->StretchBlt(300,50,bmp.bmWidth,bmp.bmHeight,pMemDC2,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);//将设备环境2放到显示器中}// TODO: add draw code for native data here
}
  

  编译运行&#xff0c;结果如图&#xff1a;

 

里面的文字描述是借鉴于其他的图像处理资料&#xff0c;代码是亲自编写调试过的&#xff0c;所以才贴出来分享&#xff01;


推荐阅读
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • windows便签快捷键_用了windows十几年,没想到竟然这么好用!隐藏的功能你知道吗?
    本文介绍了使用windows操作系统时的一些隐藏功能,包括便签快捷键、截图功能等。同时探讨了windows和macOS操作系统之间的优劣比较,以及人们对于这两个系统的不同看法。 ... [详细]
  • 家装日记六:家具采购和瓷砖选择
    本文记录了作者进行家装的过程,包括家具采购和瓷砖选择。作者介绍了自己家的装修风格以及选择烤漆家具和红白系列的原因。作者还提到了装修风格以简约为主,不可以太花哨的要求。最后,作者提到了价格较贵的问题。 ... [详细]
  • 本文讨论了当某位排位靠前的涉众提供了一张精美的界面图片时,是否可以将其作为设计约束。同时还探讨了高质量素材和愿景之间的关系,以及老大自身的软件方法和建模技能。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了一些好用的搜索引擎的替代品,包括网盘搜索工具、百度网盘搜索引擎等。同时还介绍了一些笑话大全、GIF笑话图片、动态图等资源的搜索引擎。此外,还推荐了一些迅雷快传搜索和360云盘资源搜索的网盘搜索引擎。 ... [详细]
  • 【MicroServices】【Arduino】装修甲醛检测,ArduinoDart甲醛、PM2.5、温湿度、光照传感器等,数据记录于SD卡,Python数据显示,UI5前台,微服务后台……
    这篇文章介绍了一个基于Arduino的装修甲醛检测项目,使用了ArduinoDart甲醛、PM2.5、温湿度、光照传感器等硬件,并将数据记录于SD卡,使用Python进行数据显示,使用UI5进行前台设计,使用微服务进行后台开发。该项目还在不断更新中,有兴趣的可以关注作者的博客和GitHub。 ... [详细]
  • 本文研究了使用条件对抗网络进行图片到图片翻译的方法,并提出了一种通用的解决方案。通过学习输入图像到输出图像的映射和训练相应的损失函数,我们可以解决需要不同损失函数公式的问题。实验证明该方法在合成图片、重构目标和给图片着色等多个问题上都很有效。这项工作的重要发现是不再需要人为构建映射函数和损失函数,同时能够得出合理的结果。本文的研究对于图片处理、计算机图片合成和计算机视觉等领域具有重要意义。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • 计算成像的原理与应用研究
    本文探讨了计算成像的原理与应用研究。首先介绍了小孔成像实验和软件方面的相关内容。随后从傅里叶光学的角度简单谈了成像的过程。成像是观测样品分布的一种方法,通过成像系统接收光的强度来呈现图像。视网膜作为接收端接收到的图像实际上是由像元组成的矩阵,每个元素代表相应位置像元接收光的强度。大脑通过对图像的分析,得出一系列信息,如识别物体、判断距离等。计算成像是一种采集记录系统,通过处理数据得到样品分布与像的对应关系,用于后续问题的分析。 ... [详细]
  • HTML学习02 图像标签的使用和属性
    本文介绍了HTML中图像标签的使用和属性,包括定义图像、定义图像地图、使用源属性和替换文本属性。同时提供了相关实例和注意事项,帮助读者更好地理解和应用图像标签。 ... [详细]
  • 图片复制到服务器 方向变了_双服务器热备更新配置文件步骤问题及解决方法
    本文介绍了在将图片复制到服务器并进行方向变换的过程中,双服务器热备更新配置文件所出现的问题及解决方法。通过停止所有服务、更新配置、重启服务等操作,可以避免数据中断和操作不规范导致的问题。同时还提到了注意事项,如Avimet版本的差异以及配置文件和批处理文件的存放路径等。通过严格执行切换步骤,可以成功进行更新操作。 ... [详细]
author-avatar
不要芹菜味
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有