博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
图像显示特效
阅读量:5082 次
发布时间:2019-06-13

本文共 8452 字,大约阅读时间需要 28 分钟。

(1)实现原理:将图像分成不同的区域小块,然后按照一定的方向、顺序先后显示在屏幕上。

(2)图像块的显示:一般使用下面这个函数进行处理

BOOL  CDC::BitBIt(int x,int y,int nWidth,int nHeight,CDC* pSrcDC,int xSrc,int ySrc,DWORD dwRop);

BitBlt的全称是 Bit Block Transfer(位块传输),专门用于将源设备上下文的一部分图像直接传送到当前设备上下文中。BitBlt函数实际完成的功能是图像的内存复制,所以效率很高。

(3)延时:图像的显示特效是通过图像的显示过程体现出来的,由于计算机处理速度太快,所以为了明星表现整个显示过程,需要加入延时函数。一个好的延时函数必须满足两个条件:一、精确延时,至少精确到毫秒级;二、延时函数与计算机的运行速度无关。延时函数如下:

void CMyEffectDisplay::DelayTime(DWORD dwMilliseconds){    LARGE_INTEGER litmp;    LONGLONG lTimeBeign;    LONGLONG lTimeEnd;    double dMinus;    double dFreq;    double dTim;    QueryPerformanceFrequency(&litmp);    // 获得机器内部定时器的时钟频率    dFreq = (double)litmp.QuadPart;        // 获得计数器的时钟频率    QueryPerformanceCounter(&litmp);    lTimeBeign = litmp.QuadPart;        // 获得时间起始值    do    {        QueryPerformanceCounter(&litmp);        lTimeEnd = litmp.QuadPart;        //获得中止值        dMinus = (double)(lTimeEnd - lTimeBeign);        dTim = dMinus / dFreq;            // 获得对应的时间值,单位为秒    } while (dTim < dwMilliseconds * 0.001);}

 

首先在CMyEffectDisplay头文件声明一些变量:

static int s_nOffsetX;      // 图像在内存CDC中的X偏移量    static int s_nOffsetY;      // 图像在内存CDC中的Y偏移量    static int s_nPicWidth;     // 图像的宽度    static int s_nPicHeight;    // 图像的高度    static int s_nCDCWidth;     // 内存CDC的宽度    static int s_nCDCHeight;    // 内存CDC的高度

 

然后再OnDraw函数中做一些准备工作:

   CRect rect;    GetClientRect(rect);    CDC memDC;    CBitmap MemBitmap;    memDC.CreateCompatibleDC(NULL);    MemBitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());    memDC.SelectObject(MemBitmap);    memDC.FillSolidRect(rect, RGB(255, 255, 255));    Image   image(_T("E:\\素材\\jpg\\1.jpg"));    Graphics   graph(memDC.GetSafeHdc());    graph.DrawImage(&image, 0, 0);    CMyEffectDisplay::s_nOffsetX = 0;    CMyEffectDisplay::s_nOffsetY = 0;    CMyEffectDisplay::s_nCDCWidth = rect.Width();    CMyEffectDisplay::s_nCDCHeight = rect.Height();    CMyEffectDisplay::s_nPicWidth = image.GetWidth();    CMyEffectDisplay::s_nPicHeight = image.GetHeight();   // CMyEffectDisplay::ScanDownDisplay(pDC, &memDC); // 函数调用   ...

 

一、向下扫描特效实现

