VC图片显示特效

最近研究MTK的屏幕特效,由于手机窗口特效与VC编程原理大致相同,特意找了一些VC的图像算法来研究.

创建一个滚动视图类窗口,加入相关函数变量.

// PaintPictureView.cpp : implementation of the CPaintPictureView class
//

#include "stdafx.h"
#include "PaintPicture.h"

#include "PaintPictureDoc.h"
#include "PaintPictureView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CPaintPictureView

IMPLEMENT_DYNCREATE(CPaintPictureView, CScrollView)

BEGIN_MESSAGE_MAP(CPaintPictureView, CScrollView)
//{{AFX_MSG_MAP(CPaintPictureView)
ON_WM_CREATE()
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPaintPictureView construction/destruction

CPaintPictureView::CPaintPictureView()
{
// TODO: add construction code here
}

CPaintPictureView::~CPaintPictureView()
{
delete m_pMemDC; //删除内存设备环境
delete m_pBitmap; //删除CBitmap的指针
}

BOOL CPaintPictureView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs

return CScrollView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CPaintPictureView drawing

void CPaintPictureView::OnDraw(CDC* pDC)
{
CPaintPictureDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here

BITMAP m_Bm;
//保存位图的宽、高度等数据
HBITMAP *m_hBitmap;
//在类构造函数中加入如下代码:

//从文件中装入位图数据
if (BmpName.IsEmpty())
{
BmpName.Format(_T("D://Water lilies.bmp"));
}
m_hBitmap=(HBITMAP*)::LoadImage(
AfxGetInstanceHandle(),
BmpName,
IMAGE_BITMAP,
0,0,
LR_LOADFROMFILE);

m_pMemDC->SelectObject(m_hBitmap); //将位图选入内存设备情境对象
::GetObject(m_hBitmap,sizeof(m_Bm),&m_Bm);
#if 0
pDC->BitBlt(0,0, //目标设备逻辑横、纵坐标
m_Bm.bmWidth, m_Bm.bmHeight, //显示位图的像素宽、高度
m_pMemDC,
//待显示位图数据的设备情境对象
0,0, //源数据中的横、纵坐标
SRCCOPY); //位操作方式
#elif (1)
//变宽特效
int i,j;

//for (i=0; i<=m_Bm.bmHeight; i++)

{
for (j=0; j<=m_Bm.bmWidth; j++)

pDC->StretchBlt(

0,0,

//目标设备逻辑横、纵坐标

j,m_Bm.bmHeight,

//显示位图的像素宽、高度

m_pMemDC,

//源位图设备情境对象

0,0,

//源位图的起始横、纵坐标

m_Bm.bmWidth,m_Bm.bmHeight,

//源位图的像素宽、高度

SRCCOPY);

Sleep(20);

}
#elif (1)
//水平交错效果
int i,j;
SetStretchBltMode(pDC->GetSafeHdc(),HALFTONE);
for (i=0; i<=m_Bm.bmHeight; i+=2)
{
j = i;

while(j>0)

{
pDC->StretchBlt(

//奇数,由上至下

0,j-1,

//目标设备逻辑横、纵坐标

m_Bm.bmWidth,1,

//显示位图的像素宽、高度

m_pMemDC,

//源位图设备情境对象

0,m_Bm.bmHeight-(i-j-1),

//源位图的起始横、纵坐标

m_Bm.bmWidth,1,

//源位图的像素宽、高度

SRCCOPY);

pDC->StretchBlt(

//偶数,由下至上

0,m_Bm.bmHeight-j,

//目标设备逻辑横、纵坐标

m_Bm.bmWidth,1,

//显示位图的像素宽、高度

m_pMemDC,

//源位图设备情境对象

0,i-j,

//源位图的起始横、纵坐标

m_Bm.bmWidth,1,

//源位图的像素宽、高度

SRCCOPY);

j-=2;
}

// while ( j>0 )

Sleep(10);

}
#elif (1)
//雨滴效果
int i,j;

for ( i=0; i<=m_Bm.bmHeight; i++ )

{
for ( j=0; j<=m_Bm.bmHeight-i; j++ )

pDC->StretchBlt(

0,j,

//目标设备逻辑横、纵坐标

m_Bm.bmWidth,1,

//显示位图的像素宽、高度

m_pMemDC,

//源位图设备情境对象

0,m_Bm.bmHeight-i,

//源位图的起始横、纵坐标

m_Bm.bmWidth,1,

//源位图的像素宽、高度

SRCCOPY);

Sleep(20);

}
#elif (1)
//百叶窗效果
int i,stepi,j;

stepi=m_Bm.bmHeight/10;

for ( i=0; i<=stepi; i++ )

{
for ( j=0; j<10; j++ )

pDC->StretchBlt(

0,j*stepi+i,

//目标设备逻辑横、纵坐标

m_Bm.bmWidth,1,

//显示位图的像素宽、高度

m_pMemDC,

//源位图设备情境对象

0,j*stepi+i,

//源位图的起始横、纵坐标

m_Bm.bmWidth,1,

//源位图的像素宽、高度

SRCCOPY);

Sleep(20);

} //for ( i=0; i<=stepi; i++ )
#else
//随机积木效果
int i,j,stepx,stepy,dispnum,x,y;

int pxy[10][10];

//使用本数组记录已显示过的数据组

for ( i=0; i<10; i++ )

for ( j=0; j<10; j++ )

pxy[i][j]=0;

stepx=m_Bm.bmWidth/10;

stepy=m_Bm.bmHeight/10;

srand( (unsigned)time( NULL ) );

dispnum=0;

//记录已显示过的数据组的个数

while(1)

{
x=rand() % 10;

y=rand() % 10;

if ( pxy[x][y] )

//本组x,y所代表的数据组是否已显示过?

continue;

pxy[x][y]=1;

//表明本组x,y所代表的数据组已显示过

pDC->StretchBlt(

x*stepx, y*stepy,

//目标设备逻辑横、纵坐标

stepx,stepy,

//显示位图的像素宽、高度

m_pMemDC,

//源位图设备情境对象

x*stepx, y*stepy,

//源位图的起始横、纵坐标

stepx,stepy,

//源位图的像素宽、高度

SRCCOPY);

dispnum++;

if ( dispnum >=100 )

break;

Sleep(30);

} // while(1)

#endif
}

