请教:如何实现图象控件中图象的放大缩小功能

时间:2021-06-04 15:52:51
在一个dialog中,如何实现一张bmp的放大与缩小功能?就是添加按钮,点一下放大,图片就放大一些.bmp是显示在一个picture控件里的.
最好有源码可以研究一下,本人刚接触编程,纯菜鸟...

9 个解决方案

#1


我找到这样一个函数,差不多可以实现拉伸功能
void   CFangzhiDlg::showpicture(CString   name,int   mode)   
{   
CBitmap   m_bitmap;   
CDC   *pDC=GetDC();   
int   x,y;   
CRect   rc;   
GetClientRect(&rc);   
HBITMAP   hBitmap   =   (HBITMAP)   LoadImage(NULL,   _T(name),   IMAGE_BITMAP,   
0,   0,   LR_CREATEDIBSECTION   |   LR_DEFAULTSIZE   |   LR_LOADFROMFILE);   

m_bitmap.Attach(hBitmap);             
    
CDC   dcImage;   
if   (!dcImage.CreateCompatibleDC(pDC))   
return;   
BITMAP   bm;   
m_bitmap.GetBitmap(&bm);   
//   show   the   image.   
CBitmap*   pOldBitmap   =   dcImage.SelectObject(&m_bitmap);   
x=(rc.right   -bm.bmWidth)/2;   
y=(rc.bottom   -bm.bmHeight)/2;   
//pDC->StretchBlt(100,   100,   bm.bmWidth,   bm.bmHeight,   &dcImage,   100,   100,bm.bmWidth*4,bm.bmHeight*4,SRCCOPY);   
pDC->StretchBlt(29,   56,   (bm.bmWidth)*mode, (bm.bmHeight)*mode, &dcImage,   0,      0,bm.bmWidth,bm.bmHeight,SRCCOPY);   
dcImage.SelectObject(pOldBitmap) ;   
}   

/////////////////////////
pDC->StretchBlt(29,   56,   (bm.bmWidth)*mode, (bm.bmHeight)*mode, &dcImage,   0,      0,bm.bmWidth,bm.bmHeight,SRCCOPY);  这一行是我修改过的.因为我发现参数mode原来在函数里是用不到的,于是把它作为放大倍数,然后在点击放大按钮时执行以下函数
m_bmpcontrol.ShowWindow( SW_HIDE );
showpicture(strPath,time);
time*=time;
其中time我在初始化中设为1.2

但是,我调用函数时,mode这一个参数总是传不进去,图片不进行放大.请问这是什么原因呢
如果把mode换成一个数字,显示得就很正常.

还有,图片控件如何添加水平滚动条和垂直滚动条,以便在显示放大图片时控件大小不变,但可以通过滚动条来看整个图形?

谢谢! 

#2


顶!

#3


水平滚动条和垂直滚动条只需在新建application的时候将基类选择为scrollview即可

#4


http://www.itcomputer.com.cn/Virus/gfaq/200610/104947.html
看下这个网址,说的很清楚

#5


用GDI+,very easy

#6


     大二时候写的图象放大程序  利用CDib类
      那时候没工作,代码不规范,见谅.

   原理:
   是利用线形插值原理,进行放大,每次放大2倍.

   申请一个新图象大小的内存空间,为原来图象大小的2倍,
   在原来图象基础上,把每个象素横纵坐标都乘2放到新图象对应位置
   在把空白的用两个相临值的平均值填充.

   一个象素点分为RGB三个通道,三个通道都需要赋值
   
   最后记得释放申请的空间


int m_width=dib.GetDimensions().cx;
int m_height=dib.GetDimensions().cy;

int m_newwidth=dib.m_lpBMIH->biWidth*2;
int m_newheigth=dib.m_lpBMIH->biHeight*2;
int m_newsizeperline;

m_newsizeperline=(m_newwidth*dib.m_lpBMIH->biBitCount)/32;
if((m_newwidth*dib.m_lpBMIH->biBitCount)%32)
{
m_newsizeperline++;
      }
m_newsizeperline*=4;

    
int m_sizeperline=dib.GetSizePerLine();
LPBYTE m_newImage=new BYTE[m_newsizeperline*m_newheigth];
    for (int i=1;i<m_height;i++)
{
for (int j=1;j<m_width;j++)
{    
m_newImage[2*i*m_newsizeperline+2*j*3]=dib.m_lpImage[m_sizeperline*i+j*3];
m_newImage[2*i*m_newsizeperline+2*j*3+1]=dib.m_lpImage[m_sizeperline*i+j*3+1];
m_newImage[2*i*m_newsizeperline+2*j*3+2]=dib.m_lpImage[m_sizeperline*i+j*3+2];
}
}
    for (i=1;i<m_newheigth;i++)
