计算机图形学 实验二要点
计算机图形学实验二:直线的生成算法的实现

实验二: 直线的生成算法的实现班级 08信计2班学号 20080502055 姓名分数一、实验目的和要求:1.理解直线生成的原理;2.掌握几种常用的直线生成算法;3.利用C实现直线生成的DDA算法。
二、实验内容:1.了解直线的生成原理2、掌握几种基本的直线生成算法: DDA画线法、中点画线法、Bresenham画线法。
3、仿照教材关于直线生成的DDA算法, 编译程序。
4.调试、编译、运行程序。
三、实验过程及结果分析1.直线DDA算法:算法原理:已知过端点P0(x0,y0), P1(x1,y1)的直线段L(P0,P1), 斜率为k=(y1-y0)/(x1-x0), 画线过程从x的左端点x0开始, 向x右端点步进, 步长为1个像素, 计算相应的y坐标为y=kx+B。
计算y i+1 = kx i+B=kx i +B+kx=y i +kx当x=1,yi+1=yi+k, 即当x每递增1, y递增k。
由计算过程可知, y与k可能为浮点数, 需要取y整数, 源程序中round(y)=(int)(y+0.5)表示y四舍五入所得的整数值。
(1)程序代码:#include"stdio.h"#include"graphics.h"void linedda(int x0,int y0,int x1,int y1,int color){int x,dy,dx,y;float m;dx=x1-x0;dy=y1-y0;m=dy/dx;y=y0;for(x=x0;x<=x1;x++){putpixel(x,(int)(y+0.5),color);y+=m;setbkcolor(7);}}main(){int a,b,c,d,e;int graphdriver=DETECT;int graphmode=0;initgraph(&graphdriver,&graphmode,"");a=100;b=100;c=200;d=300;e=5;linedda(a,b,c,d,e);getch();closegraph();}运行结果:2.中点画线算法:假定所画直线的斜率为k∈[0,1], 如果在x方向上增量为1, 则y方向上的增量只能在0~1之间。
计算机图形学实验报告 (2)

