VSC++学习3BMP图像文件的特效显示.docx

上传人:b****8 文档编号:10835095 上传时间:2023-02-23 格式:DOCX 页数:12 大小:18.83KB
下载 相关 举报
VSC++学习3BMP图像文件的特效显示.docx_第1页
第1页 / 共12页
VSC++学习3BMP图像文件的特效显示.docx_第2页
第2页 / 共12页
VSC++学习3BMP图像文件的特效显示.docx_第3页
第3页 / 共12页
VSC++学习3BMP图像文件的特效显示.docx_第4页
第4页 / 共12页
VSC++学习3BMP图像文件的特效显示.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

VSC++学习3BMP图像文件的特效显示.docx

《VSC++学习3BMP图像文件的特效显示.docx》由会员分享,可在线阅读,更多相关《VSC++学习3BMP图像文件的特效显示.docx(12页珍藏版)》请在冰豆网上搜索。

VSC++学习3BMP图像文件的特效显示.docx

VSC++学习3BMP图像文件的特效显示

VS2010C++学习(3):

BMP图像文件的特效显示

学习VC++编制的BMP图像文件的特效显示程序.。

一、主要内容:

1.面向对象的DIB的读写及访问,ImgCenterDib类;

2.特效显示类,SpecialEffectShow类;

3.图像的扫描显示;

4.图像的滑动显示;

5.图像的渐进显示;

6.图像的马赛克显示;

7.垂直对接;VerticalButt

8.压缩反转;CompressInvert

9.中心闭幕;CenterFallCurtain

10.中心放大;CenterEnlarge

11.交叉竖条;CrossBars

12.水平拉幕;PullCurtain

13.随机拉丝;RandomDraw

14.对角闭幕;DiagonalClose

15.垂直百叶;VerticalBlinds

16.水平拉入;PullScroll

二、设计实现:

1.面向对象的DIB的读写及访问,ImgCenterDib类;

面向对象的方式实现图像的可视化编程,声明的类叫ImgCenterDib;里面封装了DIB位图处理所需要的基本的成员变量和成员函数。

1).ImgCenterDib类的定义

ImgCenterDib类的定义在头文件“ImageCenterDib.h”中。

classImgCenterDib

{

public:

//图像数据指针

unsignedchar*m_pImgData

//图像颜色表指针

LPRGBQUADm_lpColorTable;

//每像素占的位数

intm_nBitCount;

private:

//指向DIB的指针(包含BITMAPFILEHEADER、BITMAPINFOHEADER和颜色表)

LPBYTEm_lpDib;

//图像信息头指针

LPBITMAPINFOHEADERm_lpBmpInfoHead;

//调色板句柄

HPALETTEm_hPalette;

//颜色表长度

intm_nColorTableLength;

public:

//不带参数的构造函数

ImgCenterDib();

//带参数的构造函数

ImgCenterDib(CSizesize,intnBitCount,LPRGBQUADlpColorTable,

unsignedchar*pImgData);

//析构函数

~ImgCenterDib();

//DIB读函数

BOOLRead(LPCTSTRlpszPathName);

//DIB写函数

BOOLWrite(LPCTSTRlpszPathName);

//DIB显示函数

BOOLDraw(CDC*pDC,CPointorigin,CSizesize);

//逻辑调色板生成函数

voidMakePalette();

//获取DIB的尺寸(宽、高)

CSizeGetDimensions();

//清理空间

voidEmpty();

//用新的数据替换当前DIB

voidReplaceDib(CSizesize,intnBitCount,LPRGBQUADlpColorTable,unsignedchar*pImgData);

//计算颜色表的长度

intComputeColorTabalLength(intnBitCount);

protected:

//图像的宽,像素为单位

intm_imgWidth;

//图像的高,像素为单位

intm_imgHeight;

};

2.特效显示类,SpecialEffectShow类;

图像的特效显示就是利用人眼的视觉特性,通过先对图像分块,然后以不同的次序显示出来。

其中的要点是:

如何划分图像块;确定图像块的操作次序,以及两个图像块的操作之间的延时。

SpecialEffectShow类继承了ImgCenterDib类。

3.图像的扫描显示;

扫描是最基本的特效显示方式,它没有划分图像块,只是顺序地一行一行或一列一列地显示图像。

单重循环,最基本的。

4.图像的滑动显示;

滑动是将图像看做一个整体,显示时不能像扫描那样,扫描方式有些像打开一幅画,例如显示上部分的时候,下部分可以不显示。

而移动则可以看成一块木板画,显示时候必须按照物理顺序进行,例如从上向下平移时,必须先显示下面的图像,后显示上面的图像。

因此平移的算法比扫描要难一些,平移是以复制的方法显示图像的,每次显示一次,复制的行数就增加一行,直至显示完成。

双重循环,最基本的。

5.图像的渐进显示;

图像渐进显示的思路是先记录下图像的每个像素点的灰度值,显示的时候先将屏幕置黑,将循环显示图像n次,这里设n为0,1,2,…,256。