for (int j=1;j<m_newwidth;j++)
{
if((i%2==0)&&(j%2==1))
{
if(j==m_newwidth-1)
{
m_newImage[i*m_newsizeperline+j*3]=m_newImage[i*m_newsizeperline+(j-1)*3];
m_newImage[i*m_newsizeperline+j*3+1]=m_newImage[i*m_newsizeperline+(j-1)*3+1];
m_newImage[i*m_newsizeperline+j*3+2]=m_newImage[i*m_newsizeperline+(j-1)*3+2];
}
else
{
   m_newImage[i*m_newsizeperline+j*3]=(m_newImage[i*m_newsizeperline+(j-1)*3]+
m_newImage[i*m_newsizeperline+(j+1)*3])/2;
       m_newImage[i*m_newsizeperline+j*3+1]=(m_newImage[i*m_newsizeperline+(j-1)*3+1]+
m_newImage[i*m_newsizeperline+(j+1)*3+1])/2;
   m_newImage[i*m_newsizeperline+j*3+2]=(m_newImage[i*m_newsizeperline+(j-1)*3+2]+
m_newImage[i*m_newsizeperline+(j+1)*3+2])/2;
}
}
}
     for (i=1;i<m_newheigth-1;i++)
for (int j=1;j<m_newwidth;j++)
{
if(i%2==1)
{ if(j==m_newwidth-1)
{
m_newImage[i*m_newsizeperline+j*3]=m_newImage[i*m_newsizeperline+(j-1)*3];
m_newImage[i*m_newsizeperline+j*3+1]=m_newImage[i*m_newsizeperline+(j-1)*3+1];
m_newImage[i*m_newsizeperline+j*3+2]=m_newImage[i*m_newsizeperline+(j-1)*3+2];
}
   else
   {
m_newImage[i*m_newsizeperline+j*3]=(m_newImage[(i-1)*m_newsizeperline+j*3]+
m_newImage[(i+1)*m_newsizeperline+j*3])/2;
    m_newImage[i*m_newsizeperline+j*3+1]=(m_newImage[(i-1)*m_newsizeperline+j*3+1]+
m_newImage[(i+1)*m_newsizeperline+j*3+1])/2;
m_newImage[i*m_newsizeperline+j*3+2]=(m_newImage[(i-1)*m_newsizeperline+j*3+2]+
m_newImage[(i+1)*m_newsizeperline+j*3+2])/2;
   }
}
}
delete[]dib.m_lpImage;
dib.m_lpImage=m_newImage;
dib.m_lpBMIH->biWidth=m_newwidth;
dib.m_lpBMIH->biHeight=m_newheigth;


UpdateAllViews(FALSE);

#7


回复四楼的兄弟,这个帖子我以前看过,试过这个方法,不过它和我的功能不太一样.现在用StretchBlt差不多能实现放大缩小功能了.就是滚动条的问题比较麻烦.gdi+没接触过

#8


请教六楼的,dib是什么

#9


解决了.现在没分可用,只能给大家意思一下了,不好意思!!

#1


我找到这样一个函数,差不多可以实现拉伸功能
void   CFangzhiDlg::showpicture(CString   name,int   mode)   
{   
CBitmap   m_bitmap;   
CDC   *pDC=GetDC();   
int   x,y;   
CRect   rc;   
GetClientRect(&rc);   
HBITMAP   hBitmap   =   (HBITMAP)   LoadImage(NULL,   _T(name),   IMAGE_BITMAP,   
0,   0,   LR_CREATEDIBSECTION   |   LR_DEFAULTSIZE   |   LR_LOADFROMFILE);   

m_bitmap.Attach(hBitmap);             
    
CDC   dcImage;   
if   (!dcImage.CreateCompatibleDC(pDC))   
return;   
BITMAP   bm;   
m_bitmap.GetBitmap(&bm);   
//   show   the   image.   
CBitmap*   pOldBitmap   =   dcImage.SelectObject(&m_bitmap);   
x=(rc.right   -bm.bmWidth)/2;   
y=(rc.bottom   -bm.bmHeight)/2;   
//pDC->StretchBlt(100,   100,   bm.bmWidth,   bm.bmHeight,   &dcImage,   100,   100,bm.bmWidth*4,bm.bmHeight*4,SRCCOPY);   
pDC->StretchBlt(29,   56,   (bm.bmWidth)*mode, (bm.bmHeight)*mode, &dcImage,   0,      0,bm.bmWidth,bm.bmHeight,SRCCOPY);   
dcImage.SelectObject(pOldBitmap) ;   
}   

/////////////////////////
pDC->StretchBlt(29,   56,   (bm.bmWidth)*mode, (bm.bmHeight)*mode, &dcImage,   0,      0,bm.bmWidth,bm.bmHeight,SRCCOPY);  这一行是我修改过的.因为我发现参数mode原来在函数里是用不到的,于是把它作为放大倍数,然后在点击放大按钮时执行以下函数
m_bmpcontrol.ShowWindow( SW_HIDE );
showpicture(strPath,time);
time*=time;
其中time我在初始化中设为1.2

但是,我调用函数时,mode这一个参数总是传不进去,图片不进行放大.请问这是什么原因呢
如果把mode换成一个数字,显示得就很正常.

还有,图片控件如何添加水平滚动条和垂直滚动条,以便在显示放大图片时控件大小不变,但可以通过滚动条来看整个图形?