void CPaintPictureView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();

CSize sizeTotal;
// TODO: calculate the total size of this view
sizeTotal.cx = sizeTotal.cy = 100;
SetScrollSizes(MM_TEXT, sizeTotal);
}

/////////////////////////////////////////////////////////////////////////////
// CPaintPictureView printing

BOOL CPaintPictureView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}

void CPaintPictureView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}

void CPaintPictureView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CPaintPictureView diagnostics

#ifdef _DEBUG
void CPaintPictureView::AssertValid() const
{
CScrollView::AssertValid();
}

void CPaintPictureView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}

CPaintPictureDoc* CPaintPictureView::GetDocument() // non-debug version is
inline

{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPaintPictureDoc)));
return (CPaintPictureDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CPaintPictureView message handlers

int CPaintPictureView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CScrollView::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: Add your specialized creation code here
CDC* pDC=GetDC();
int nWidth=GetSystemMetrics(SM_CXSCREEN);
int nHeight=GetSystemMetrics(SM_CYSCREEN);

m_pMemDC = new CDC();
m_pBitmap = new CBitmap();

m_pMemDC->CreateCompatibleDC(pDC);
m_pBitmap->CreateCompatibleBitmap(pDC,nWidth,nHeight);
m_pOldBitmap = m_pMemDC->SelectObject(m_pBitmap);
ReleaseDC(pDC);

return 0;
}

void CPaintPictureView::OnFileOpen()
{
// TODO: Add your command handler code here
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,_T(
"位图文件(*.BMP)|*.BMP|jpg文件(*.jpg)|*.jpg||")); //这行代码可以打开BMP和JPG
格式的图片


//gif格式图片的打开在这就不列出来了,留给各位自己尝试吧,对于gif
格式图片的显示图片函数和jpg格式图片是同一个函数。


if (IDOK==dlg.DoModal())
{
BmpName.Format(_T("%s"),dlg.GetPathName());
Invalidate();
}


}
BOOL CPaintPictureView::ShowJpgGif(CDC* pDC,CString strPath, int x, int y)

{
IStream *pStm;
CFileStatus fstatus;
CFile file;
LONG cb;

//打开文件并检测文件的有效性
if (file.Open(strPath,CFile::modeRead)&&
file.GetStatus(strPath,fstatus)&&
((cb = fstatus.m_size) != -1))
{
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, cb);
LPVOID pvData = NULL;
if (hGlobal != NULL)
{
pvData = GlobalLock(hGlobal);
if (pvData != NULL)
{
//file.ReadHuge(pvData, cb); //6.0中可能是用这个函数
file.Read(pvData, cb); //VC2005.NET中用这个函数
GlobalUnlock(hGlobal);
CreateStreamOnHGlobal(hGlobal, TRUE, &pStm);
}
}
}
else
{
return false;
} //打开文件结束

//显示JPEG和GIF格式的图片,GIF只能显示一帧,还不能显示动画,

//要显示动画GIF请使用ACTIVE控件。

IPicture *pPic;

//load image from file stream

if(SUCCEEDED(OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID*
)&pPic)))


{

OLE_XSIZE_HIMETRIC hmWidth;
OLE_YSIZE_HIMETRIC hmHeight;
pPic->get_Width(&hmWidth);
pPic->get_Height(&hmHeight);
double fX,fY;

//get image height and width

fX = (double)pDC->GetDeviceCaps(HORZRES)*(double)hmWidth/((double)pDC
->GetDeviceCaps(HORZSIZE)*100.0);


fY = (double)pDC->GetDeviceCaps(VERTRES)*(double)hmHeight/((double)
pDC->GetDeviceCaps(VERTSIZE)*100.0);


//use render function display image
if(FAILED(pPic->Render(*pDC,x,y,(DWORD)fX,(DWORD)fY,0,hmHeight,hmWidth
,-hmHeight,NULL)))

{
pPic->Release();
return false;
}
pPic->Release();
}
else
{
return false;
}

return true;
}

你可能感兴趣的:(图片)