实验一Window图形编程根底一、实验类型:验证型实验二、实验目的1、熟练使用实验主要开发平台VC6.0;2、掌握如何在编译平台下编辑、编译、连接和运行一个简单的Windows图形应用程序;3、掌握Window图形编程的根本方法;4、学会使用根本绘图函数和Window GDI对象;三、实验内容创立基于MFC的Single Document应用程序〔Win32应用程序也可,同学们可根据自己的喜好决定〕,程序可以实现以下要求:1、用户可以通过菜单项选择择绘图颜色;2、用户点击菜单项选择择绘图形状时,能在视图中绘制指定形状的图形;四、实验要求与指导1、建立名为“颜色〞的菜单,该菜单下有四个菜单项:红、绿、蓝、黄。
用户通过点击不同的菜单项,可以选择不同的颜色进行绘图。
2、建立名为“绘图〞的菜单,该菜单下有三个菜单项:直线、曲线、矩形其中“曲线〞项有级联菜单,包括:圆、椭圆。
3、用户通过点击“绘图〞中不同的菜单项,弹出对话框,让用户输入绘图位置,在指定位置进行绘图。
五、实验结果:六、实验主要代码1、画直线:CClientDC *m_pDC;再在OnDraw函数里给变量初始化m_pDC=new CClientDC(this);在OnDraw函数中添加:m_pDC=new CClientDC(this);m_pDC->MoveTo(10,10);m_pDC->LineTo(100,100);m_pDC->SetPixel(100,200,RGB(0,0,0));m_pDC->TextOut(100,100);2、画圆:void CMyCG::LineDDA2(int xa, int ya, int xb, int yb, CDC *pDC){int dx = xb - xa;int dy = yb - ya;int Steps, k;float xIncrement,yIncrement;float x = xa,y= ya;if(abs(dx)>abs(dy))Steps = abs(dx);elseSteps = abs(dy);xIncrement = dx/(float)Steps;yIncrement = dy/(float)Steps;pDC->SetPixel(ROUND(x),ROUND(y),RGB(0,0,0));for(k=0;k<Steps;k++){x +=xIncrement;y +=yIncrement;sleep(10);pDC->SetPixel(ROUND(x),ROUND(y),RGB(0,0,0));}3、画矩形void CRectangleDlg::OnLButtonDown(UINT nFlags, CPoint point){lButtonDownNotUp = TRUE;RECT rect;m_showRectangle. GetClientRect( &rect ) ;if( (point. x<rect. right) && (point. x>rect. left) && (point. y<rect. bottom) && (point. y>rect. top) ){regionLeftTopTemp = point;}CDialog::OnLButtonDown(nFlags, point);}void CRectangleDlg::OnMouseMove(UINT nFlags, CPoint point){RECT rect;m_showRectangle. GetClientRect( &rect );if( ( point.x<rect.right ) && ( point.x>rect.left ) && ( point.y<rect.bottom ) && ( point.y>rect.top ) ){if( ( lButtonDownNotUp == TRUE ){regionRightBottomTemp = point;CDC * pDC = m_showRectangle. GetWindowDC ();pDC -> Rectangle( CRect( regionLeftTopTemp, regionRightBottomTemp ) ) ;}}CDialog::OnMouseMove(nFlags, point);}void CRectangleDlg::OnLButtonUp(UINT nFlags, CPoint point){lButtonDownNotUp=FALSE;CDialog::OnLButtonUp(nFlags, point);}实验二根本图形生成算法一、实验类型:验证型实验二、实验目的1、掌握DDA、Bresenham直线生成算法;2、掌握Bresenham或中点圆生成算法;3、掌握Bresenham或中点椭圆生成算法;三、实验内容1、实现DDA、Bresenham直线生成算法;2、实现Bresenham画圆法或中点画圆法;3、实现Bresenham或中点法椭圆生成算法;4、利用1、2、3实现的直线、圆、椭圆图形生成函数进行图形绘制;四、实验要求与指导1、按照实验指导书1.6节创立一个基于MFC的Single Document应用程序。
计算机图形学实验二 直线的生成算法的实现

实验二直线的生成算法的实现班级 08信计二班学号 20080502086 姓名分数一、实验目的和要求:1、理解直线生成的基本原理2、熟悉直线的生成算法,掌握直线的绘制3、实现直线生成的DDA 中点画法 Bresenham算法4、了解Visual C++等编程环境中常用控件命令与绘图函数,初步掌握在试验设计集成下进行图形处理程序的设计方法二、实验内容:1、了解直线生成的原理直线DDA算法,中点画线算法,Bresenham画线算法2、编程实现DDA算法、Bresenham算法、中点画法绘制直线段三、实验结果分析1.DDA算法// 程序名称:基于 DDA 算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 四舍五入int Round(float x){return (int)(x < 0 ? x - 0.5 : x + 0.5);}// 使用 DDA 算法画任意斜率的直线(包括起始点,不包括终止点)void Line_DDA(int x1, int y1, int x2, int y2, int color){float x, y; // 当前坐标点float cx, cy; // x、y 方向上的增量int steps = abs(x2 - x1) > abs(y2 - y1) ? abs(x2 - x1) : abs(y2 - y1);x = (float)x1;y = (float)y1;cx = (float)(x2 - x1) / steps;cy = (float)(y2 - y1) / steps;for(int i = 0; i < steps; i++){putpixel(Round(x), Round(y), color); // 在坐标 (x, y) 处画一个 color 颜色的点x += cx;y += cy;}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_DDA(100, 1, 1, 478, GREEN);Line_DDA(1, 478, 638, 1, GREEN);// 按任意键退出getch();closegraph();}2.中点算法// 程序名称:基于中点算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 使用中点算法画任意斜率的直线(包括起始点,不包括终止点)void Line_Midpoint(int x1, int y1, int x2, int y2, int color){int x = x1, y = y1;int a = y1 - y2, b = x2 - x1;int cx = (b >= 0 ? 1 : (b = -b, -1));int cy = (a <= 0 ? 1 : (a = -a, -1));putpixel(x, y, color);int d, d1, d2;if (-a <= b) // 斜率绝对值 <= 1{d = 2 * a + b;d1 = 2 * a;d2 = 2 * (a + b);while(x != x2){if (d < 0)y += cy, d += d2;elsed += d1;x += cx;putpixel(x, y, color);}}else // 斜率绝对值 > 1{d = 2 * b + a;d1 = 2 * b;d2 = 2 * (a + b);while(y != y2){if(d < 0)d += d1;elsex += cx, d += d2;y += cy;putpixel(x, y, color);}}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_Midpoint(100, 1, 1, 478,YELLOW);Line_Midpoint(1, 478, 638, 1, YELLOW);// 按任意键退出getch();closegraph();}3. Bresenham 算法// 程序名称:基于 Bresenham 算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 使用 Bresenham 算法画任意斜率的直线(包括起始点,不包括终止点)void Line_Bresenham(int x1, int y1, int x2, int y2, int color){int x = x1;int y = y1;int dx = abs(x2 - x1);int dy = abs(y2 - y1);int s1 = x2 > x1 ? 1 : -1;int s2 = y2 > y1 ? 1 : -1;bool interchange = false; // 默认不互换 dx、dyif (dy > dx) // 当斜率大于 1 时,dx、dy 互换{int temp = dx;dx = dy;dy = temp;interchange = true;}int p = 2 * dy - dx;for(int i = 0; i < dx; i++){putpixel(x, y, color);if (p >= 0){if (!interchange) // 当斜率 < 1 时,选取上下象素点y += s2;else // 当斜率 > 1 时,选取左右象素点x += s1;p -= 2 * dx;}if (!interchange)x += s1; // 当斜率 < 1 时,选取 x 为步长elsey += s2; // 当斜率 > 1 时,选取 y 为步长p += 2 * dy;}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_Bresenham(100, 1, 1, 478, RED);Line_Bresenham(1, 478, 638, 1, RED);// 按任意键退出getch();closegraph();}实验结果分析三种算法运算结果比较:像素逼近效果由好到差依次为:B算法、DDA算法、中点算法执行速度由快到慢依次为:中点算法、DDA算法、B算法。
实验二:图形填充算法实验报告

《计算机图形学》实验报告(实验二:图形填充算法)一、实验目的及要求用两种方法做图形的填充算法!二、理论基础1.边填充算法对于每一条扫描线和每条多边形的交点(x1,y1),将该扫描线上的交点右方的所有像素取补。
2.种子填充算法利用栈来实现种子填充算法。
种子像素入栈,当栈非空时重复执行如下步骤:将栈顶像素出栈,将出栈像素置成多边形色,按左,上,右,下顺序检查与出栈像素相邻的四个像素,若其中某个像素不再边界且未置成多边形,则把该像素入栈!三、算法设计与分析1、边填充算法void CEdge_mark_fillView::OnDraw(CDC* pDC){CEdge_mark_fillDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);int d[500][500]={0};int inside;int x,y;Bresenham(80,101,100,400,d);Bresenham(100,300,290,400,d);Bresenham(292,400,382,50,d);Bresenham(380,50,202,150,d);Bresenham(200,150,82,101,d);for(y=0;y<500;y++){inside=0;for(x=0;x<500;x++){if(d[x][y]==1)if(d[x+1][y]!=1){inside=!(inside);}if(inside!=0)pDC->SetPixel(x,y,12);}}}2、种子填充int x=299,y=51;COLORREF oldcolor;COLORREF newcolor;oldcolor=RGB(256,256,256);newcolor=RGB(123,123,123);pDC->MoveTo (40,40);pDC->LineTo (80,40);pDC->LineTo (70,80);pDC->LineTo (40,40);FloodFill(51,51,RGB(255,255,255),RGB(0,0,255));pDC->LineTo (40,40);void CMyView::FloodFill(int x,int y,COLORREF oldcolor,COLORREF newcolor) {CDC* pDC;pDC=GetDC();if(pDC->GetPixel(x,y)==oldcolor){pDC->SetPixel(x,y,newcolor);FloodFill(x,y-1,oldcolor,newcolor);FloodFill(x,y+1,oldcolor,newcolor);FloodFill(x-1,y,oldcolor,newcolor);FloodFill(x+1,y,oldcolor,newcolor);}四、程序调试及结果的分析1、2、四、实验心得及建议由于很多不会,所以这次没能按时当堂完成,下来花了不少时间才弄出来,第二种尤其比较麻烦,在同学的帮助下才做出来了。
计算机图形学_实验2_二维图形绘制

深圳大学实验报告课程名称:计算图形学实验名称:二维图形绘制学院:计算机与软件学院专业:计算机科学与技术报告人:学号:班级:同组人:无指导教师:周虹实验时间:2014/10/31实验报告提交时间:2014/11/3教务处制一.实验目的1、能正确使用OpenGL图元产生图画,并且学会使用多种生成图案的方式。
2、能正确设置图元属性,得到不同的绘制效果。
二.实验步骤1、用三角形模式画有颜色填充的太阳,圆心为(-0.5,0.7)2、直线模式,以-0.5,0.7为圆心画一些列直线作为太阳光3、用三角形画树,多边形画树干4、直线模式,以-0.5,0.7为圆心画一小花点缀树5、以三角形模式画一个小山坡,用天蓝色填充6、直线模式,以-0.5,0.7为圆心,以不同大小的直线画一系列小花点缀小山坡7、以不同大小的点形成双色围栏8、用不同的多边形模式画小树,用多边形模式画树干,并染上特别的颜色9、用虚线画零星的小草三.实验结果1、用三角形模式画有颜色填充的太阳,圆心为(-0.5,0.7)2、直线模式,以-0.5,0.7为圆心画一些列直线作为太阳光3、用三角形画树,多边形画树干4、直线模式,以-0.5,0.7为圆心画一小花点缀树5、以三角形模式画一个小山坡,用天蓝色填充6、直线模式,以-0.5,0.7为圆心,以不同大小的直线画一系列小花点缀小山坡7、以不同大小的点形成双色围栏8、用不同的多边形模式画小树,用多边形模式画树干,并染上特别的颜色9、用虚线画零星的小草四.实验心得通过这次实验,我比较深入地理解了二维图形的绘制过程和不同图元相关属性的设置,并学会运用不同的图元组合得到自己想要的画。
本次实验收获良多,主要体现在以下方面:作图时要善于运用函数。
例如在本次实验中涉及到画圆,可是opengl中并没有提供画圆的工具,这时函数就显得尤为重要了。
可是,有了函数还不够,得到函数后要根据自己要的属性选择适当的作图模式。
例如本次画太阳的过程中,一开始我选用GL_LINES的模式,当n趋向无穷大时得到一个圆,可是问题是这个圆是空心的,无法填充红色。
计算机图形学实验报告_2

计算机图形学实验报告学号:********姓名:班级:计算机 2班指导老师:***2010.6.19实验一、Windows 图形程序设计基础1、实验目的1)学习理解Win32 应用程序设计的基本知识(SDK 编程);2)掌握Win32 应用程序的基本结构(消息循环与消息处理等); 3)学习使用VC++编写Win32 Application 的方法。
4)学习MFC 类库的概念与结构;5)学习使用VC++编写Win32 应用的方法(单文档、多文档、对话框);6)学习使用MFC 的图形编程。
2、实验内容1)使用WindowsAPI 编写一个简单的Win32 程序,调用绘图API 函数绘制若干图形。
(可选任务)2 )使用MFC AppWizard 建立一个SDI 程序,窗口内显示"Hello,Thisis my first SDI Application"。
(必选任务)3)利用MFC AppWizard(exe)建立一个SDI 程序,在文档视口内绘制基本图形(直线、圆、椭圆、矩形、多边形、曲线、圆弧、椭圆弧、填充、文字等),练习图形属性的编程(修改线型、线宽、颜色、填充样式、文字样式等)。
定义图形数据结构Point\Line\Circle 等保存一些简单图形数据(在文档类中),并在视图类OnDraw 中绘制。
3、实验过程1)使用MFC AppWizard(exe)建立一个SDI 程序,选择单文档;2)在View类的OnDraw()函数中添加图形绘制代码,说出字符串“Hello,Thisis my first SDI Application”,另外实现各种颜色、各种边框的线、圆、方形、多边形以及圆弧的绘制;3)在类视图中添加图形数据point_pp,pp_circle的类,保存简单图形数据,通过在OnDraw()函数中调用,实现线、圆的绘制。
4、实验结果正确地在指定位置显示了"Hello,This is my first SDI Application"字符串,成功绘制了圆,椭圆,方形,多边形以及曲线圆弧、椭圆弧,同时按指定属性改绘了圆、方形和直线。
图形学实验报告