谢谢! 

#2


顶!

#3


水平滚动条和垂直滚动条只需在新建application的时候将基类选择为scrollview即可

#4


http://www.itcomputer.com.cn/Virus/gfaq/200610/104947.html
看下这个网址,说的很清楚

#5


用GDI+,very easy

#6


     大二时候写的图象放大程序  利用CDib类
      那时候没工作,代码不规范,见谅.

   原理:
   是利用线形插值原理,进行放大,每次放大2倍.

   申请一个新图象大小的内存空间,为原来图象大小的2倍,
   在原来图象基础上,把每个象素横纵坐标都乘2放到新图象对应位置
   在把空白的用两个相临值的平均值填充.

   一个象素点分为RGB三个通道,三个通道都需要赋值
   
   最后记得释放申请的空间


int m_width=dib.GetDimensions().cx;
int m_height=dib.GetDimensions().cy;

int m_newwidth=dib.m_lpBMIH->biWidth*2;
int m_newheigth=dib.m_lpBMIH->biHeight*2;
int m_newsizeperline;

m_newsizeperline=(m_newwidth*dib.m_lpBMIH->biBitCount)/32;
if((m_newwidth*dib.m_lpBMIH->biBitCount)%32)
{
m_newsizeperline++;
      }
m_newsizeperline*=4;

    
int m_sizeperline=dib.GetSizePerLine();
LPBYTE m_newImage=new BYTE[m_newsizeperline*m_newheigth];
    for (int i=1;i<m_height;i++)
{
for (int j=1;j<m_width;j++)
{    
m_newImage[2*i*m_newsizeperline+2*j*3]=dib.m_lpImage[m_sizeperline*i+j*3];
m_newImage[2*i*m_newsizeperline+2*j*3+1]=dib.m_lpImage[m_sizeperline*i+j*3+1];
m_newImage[2*i*m_newsizeperline+2*j*3+2]=dib.m_lpImage[m_sizeperline*i+j*3+2];
}
}
    for (i=1;i<m_newheigth;i++)
for (int j=1;j<m_newwidth;j++)
{
if((i%2==0)&&(j%2==1))
{
if(j==m_newwidth-1)
{
m_newImage[i*m_newsizeperline+j*3]=m_newImage[i*m_newsizeperline+(j-1)*3];
m_newImage[i*m_newsizeperline+j*3+1]=m_newImage[i*m_newsizeperline+(j-1)*3+1];
m_newImage[i*m_newsizeperline+j*3+2]=m_newImage[i*m_newsizeperline+(j-1)*3+2];
}
else
{
   m_newImage[i*m_newsizeperline+j*3]=(m_newImage[i*m_newsizeperline+(j-1)*3]+
m_newImage[i*m_newsizeperline+(j+1)*3])/2;
       m_newImage[i*m_newsizeperline+j*3+1]=(m_newImage[i*m_newsizeperline+(j-1)*3+1]+
m_newImage[i*m_newsizeperline+(j+1)*3+1])/2;
   m_newImage[i*m_newsizeperline+j*3+2]=(m_newImage[i*m_newsizeperline+(j-1)*3+2]+
m_newImage[i*m_newsizeperline+(j+1)*3+2])/2;
}
}
}
     for (i=1;i<m_newheigth-1;i++)
for (int j=1;j<m_newwidth;j++)
{
if(i%2==1)
{ if(j==m_newwidth-1)
{
m_newImage[i*m_newsizeperline+j*3]=m_newImage[i*m_newsizeperline+(j-1)*3];
m_newImage[i*m_newsizeperline+j*3+1]=m_newImage[i*m_newsizeperline+(j-1)*3+1];
m_newImage[i*m_newsizeperline+j*3+2]=m_newImage[i*m_newsizeperline+(j-1)*3+2];
}
   else
   {
m_newImage[i*m_newsizeperline+j*3]=(m_newImage[(i-1)*m_newsizeperline+j*3]+
m_newImage[(i+1)*m_newsizeperline+j*3])/2;
    m_newImage[i*m_newsizeperline+j*3+1]=(m_newImage[(i-1)*m_newsizeperline+j*3+1]+
m_newImage[(i+1)*m_newsizeperline+j*3+1])/2;
m_newImage[i*m_newsizeperline+j*3+2]=(m_newImage[(i-1)*m_newsizeperline+j*3+2]+
m_newImage[(i+1)*m_newsizeperline+j*3+2])/2;
   }
}
}
delete[]dib.m_lpImage;
dib.m_lpImage=m_newImage;
dib.m_lpBMIH->biWidth=m_newwidth;
dib.m_lpBMIH->biHeight=m_newheigth;


UpdateAllViews(FALSE);

#7


回复四楼的兄弟,这个帖子我以前看过,试过这个方法,不过它和我的功能不太一样.现在用StretchBlt差不多能实现放大缩小功能了.就是滚动条的问题比较麻烦.gdi+没接触过

#8


请教六楼的,dib是什么

#9


解决了.现在没分可用,只能给大家意思一下了,不好意思!!