void CMyEffectDisplay::ScanDownDisplay(CDC* pDC, CDC* pMemDC){    // 扫描高度    int nHeight = min(s_nPicHeight, s_nCDCHeight);    // 扫描宽度    int nWidth = min(s_nPicWidth, s_nCDCWidth);    for (int i = 0; i <= nHeight; i += 1)    {        pDC->BitBlt(s_nOffsetX, i + s_nOffsetY, nWidth, 1,            pMemDC, s_nOffsetX, i + s_nOffsetY, SRCCOPY);        DelayTime(1);    }}

二、垂直双重扫描特效实现

void CMyEffectDisplay::VSScanDisplay(CDC* pDC, CDC* pMemDC){    // 扫描高度    int nHeight = min(s_nPicHeight, s_nCDCHeight);    // 扫描宽度    int nWidth = min(s_nPicWidth, s_nCDCWidth);    for (int i = 0; i <= nHeight / 2; i += 1)    {        // 向下扫描        pDC->BitBlt(s_nOffsetX, i + s_nOffsetY, nWidth, 1, pMemDC, s_nOffsetX, i + s_nOffsetY, SRCCOPY);        // 向上扫描        pDC->BitBlt(s_nOffsetX, nHeight - i - 1, nWidth, 1, pMemDC, s_nOffsetX, nHeight - i - 1, SRCCOPY);        // 延时        DelayTime(2);    }}

三、向右移动特效实现:

void CMyEffectDisplay::MoveRightDisplay(CDC* pDC, CDC* pMemDC){    // 扫描高度    int nHeight = min(s_nPicHeight, s_nCDCHeight);    for (int i = 0; i <= s_nCDCWidth - s_nOffsetX; i += 2)    {        pDC->BitBlt(0, s_nOffsetY, i, nHeight,            pMemDC, s_nCDCWidth - s_nOffsetX - i, s_nOffsetY, SRCCOPY);        DelayTime(1);    }    // 修正图像位置    pDC->BitBlt(0, s_nOffsetY, s_nCDCWidth - s_nOffsetX, nHeight,        pMemDC, 0, s_nOffsetY, SRCCOPY);}

四、水平双重移动特效实现:

void CMyEffectDisplay::HSMoveDisplay(CDC* pDC, CDC* pMemDC){    // 扫描高度    int nHeight = min(s_nPicHeight, s_nCDCHeight);    // 扫描宽度    int nWidth = min(s_nPicWidth, s_nCDCWidth);    for (int i = 0; i <= s_nCDCWidth / 2; i += 2)    {        // 左面部分        pDC->BitBlt(0, s_nOffsetY, i, nHeight,            pMemDC, nWidth / 2 - i + s_nOffsetX, s_nOffsetY, SRCCOPY);        // 右面部分        pDC->BitBlt(s_nCDCWidth - i, s_nOffsetY, i, nHeight,            pMemDC, nWidth / 2 + s_nOffsetX, s_nOffsetY, SRCCOPY);        DelayTime(1);    }    // 修正图像位置    pDC->BitBlt(0, s_nOffsetY, s_nCDCWidth - s_nOffsetX, nHeight,        pMemDC, 0, s_nOffsetY, SRCCOPY);}

五、垂直百叶窗特效实现

void CMyEffectDisplay::VBlindDisplay(CDC* pDC, CDC* pMemDC){    // 扫描高度    int nHeight = min(s_nPicHeight, s_nCDCHeight);    // 扫描宽度    int nWidth = min(s_nPicWidth, s_nCDCWidth);    // 百叶窗宽度    int nScanLine = 8;    for (int i = 0; i < nScanLine; i++)  // 循环8次,即分8列显示    {        for (int j = 0; j < nWidth; j += nScanLine)        {            pDC->BitBlt(j + i + s_nOffsetX, s_nOffsetY, 1, nHeight,                pMemDC, j + i + s_nOffsetX, s_nOffsetY, SRCCOPY);        }        DelayTime(200);    }}

六、水平百叶窗特效实现

void CMyEffectDisplay::HBlindDisplay(CDC* pDC, CDC* pMemDC){    // 扫描高度    int nHeight = min(s_nPicHeight, s_nCDCHeight);    // 扫描宽度    int nWidth = min(s_nPicWidth, s_nCDCWidth);    // 百叶窗宽度    int nScanLine = 8;    for (int i = 0; i < nScanLine; i++)    {        for (int j = 0; j < nHeight; j += nScanLine)        {            pDC->BitBlt(s_nOffsetX, j + i + s_nOffsetY, nWidth, 1,                pMemDC, s_nOffsetX, j + i + s_nOffsetY, SRCCOPY);        }        DelayTime(200);    }}

七、垂直栅条特效实现

void CMyEffectDisplay::VRasterDisplay(CDC* pDC, CDC* pMemDC){    // 扫描高度    int nHeight = min(s_nPicHeight, s_nCDCHeight);    // 扫描宽度    int nWidth = min(s_nPicWidth, s_nCDCWidth);    int nScanLine = 16;    for (int i = 0; i <= nHeight + s_nOffsetY; i++)    {        for (int j = 0; j <= nWidth; j += 2 * nScanLine)        {            pDC->BitBlt(j + s_nOffsetX, 0, nScanLine, i,                pMemDC, j + s_nOffsetX, nHeight + s_nOffsetY - i, SRCCOPY);            int k = j + nScanLine;            pDC->BitBlt(k + s_nOffsetX, nHeight + s_nOffsetY - i, nScanLine, i + s_nOffsetY,                pMemDC, k + s_nOffsetX, 0, SRCCOPY);        }        DelayTime(1);    }}

八、水平栅条特效实现

void CMyEffectDisplay::HRasterDisplay(CDC* pDC, CDC* pMemDC){    // 扫描高度    int nHeight = min(s_nPicHeight, s_nCDCHeight);    // 扫描宽度    int nWidth = min(s_nPicWidth, s_nCDCWidth);    int nScanLine = 16;    for (int i = 0; i <= nWidth + s_nOffsetX; i++)    {        for (int j = 0; j <= nHeight; j += 2 * nScanLine)        {            pDC->BitBlt(0, j + s_nOffsetY, i, nScanLine,                pMemDC, nWidth + s_nOffsetX - i, j + s_nOffsetY, SRCCOPY);            int k = j + nScanLine;            pDC->BitBlt(nWidth + s_nOffsetX - i, k + s_nOffsetY, i + s_nOffsetX, nScanLine,                pMemDC, 0, k + s_nOffsetY, SRCCOPY);        }        DelayTime(1);    }}

九、马赛克特效实现

void CMyEffectDisplay::MosaicDisplay(CDC* pDC, CDC* pMemDC){    int nTileSize = 24;    // 马赛克小方块大小    int nRw = 0;    int nRh = 0;    if (s_nPicWidth % nTileSize != 0)        nRw = 1;    if (s_nPicHeight % nTileSize != 0)        nRh = 1;    // 计算小方块的个数    int nTileCount = (s_nPicWidth / nTileSize + nRw) * (s_nPicHeight / nTileSize + nRh);    CPtrArray    points;        // 保存所有小方块的左上坐标    long        lx = 0;    long        ly = 0;    for (int k = 0; k < nTileCount; k++)    {        CPoint* point = new CPoint;        point->x = lx;        point->y = ly;        lx = lx + nTileSize;        if (lx >= s_nPicWidth)        {            lx = 0;            ly = ly + nTileSize;        }        points.Add(point);    }    int nDelayTime = 2;    if (s_nPicHeight * s_nPicWidth > 600 * 500)        nDelayTime = 1;    LARGE_INTEGER seed;    QueryPerformanceFrequency(&seed);    QueryPerformanceCounter(&seed);    //初始化一个以微秒为单位的时间种子    srand((int)seed.QuadPart);    for (int i = nTileCount - 1; i >= 0; i--)    {        int n = rand() % (i + 1);        CPoint* point = (CPoint*)points[n];        lx = point->x;        ly = point->y;        pDC->BitBlt(lx + s_nOffsetX, ly + s_nOffsetY, nTileSize, nTileSize,            pMemDC, lx + s_nOffsetX, ly + s_nOffsetY, SRCCOPY);        /*SAFE_DELETE(point);*/        if (point != NULL)        {            delete point;            point = NULL;        }        points.RemoveAt(n);        DelayTime(nDelayTime);    }}

十、雨滴特效实现

void CMyEffectDisplay::RaindropDisplay(CDC* pDC, CDC* pMemDC){    // 扫描高度    int nHeight = min(s_nPicHeight, s_nCDCHeight);    // 扫描宽度    int nWidth = min(s_nPicWidth, s_nCDCWidth);    for (int i = 0; i <= nHeight + s_nOffsetY; i++)    {        for (int j = 0; j <= nHeight + s_nOffsetY - i; j++)        {            pDC->BitBlt(s_nOffsetX, j, nWidth, 1,                pMemDC, s_nOffsetX, nHeight + s_nOffsetY - i, SRCCOPY);        }        DelayTime(1);    }}

 

转载于:https://www.cnblogs.com/luzuwei/p/9042186.html

你可能感兴趣的文章
Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十四章:曲面细分阶段...
查看>>
在WPF控件上添加Windows窗口式调整大小行为
查看>>
背水一战 Windows 10 (36) - 控件(弹出类): ToolTip, Popup, PopupMenu
查看>>
教育类APP开发现新增长,多款APP该如何突围?
查看>>
打开3389
查看>>
React学习记录
查看>>
nginx常见内部参数,错误总结
查看>>
对象与类
查看>>
《奸的好人2》财色战场----笔记
查看>>
BZOJ 1834网络扩容题解
查看>>
bzoj1878
查看>>
【Vegas原创】Mysql绿色版安装方法
查看>>
Thrift Expected protocol id ffffff82 but got 0
查看>>
分享《去哪儿网》前端笔试题
查看>>
2013-07-04学习笔记二
查看>>
CP15 协处理器寄存器解读
查看>>
【codeforces 787B】Not Afraid
查看>>
【9111】高精度除法(高精度除高精度)
查看>>
【hihocoder 1312】搜索三·启发式搜索(普通广搜做法)
查看>>
JavaFX中ObservableValue类型
查看>>