大图像移动时的闪动解决方案[原创]

本文介绍了一种使用GDI+在PictureBox中实现类似Google Earth平滑滚动效果的方法。通过仅重新绘制客户端区域大小的部分图片,即使在处理大尺寸图片时也能保持良好的用户体验。文章提供了具体的实现代码。
暑假的时候yangmin和我讨论了一个问题, 就是如何实现像GoogleEarth那样, 鼠标移动图片的时候很平滑。详细观察之后, 才知道它用了DX, OpenGl的**技术。心有不甘,决定用Gdi+来试试。
我是在Form上放置了一个PictureBox, 然后进行移动。 刚开始的时候我是用整个图来画的, 发现当图片大到一个程度之后就可以闪了,尽管PictureBox有一个双缓冲。。。后来仔细想想, 其实完全可以在图片移动的过程中仅仅绘制一部分,也就是ClientSize的那一块, 试验了一下 , 效果果然不错。(在图片巨大无比的时候, 内存会上涨到250M,这个时候拖动的平滑感就欠缺一点了)
核心代码如下:
None.gifprivate void pictureBox1_MouseMove(object sender, MouseEventArgs e)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif{
InBlock.gif            
InBlock.gif            
if (e.Button == MouseButtons.Left)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
//移动处理
InBlock.gif
                if (!isLeftCtrlKeyDown)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    offset.Width 
+= e.X - mousePressPoint.X;
InBlock.gif                    offset.Height 
+= e.Y - mousePressPoint.Y;
InBlock.gif                    mousePressPoint 
= e.Location;
InBlock.gif                    Bitmap newbmp 
= new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
InBlock.gif                    Graphics g 
= Graphics.FromImage(newbmp);
InBlock.gif                    
//重绘一小段图片
InBlock.gif
                    g.DrawImage(bmp, new Rectangle(00this.ClientSize.Width, this.ClientSize.Height),
InBlock.gif                        
-offset.Width, -offset.Height, this.ClientSize.Width, this.ClientSize.Height, GraphicsUnit.Pixel);
InBlock.gif                    pictureBox1.Image 
= newbmp;
InBlock.gif                    pictureBox1.Refresh();                   
ExpandedSubBlockEnd.gif                }

InBlock.gif                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
//放大缩小处理
InBlock.gif
                    int width = bmp.Width + pictureBox1.Location.X + e.X - mousePressPoint.X;
InBlock.gif                    
int height = bmp.Height + pictureBox1.Location.Y + e.Y - mousePressPoint.Y;
InBlock.gif                    
if (width > 0 && height > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        bmp 
= new Bitmap(bmp, new Size(width, height));
InBlock.gif                        pictureBox1.Image 
= bmp;
InBlock.gif                        pictureBox1.Refresh();
ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

InBlock.gif                
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值