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可以会刷两次
------解决方案--------------------双缓冲是最好的方法,以前做的东西也是用双缓冲解决这个问题的
序列化可以直接以二进制实现绘图,而且是可以是 矢量图,是个好方法
不过我没有做成过,所以惭愧下。