每一次显示像素灰度值的n/256倍,图像的像素点计算一遍后,显示一次,重复执行上述过程,直至每一个屏幕上的像素点的灰度值恢复到原始图像灰度值的水平。

渐进显示特效虽然不需要对图像进行分块,但是需要开辟两块内存空间,一块用来存储图像的原始灰度值,另一块用来存储每次计算后的像素灰度值。

逐渐增强亮度,从0到256。

6.图像的马赛克显示;

马赛克显示是图像被分成许多小区域,显示时候小区域以杂乱无章的顺序显示在屏幕上。

马赛克显示是比较难的特效,它的图像分块和显示都比较复杂。

其编程思想是:

先将图像分成大小相同的小区域,计算出每一块区域的首地址,并记录下来。

设置一个随机数,用来产生随机显示区域的次序,每获得一个随机区域,就根据首地址显示这块区域的图像,直至所有的区域都至少显示一次。

把每个小方块都显示出来,即使每个小方块的标记都为真。

7.图像的垂直对接显示;VerticalButt

垂直对接显示是将图像分为上下部分,然后同时向中心移动;

需要注意的是,BMP文件是倒着存放的,即屏幕显示位置(0,j)对应数据块的(0,bitmapHeight–j);屏幕显示位置(0,bitmapHeight–j)对应数据块的(0,j)。

8.图像的压缩反转显示;CompressInvert

计算图像位置和高度,以高度的一半为轴进行对换上下半边的图像。

目标矩形区域在循环的前半段为垂直反向。

//压缩反转特效显示的具体算法

intblockSize=4;//每次显示的高度增量,应能被高度整除

for(intj=-bitmapHeight/blockSize;j<=bitmapHeight/blockSize;j++)

{

//目标矩形区域在循环的前半段为垂直反向

:

:

StretchDIBits(pDC->GetSafeHdc(),

0,bitmapHeight/2-j*blockSize/2,bitmapWidth,j*blockSize,

0,0,bitmapWidth,bitmapHeight,

m_pImgData,pBitmapInfo,

DIB_RGB_COLORS,SRCCOPY);

Sleep(3);//设置延时时间

}

9.中心闭幕;CenterFallCurtain

由大到小生成图像中心区域,然后用总区域减去该中心区域,并用材质画刷填充。

//中心闭幕特效显示的具体算法

for(intj=0;j<=bitmapWidth/2;j+=stepCount)

{

CRgnrgn1,rgn2;

rgn1.CreateRectRgn(0,0,bitmapWidth,bitmapHeight);

//以源图象的尺寸创建一个矩形

rgn2.CreateRectRgn(j,j*bitmapHeight/bitmapWidth,bitmapWidth-2*j,bitmapHeight-j*2*bitmapHeight/bitmapWidth);

//不在rgn1中的部分

rgn1.CombineRgn(&rgn1,&rgn2,RGN_DIFF);

:

:

StretchDIBits(pDC->GetSafeHdc(),j,j*bitmapHeight/bitmapWidth,

bitmapWidth-2*j,bitmapHeight-j*2*bitmapHeight/bitmapWidth,

0,0,bitmapWidth,bitmapHeight,

m_pImgData,pBitmapInfo,

DIB_RGB_COLORS,SRCCOPY);

pDC->FillRgn(&rgn1,&brush1);

rgn1.DeleteObject();

rgn2.DeleteObject();

Sleep(3);//设置延时时间

}

10.中心放大;CenterEnlarge

由中心向边缘按高度和宽度的比例循环输出所有像素,直到高度和宽度为原始大小。

//中心放大特效显示的具体算法

intstepCount=2;//每次收缩的步长像素

for(intj=0;j<=bitmapWidth/2;j+=stepCount)

{

:

:

StretchDIBits(pDC->GetSafeHdc(),bitmapWidth/2-j,

bitmapHeight/2-j*bitmapHeight/bitmapWidth,2*j,2*j*bitmapHeight/bitmapWidth,

0,0,bitmapWidth,bitmapHeight,

m_pImgData,pBitmapInfo,

DIB_RGB_COLORS,SRCCOPY);

Sleep(30);//设置延时时间

}

11.交叉竖条;CrossBars

将图像分成宽度相等的列,然后计算从上下两个方向交叉前进的区域,并使用材质画刷填充。

//交叉竖条特效显示的具体算法

intlineWidth=8;//竖条宽度

intlineStep=6;//竖条每次前进的步长

