C#画图,用虚拟画布太慢,用onPaint重绘时不正常
picturebox加载图片作为地图,图片比较大,目前使用的是1M左右的图. 
 用   DrawImage已经实现了放大缩小功能,但每次放大或者缩小后,一改变窗体大小,图片就恢复成初始大小了,我重载了onpaint 
          protected   override   void   OnPaint(PaintEventArgs   e) 
                         { 
                                     g.DrawImage(pictureBox1.Image,   p1,   p2,   p3,   p4); 
                                     base.OnPaint(e); 
                         } 
 可每次重绘后还是初始大小,需要移动一下鼠标才能正常   
 看资料g.DrawImage后需要g.dispose(); 
 可我dispose后在onpaint中就出问题了,必须重新实例化一下g 
    g   =   pictureBox1.CreateGraphics(); 
 每次都要实例化g吗?   
 试过用虚拟画布,窗体改变大小时到是可以重绘,但实在是太慢了,我内存比较小,256的,处理1M的图,放大或缩小一次要好久,不能忍受,用虚拟画布有什么好处啊?   
------解决方案--------------------          protected override void OnPaint(PaintEventArgs e) 
         { 
             g.DrawImage(pictureBox1.Image, p1, p2, p3, p4); 
             //base.OnPaint(e);//这句屏蔽看看 
         } 
------解决方案--------------------因为你的图片太大,所以应该用双缓冲
------解决方案--------------------只有窗体在重新绘制的时候才会调用OnPaint方法里的代码来绘制,   
 如果当前没有任何一个消息能引发Paint的消息,那么OnPaint方法是不会执行的,   
 当鼠标移动的时候可能会引发重绘的消息,所以才被重绘了.   
 你可以通过Invalidate方法来立刻要求窗体绘制而不用等鼠标事件. 
------解决方案--------------------我虽然没有回答您的问题,但也帮您顶了下,求您给小女几分好吗?我非专业,但需要点分提问啊! 
 呵呵,谢谢!!
------解决方案--------------------问题1:可每次重绘后还是初始大小,需要移动一下鼠标才能正常这个问题应该是没有使用 
     SizeChange这个事件。 应该在这个事件加入重绘事件。加上   
     SetStyle(ControlStyles.ResizeRedraw, true);或 SizeChanged+=delegate 
     {Invalidate();} 
 问题2:这个感觉你说的不是很清楚。 不知道你这个Form与 Picture之间是什么关系。 
     如果Picture.Dock==DockStyle.Fill. 你根本不用重写Form1的OnPaint属性。    
     只要添加pictureBox1_Paint事件这可以了。 
     Image  bmp = Image.FromFile(@ "G:\地图处理\地图缩放 
     \bin\Debug\map\ditu.jpg "); 
     这句不能加在pictureBox1_Paint这个事件里, 因为它只要程序启动时读一次就行 
     了。而pictureBox1_Paint 这个事件是要经常被调用的。 
     Bitmap bmp=null; 
       private void Form1_Load(object sender, EventArgs e) 
 	{   
        bmp = Image.FromFile(@ "G:\地图处理\地图缩放\bin\Debug\map\ditu.jpg "); 
 	}   
      private void pictureBox1_Paint(object sender, PaintEventArgs e) 
 	{   
        Graphics g = e.Graphics; 
        g.DrawImage(bmp, 0, 0, pictureBox1.Width, pictureBox1.Height); 
 	} 
 问题3:虚拟画布的问题。虚拟画布是指在内存中定义好一个位图,图形做什么操作先在虚拟画    布上进行,最后再一次性地DrawImage, 它更适合有变化频繁的图形的程序, 而且    这个图形都是很小的, 至少在你的这个项目中,它 并不适用, 反而会影响图形显 
     示的速度。 
 建议 :使用双缓冲。在构造函数中加入   
 			SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer | ControlStyles.ResizeRedraw, true);
------解决方案--------------------用直接 pictureBox1.Refresh();因为用mousedown可以会刷两次
------解决方案--------------------双缓冲是最好的方法,以前做的东西也是用双缓冲解决这个问题的  
 序列化可以直接以二进制实现绘图,而且是可以是 矢量图,是个好方法 
 不过我没有做成过,所以惭愧下。