大图像移动时的闪动解决方案[原创]
2006-10-18 09:54 老博客哈 阅读(1330) 评论(3) 收藏 举报
暑假的时候yangmin和我讨论了一个问题, 就是如何实现像GoogleEarth那样, 鼠标移动图片的时候很平滑。详细观察之后, 才知道它用了DX, OpenGl的**技术。心有不甘,决定用Gdi+来试试。
我是在Form上放置了一个PictureBox, 然后进行移动。 刚开始的时候我是用整个图来画的, 发现当图片大到一个程度之后就可以闪了,尽管PictureBox有一个双缓冲。。。后来仔细想想, 其实完全可以在图片移动的过程中仅仅绘制一部分,也就是ClientSize的那一块, 试验了一下 , 效果果然不错。(在图片巨大无比的时候, 内存会上涨到250M,这个时候拖动的平滑感就欠缺一点了)
核心代码如下:
 private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
 {
        {
 
            
 if (e.Button == MouseButtons.Left)
            if (e.Button == MouseButtons.Left)
 {
            {
 //移动处理
                //移动处理
 if (!isLeftCtrlKeyDown)
                if (!isLeftCtrlKeyDown)
 {
                {
 offset.Width += e.X - mousePressPoint.X;
                    offset.Width += e.X - mousePressPoint.X;
 offset.Height += e.Y - mousePressPoint.Y;
                    offset.Height += e.Y - mousePressPoint.Y;
 mousePressPoint = e.Location;
                    mousePressPoint = e.Location;
 Bitmap newbmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
                    Bitmap newbmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
 Graphics g = Graphics.FromImage(newbmp);
                    Graphics g = Graphics.FromImage(newbmp);
 //重绘一小段图片
                    //重绘一小段图片
 g.DrawImage(bmp, new Rectangle(0, 0, this.ClientSize.Width, this.ClientSize.Height),
                    g.DrawImage(bmp, new Rectangle(0, 0, this.ClientSize.Width, this.ClientSize.Height),
 -offset.Width, -offset.Height, this.ClientSize.Width, this.ClientSize.Height, GraphicsUnit.Pixel);
                        -offset.Width, -offset.Height, this.ClientSize.Width, this.ClientSize.Height, GraphicsUnit.Pixel);
 pictureBox1.Image = newbmp;
                    pictureBox1.Image = newbmp;
 pictureBox1.Refresh();
                    pictureBox1.Refresh();                   
 }
                }
 else
                else
 {
                {
 //放大缩小处理
                    //放大缩小处理
 int width = bmp.Width + pictureBox1.Location.X + e.X - mousePressPoint.X;
                    int width = bmp.Width + pictureBox1.Location.X + e.X - mousePressPoint.X;
 int height = bmp.Height + pictureBox1.Location.Y + e.Y - mousePressPoint.Y;
                    int height = bmp.Height + pictureBox1.Location.Y + e.Y - mousePressPoint.Y;
 if (width > 0 && height > 0)
                    if (width > 0 && height > 0)
 {
                    {
 bmp = new Bitmap(bmp, new Size(width, height));
                        bmp = new Bitmap(bmp, new Size(width, height));
 pictureBox1.Image = bmp;
                        pictureBox1.Image = bmp;
 pictureBox1.Refresh();
                        pictureBox1.Refresh();
 }
                    }
 }
                }
 
                
 }
            }
 }
        }
我是在Form上放置了一个PictureBox, 然后进行移动。 刚开始的时候我是用整个图来画的, 发现当图片大到一个程度之后就可以闪了,尽管PictureBox有一个双缓冲。。。后来仔细想想, 其实完全可以在图片移动的过程中仅仅绘制一部分,也就是ClientSize的那一块, 试验了一下 , 效果果然不错。(在图片巨大无比的时候, 内存会上涨到250M,这个时候拖动的平滑感就欠缺一点了)
核心代码如下:
 private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
private void pictureBox1_MouseMove(object sender, MouseEventArgs e) {
        { 
             if (e.Button == MouseButtons.Left)
            if (e.Button == MouseButtons.Left) {
            { //移动处理
                //移动处理 if (!isLeftCtrlKeyDown)
                if (!isLeftCtrlKeyDown) {
                { offset.Width += e.X - mousePressPoint.X;
                    offset.Width += e.X - mousePressPoint.X; offset.Height += e.Y - mousePressPoint.Y;
                    offset.Height += e.Y - mousePressPoint.Y; mousePressPoint = e.Location;
                    mousePressPoint = e.Location; Bitmap newbmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
                    Bitmap newbmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height); Graphics g = Graphics.FromImage(newbmp);
                    Graphics g = Graphics.FromImage(newbmp); //重绘一小段图片
                    //重绘一小段图片 g.DrawImage(bmp, new Rectangle(0, 0, this.ClientSize.Width, this.ClientSize.Height),
                    g.DrawImage(bmp, new Rectangle(0, 0, this.ClientSize.Width, this.ClientSize.Height), -offset.Width, -offset.Height, this.ClientSize.Width, this.ClientSize.Height, GraphicsUnit.Pixel);
                        -offset.Width, -offset.Height, this.ClientSize.Width, this.ClientSize.Height, GraphicsUnit.Pixel); pictureBox1.Image = newbmp;
                    pictureBox1.Image = newbmp; pictureBox1.Refresh();
                    pictureBox1.Refresh();                    }
                } else
                else {
                { //放大缩小处理
                    //放大缩小处理 int width = bmp.Width + pictureBox1.Location.X + e.X - mousePressPoint.X;
                    int width = bmp.Width + pictureBox1.Location.X + e.X - mousePressPoint.X; int height = bmp.Height + pictureBox1.Location.Y + e.Y - mousePressPoint.Y;
                    int height = bmp.Height + pictureBox1.Location.Y + e.Y - mousePressPoint.Y; if (width > 0 && height > 0)
                    if (width > 0 && height > 0) {
                    { bmp = new Bitmap(bmp, new Size(width, height));
                        bmp = new Bitmap(bmp, new Size(width, height)); pictureBox1.Image = bmp;
                        pictureBox1.Image = bmp; pictureBox1.Refresh();
                        pictureBox1.Refresh(); }
                    } }
                } 
                 }
            } }
        } 
                    
                     
                    
                 
                    
                 
        
 
             
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号