图形学实验报告图形学实验报告概述:在本次图形学实验中,我们将探索和学习计算机图形学的基本概念和技术。
通过实验,我们深入了解了图形学的原理和应用,以及如何使用计算机生成和处理图像。
实验一:像素和颜色在这个实验中,我们学习了图像是由像素组成的,每个像素都有自己的颜色值。
我们使用了Python编程语言和PIL库来创建一个简单的图像,并设置了不同的像素颜色。
通过改变像素的颜色值,我们可以创建出各种各样的图像效果。
实验二:坐标系统和变换在这个实验中,我们学习了坐标系统和图形变换。
我们使用OpenGL库来创建一个简单的二维图形,并通过平移、旋转和缩放等变换操作来改变图形的位置和形状。
这些变换操作使我们能够在屏幕上创建出各种不同的图案和效果。
实验三:线段和多边形在这个实验中,我们学习了如何使用线段和多边形来绘制图形。
我们使用了Bresenham算法来绘制直线,并学习了如何使用多边形填充算法来填充图形。
通过这些技术,我们可以创建出更加复杂和精细的图像。
实验四:光照和阴影在这个实验中,我们学习了光照和阴影的原理和应用。
我们使用了光照模型来模拟光线的传播和反射,以及计算物体的明暗效果。
通过调整光照参数和材质属性,我们可以创建出逼真的光照和阴影效果。
实验五:纹理映射和渲染在这个实验中,我们学习了纹理映射和渲染的概念和技术。
我们使用了纹理映射来将图像贴到三维物体表面,以增加物体的细节和真实感。
通过渲染技术,我们可以模拟光线的折射和反射,以及创建出逼真的材质效果。
实验六:三维建模和动画在这个实验中,我们学习了三维建模和动画的基本原理和方法。
我们使用了三维建模工具来创建三维模型,并学习了如何使用关键帧动画来实现物体的运动和变形。
通过这些技术,我们可以创建出逼真的三维场景和动画效果。
总结:通过这次图形学实验,我们深入了解了计算机图形学的原理和应用。
我们学习了像素和颜色、坐标系统和变换、线段和多边形、光照和阴影、纹理映射和渲染,以及三维建模和动画等技术。
图形学实验报告2