for(intj=0;j<=bitmapHeight/lineStep;j++){

for(inti=0;i<=bitmapWidth/lineWidth;i++)

{if(i%2==0)//从上到下

{

:

:

StretchDIBits(pDC->GetSafeHdc(),

i*lineWidth,j*lineStep,lineWidth,lineStep,

i*lineWidth,bitmapHeight-(j+1)*lineStep,lineWidth,lineStep,

m_pImgData,pBitmapInfo,

DIB_RGB_COLORS,SRCCOPY);

}

else//从下到上

{

:

:

StretchDIBits(pDC->GetSafeHdc(),

bitmapWidth-(i+0)*lineWidth,bitmapHeight-(j+1)*lineStep,

lineWidth,lineStep,

bitmapWidth-(i+0)*lineWidth,j*lineStep,lineWidth,lineStep,

m_pImgData,pBitmapInfo,

DIB_RGB_COLORS,SRCCOPY);

}

}

Sleep(30);//设置延时时间

}

12.水平拉幕;PullCurtain

由中心向开始逐渐输出中心两侧的像素,直到宽度为原始大小。

//水平拉幕特效显示的具体算法

for(inti=0;i<=bitmapWidth/2;i+=lineStep)

{

:

:

StretchDIBits(pDC->GetSafeHdc(),

bitmapWidth/2-i,0,2*i,bitmapHeight,

bitmapWidth/2-i,0,2*i,bitmapHeight,

m_pImgData,pBitmapInfo,

DIB_RGB_COLORS,SRCCOPY);

Sleep(30);//设置延时时间

}

13.随机拉丝;RandomDraw

每次随机显示图像的一个像素行。

//13.随机拉丝特效显示的具体算法

int*rowIndex=newint[bitmapHeight];

for(inti=0;i

rowIndex[i]=0;

intindex=1;//数组索引

longRandNum;//随机变量

srand((unsigned)time(NULL));//生成随机种子

do

{

RandNum=(long)(((double)bitmapHeight)*rand()/RAND_MAX);

//随机变量在0到bitmapHeight-1之间取值

if(rowIndex[RandNum]==0)

{

rowIndex[RandNum]=index++;

}

}while(index

//按照上面随机生成的次序逐一显示每个像素行

for(inti=0;i

{

:

:

StretchDIBits(pDC->GetSafeHdc(),

0,rowIndex[i]-1,bitmapWidth,1,

0,bitmapHeight-rowIndex[i],bitmapWidth,1,

m_pImgData,pBitmapInfo,

DIB_RGB_COLORS,SRCCOPY);

Sleep(3);//设置延时时间

}

 

14.对角闭幕;DiagonalClose

用背景色填充左上、右下角。

//对角闭幕特效显示的具体算法

intstepCount=4;//每次收缩的步长像素

CBrushbrush1(RGB(0,128,128));//设置画刷为lan色

CPointptVertex[3];

for(intj=0;j<=bitmapHeight;j+=stepCount)

{

CRgnrgn1,rgn2;

//左上角区域

ptVertex[0].x=0;

ptVertex[0].y=0;

ptVertex[1].x=0;

ptVertex[1].y=j;

ptVertex[2].x=j*bitmapWidth/bitmapHeight;

ptVertex[2].y=0;

rgn1.CreatePolygonRgn(ptVertex,3,ALTERNATE);

//右下角区域

ptVertex[0].x=bitmapWidth;

ptVertex[0].y=bitmapHeight;

ptVertex[1].x=bitmapWidth;

ptVertex[1].y=bitmapHeight-j;

ptVertex[2].x=bitmapWidth-j*bitmapWidth/bitmapHeight;

ptVertex[2].y=bitmapHeight;

rgn2.CreatePolygonRgn(ptVertex,3,ALTERNATE);

pDC->FillRgn(&rgn1,&brush1);

pDC->FillRgn(&rgn2,&brush1);

rgn1.DeleteObject();

rgn2.DeleteObject();

Sleep(30);//设置延时时间

}

15.垂直百叶;VerticalBlinds

//百叶特效显示的具体算法

for(inti=0;i

{

for(intj=0;j<=bitmapHeight/lineHeight;j++)

{

CRgnrgn1;

inty=lineHeight*j+i;

if(y>=(bitmapHeight-1))y=bitmapHeight-1;

rgn1.CreateRectRgn(0,y,bitmapWidth,y+1);

pDC->FillRgn(&rgn1,&brush1);

rgn1.DeleteObject();

Sleep(10);//设置延时时间

}

}

16.水平拉入;PullScroll

由于内存位图与设备无关,故不能使用在水平方向逐渐改变图像分辨率(每英寸点数)的办法而改为使用在水平方向拉伸显示,并逐步缩小。

CBrushbrush1(RGB(255,255,255));//设置画刷为白色

for(inti=1;i<=96;i++)

{

CRgnrgn1;

rgn1.CreateRectRgn(bitmapWidth,0,bitmapWidth*96/i,bitmapHeight);

:

:

StretchDIBits(pDC->GetSafeHdc(),

0,0,bitmapWidth*96/i,bitmapHeight,

0,0,bitmapWidth,bitmapHeight,

m_pImgData,pBitmapInfo,

DIB_RGB_COLORS,SRCCOPY);

pDC->FillRgn(&rgn1,&brush1);

rgn1.DeleteObject();

Sleep(30);//设置延时时间

}

三、源码下载

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1