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;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值