return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CTransformView drawing
三、实验要求:
实验前须规划程序界面和按钮的相关事件的编写代码。实验时进行代码的调试。
四、实验代码
1,图形的变换
// TransformView.cpp : implementation of the CTransformView class
//
#include "stdafx.h"
#include "Transform.h"
#include "TransformDoc.h"
#include "TransformView.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
for(i=1; i<3; i++)
{
Pt[i].x *= 0.5;
Pt[i].y *= 0.5;
}
Pt[0] = TmpPt;
Pt[1] = Pt[1] + Pt[0];
Pt[2] = Pt[2] + Pt[0];
break;
case 0X58://X的ASCII码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机科学系实验报告课程名称计算机图形学班级12网络2实验名称VC存取BMP图像及其几何变换教导教师吴志攀姓名李文森学号1214080613213 日期2014 .11.21一、实验目的1. 掌握VC中BMP图像的存取方法;2. 掌握BMP图像平移、旋转、变比等几何变换。
二、实验设备与环境TC2.0,Windows XP三、实验内容、程序清单及运行结果1.打开VC++ 6.0,选择File|New进入界面。
在Projects中选择MFC AppWinzard(exe),在Project name中输入项目名称,本例为ReadBMP,在Location中输入项目要保存的文件夹。
点击“OK”进入下一步。
如下图2-1所示。
图2-12.选择文档类型。
在本例中使用的是单文档视图结构,所以这里选择Singledocument。
其余部分设置使用VC++ 6.0的默认设置,点击“Finish”完成项目创建。
如下图2-2所示:图2-23.为了将BMP中的数据读入到内存中,在项目中导入专门处理BMP文件头和数据的文件:DIBAPI.H和DIBAPI.CPP,在其中实现对BMP文件的大部分处理。
在工作区“FileView”选项卡的“Header Files”中点右键,在“添加文件到目录”添加“DIBAPI.H”文件。
如下图2-3所示:图2-3在工作区“FileView”选项卡的“Source Files”中点右键,在“添加文件到目录”添加“DIBAPI.CPP”文件。
并在“ReadBMPDoc.h”添加头文件"dibapi.h",如下所示:#include "dibapi.h"4.在CReadBMPDoc类中添加保护成员变量CPalette* m_palDIB,HDIB m_hDIB和CSize m_sizeDoc。
m_hDIB用于保存当前BMP图像句柄,m_palDIB用于指向BMP图像对应的调色板。
protected:HDIB m_hDIB;CPalette* m_palDIB;CSize m_sizeDoc;5.为了取得保存在当前文档中的HDIB和Palette数据,在“ReadBMPDoc.h”的CReadBMPDoc类中添加方法:GetHDIB,GetDocPalette和GDocSize。
如下所示:// Attributespublic:HDIB GetHDIB() const{ return m_hDIB; }CPalette* GetDocPalette() const{ return m_palDIB; }CSize GetDocSize() const{ return m_sizeDoc; }在CReadBMPDoc.cpp的构造函数中初始化:// 初始化变量m_hDIB = NULL;m_palDIB = NULL;m_sizeDoc = CSize(1,1);6.响应类CReadBMPDoc OnOpenDocument事件,以实现打开文件的操作。
从View|ClassWizard进入MFC ClassWizard界面,在Message Maps选项中完成消息映射。
下图2-4所示:图2-4在BOOL CReadBMPDoc::OnOpenDocument(LPCTSTR lpszPathName)函数中添加如下代码://if (!CDocument::OnOpenDocument(lpszPathName))//return FALSE;// TODO: Add your specialized creation code here//return TRUE;CFile file;CFileException fe;// 打开文件if (!file.Open(lpszPathName, CFile::modeRead | CFile::shareDenyWrite, &fe)){// 失败ReportSaveLoadException(lpszPathName, &fe,FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);// 返回FALSEreturn FALSE;}DeleteContents();// 更改光标形状BeginWaitCursor();// 尝试调用ReadDIBFile()读取图像TRY{m_hDIB = ::ReadDIBFile(file);}CA TCH (CFileException, eLoad){// 读取失败file.Abort();// 恢复光标形状EndWaitCursor();// 报告失败ReportSaveLoadException(lpszPathName, eLoad,FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);// 设置DIB为空m_hDIB = NULL;// 返回FALSEreturn FALSE;}END_CATCH// 初始化DIBInitDIBData();// 恢复光标形状EndWaitCursor();// 判断读取文件是否成功if (m_hDIB == NULL){// 失败,可能非BMP格式CString strMsg;strMsg = "读取图像时出错!可能是不支持该类型的图像文件!";// 提示出错MessageBox(NULL, strMsg, "系统提示", MB_ICONINFORMA TION | MB_OK);// 返回FALSEreturn FALSE;}// 设置文件名称SetPathName(lpszPathName);// 初始化胀标记为FALSESetModifiedFlag(FALSE);// 返回TRUEreturn TRUE;并在ReadBMPDoc.cpp添加Public成员函数InitDIBData,并添加如下程序:void CReadBMPDoc::InitDIBData(){// 初始化DIB对象// 判断调色板是否为空if (m_palDIB != NULL){// 删除调色板对象delete m_palDIB;// 重置调色板为空m_palDIB = NULL;}// 如果DIB对象为空,直接返回if (m_hDIB == NULL){// 返回return;}LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);// 判断图像是否过大if (::DIBWidth(lpDIB) > INT_MAX ||::DIBHeight(lpDIB) > INT_MAX){::GlobalUnlock((HGLOBAL) m_hDIB);// 释放DIB对象::GlobalFree((HGLOBAL) m_hDIB);// 设置DIB为空m_hDIB = NULL;CString strMsg;strMsg = "BMP图像太大!";// 提示用户MessageBox(NULL, strMsg, "系统提示", MB_ICONINFORMA TION | MB_OK);// 返回return;}// 设置文档大小m_sizeDoc = CSize((int) ::DIBWidth(lpDIB), (int) ::DIBHeight(lpDIB));::GlobalUnlock((HGLOBAL) m_hDIB);// 创建新调色板m_palDIB = new CPalette;// 判断是否创建成功if (m_palDIB == NULL){// 失败,可能是内存不足::GlobalFree((HGLOBAL) m_hDIB);// 设置DIB对象为空m_hDIB = NULL;// 返回return;}// 调用CreateDIBPalette来创建调色板if (::CreateDIBPalette(m_hDIB, m_palDIB) == NULL){// 返回空,可能该DIB对象没有调色板// 删除delete m_palDIB;// 设置为空m_palDIB = NULL;// 返回return;}}// 调用CreateDIBPalette来创建调色板if (::CreateDIBPalette(m_hDIB, m_palDIB) == NULL){// 返回空,可能该DIB对象没有调色板// 删除delete m_palDIB;// 设置为空m_palDIB = NULL;// 返回return;}7.完成图片的打开操作之后,图片的数据就已经被保存在程序中,为了将图片显示出来还需要响应类CReadBMPView的OnDraw事件,在其中完成图像显示。
void CReadBMPView::OnDraw(CDC* pDC){//CReadBMPDoc* pDoc = GetDocument();//ASSERT_V ALID(pDoc);// TODO: add draw code for native data here// 显示等待光标BeginWaitCursor();// 获取文档CReadBMPDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);// 获取DIBHDIB hDIB = pDoc->GetHDIB();// 判断DIB是否为空if (hDIB != NULL){LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);// 获取DIB宽度int cxDIB = (int) ::DIBWidth(lpDIB);// 获取DIB高度int cyDIB = (int) ::DIBHeight(lpDIB);::GlobalUnlock((HGLOBAL) hDIB);CRect rcDIB;rcDIB.top = rcDIB.left = 0;rcDIB.right = cxDIB;rcDIB.bottom = cyDIB;CRect rcDest;// 判断是否是打印if (pDC->IsPrinting()){// 是打印,计算输出图像的位置和大小,以便符合页面// 获取打印页面的水平宽度(象素)int cxPage = pDC->GetDeviceCaps(HORZRES);// 获取打印页面的垂直高度(象素)int cyPage = pDC->GetDeviceCaps(VERTRES);// 获取打印机每英寸象素数int cxInch = pDC->GetDeviceCaps(LOGPIXELSX);int cyInch = pDC->GetDeviceCaps(LOGPIXELSY);// 计算打印图像大小(缩放,根据页面宽度调整图像大小)rcDest.top = rcDest.left = 0;rcDest.bottom = (int)(((double)cyDIB * cxPage * cyInch)/ ((double)cxDIB * cxInch));rcDest.right = cxPage;// 计算打印图像位置(垂直居中)int temp = cyPage - (rcDest.bottom - rcDest.top);rcDest.bottom += temp/2;rcDest.top += temp/2;}else// 非打印{// 不必缩放图像rcDest = rcDIB;}// 输出DIB::PaintDIB(pDC->m_hDC, &rcDest, pDoc->GetHDIB(),&rcDIB, pDoc->GetDocPalette());}// 恢复正常光标EndWaitCursor();}8.编译、调试并运行程序,自此一个用于打开BMP图像的单文档视图结构的程序就完成了。