最近研究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;
}