关于C#中适用BITBLT的问题...

huzepiao 2012-04-04 11:46:18
最近在研究GDI+
在移动一张贴图的时候发现.drawimage()很卡..
后来用了双缓冲,感觉好多了,但还是觉得有点慢..
请问怎么使用bitblt把一张图绘到另外一张图中..

弄了好久都找不到可以参考的C#源码...压力大
P.s. 源代码在此,如果有可以改进的地方希望指出,谢谢



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
SetStyle(ControlStyles.OptimizedDoubleBuffer, true); //默认启动双缓冲
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.


haha = new Bitmap(panel1.Width, panel1.Height);
g = Graphics.FromImage(haha);

pang = panel1.CreateGraphics();
}
Graphics g;
int x = 0;
Image haha;
Graphics pang;//panel1

private void timer1_Tick(object sender, EventArgs e)
{
x += 3;
timer1.Interval = 1;
Invalidate();
Draw();
}

private void Draw()
{
using (Graphics g = Graphics.FromImage(haha))
{
g.Clear(Color.White);
g.DrawImage(Properties.Resources._2, -x, 100);
g.DrawImage(Properties.Resources._2, x, 100);
g.DrawImage(Properties.Resources._2, x, 0);
g.DrawImage(Properties.Resources._2, -x, -x);
g.Dispose();
}
}
protected override void OnPaint(PaintEventArgs e)
{
Draw();
pang.DrawImage(haha, Point.Empty);
}
}
}
...全文
559 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
千年草 2012-12-28
  • 打赏
  • 举报
回复
能截。。。但总感觉速度很慢。。求解
千年草 2012-12-28
  • 打赏
  • 举报
回复
引用 9 楼 jointan 的回复:
你也把这些事当真了,如果追求完美,BitBlt速度肯定快,实际上.Net中也是有解决办法的Graphics不是也有Clip方法么? 如果你刻意用BitBlt去解决,不如复制一段C++代码贴这,让人翻译 如果C#中也能达到你的效果,那么非要转入DLL中就没什么意思了, 另外提高阶的问题也是有学问的,因为别人在回答你的问题时,也需要考虑你的"文化层次",给你扔一段你看不懂的代码,首先……
[yabao=sacv][/yabao] 我做截图速度太慢了。。怎么加速啊
huzepiao 2012-04-05
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]
你也把这些事当真了,如果追求完美,BitBlt速度肯定快,实际上.Net中也是有解决办法的Graphics不是也有Clip方法么?

如果你刻意用BitBlt去解决,不如复制一段C++代码贴这,让人翻译

如果C#中也能达到你的效果,那么非要转入DLL中就没什么意思了,

另外提高阶的问题也是有学问的,因为别人在回答你的问题时,也需要考虑你的"文化层次",给你扔一段你看不懂的代码,首先……
[/Quote]

谢谢你,今天我回学校上课的时候自己想过了一下这个问题...应该有了一个比较明确的答案了,我思考下...
jointan 2012-04-04
  • 打赏
  • 举报
回复
另外我上面介绍的是双缓冲的用法,不是绘制动画的方法,绘制动画还得用BitBlt
jointan 2012-04-04
  • 打赏
  • 举报
回复
BitBlt已经10来年没用过了,忘的差不多了,你的双缓存用的方法不对

不要在OnPaint事件中去Draw,在数据改变时去Draw一个BufferedGraphics(也就是用作缓冲的Graphics),Draw完后调用Invalidate
OnPaint中就写一句:

m_MemoryDC.Render(e.Graphics);


另外,没必要整一个Image出来配合,直接画MemoryDC就可以了.

窗口声明:
protected BufferedGraphics m_MemoryDC = null;
protected BufferedGraphicsContext m_Context = BufferedGraphicsManager.Current;

窗口构造函数中:
this.m_MemoryDC = m_Context.Allocate(this.CreateGraphics(), this.ClientRectangle);
huzepiao 2012-04-04
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

你也把这些事当真了,如果追求完美,BitBlt速度肯定快,实际上.Net中也是有解决办法的Graphics不是也有Clip方法么?

如果你刻意用BitBlt去解决,不如复制一段C++代码贴这,让人翻译

如果C#中也能达到你的效果,那么非要转入DLL中就没什么意思了,

另外提高阶的问题也是有学问的,因为别人在回答你的问题时,也需要考虑你的"文化层次",给你扔一段你看不懂的代码,首……
[/Quote]


实际上...我也有试过自己去弄一遍...只是画出了一团黑色...不知道怎么弄下去了.
Clip方法还是没有搞懂...只是我觉得想到的这么多种方法中bitblt比较接近了,想去尝试一下..


Graphics g1 = Graphics.FromImage(Properties.Resources._2);
Image MyImage = new Bitmap(1024,768, g1);
Graphics g2 = this.CreateGraphics();
IntPtr dc1 = g1.GetHdc();
IntPtr dc2 = g2.GetHdc();
BitBlt(dc2, 0, 0, MyImage.Width, MyImage.Height, dc1, 0, 0, 13369376);
g1.ReleaseHdc(dc1);
g2.ReleaseHdc(dc2);
jointan 2012-04-04
  • 打赏
  • 举报
回复
你也把这些事当真了,如果追求完美,BitBlt速度肯定快,实际上.Net中也是有解决办法的Graphics不是也有Clip方法么?

如果你刻意用BitBlt去解决,不如复制一段C++代码贴这,让人翻译

如果C#中也能达到你的效果,那么非要转入DLL中就没什么意思了,

另外提高阶的问题也是有学问的,因为别人在回答你的问题时,也需要考虑你的"文化层次",给你扔一段你看不懂的代码,首先是对你的不负责.

我知道用GDI函数,解决你类似的问题很容易,不外乎写一段代码,也挺费时间,示例好写,翻译成C#就比较麻烦了,至少复制许多API),更关键是,未必能说明问题,也就是让你明白,比如你把一个什么类icon的复制了四遍,也许不是icon,不过四遍已经让人很头疼了,无外乎是个擦除么,擦除一个容易吧,VERY,擦四个,坐标运算??
huzepiao 2012-04-04
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

引用 6 楼 的回复:

不卡才怪,屏幕刷新60hz就行了,你1ms刷新一次,牛b


这个timer到30ms以下刷新的时间都一样了,1ms刷新跟30ms刷新没啥区别,不然你自己试试吧
[/Quote]


把timer 弄成17ms ,运行比较还是跟1ms一样的...至少我这里测出来是这样的...
huzepiao 2012-04-04
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

不卡才怪,屏幕刷新60hz就行了,你1ms刷新一次,牛b
[/Quote]

这个timer到30ms以下刷新的时间都一样了,1ms刷新跟30ms刷新没啥区别,不然你自己试试吧
feixuyue 2012-04-04
  • 打赏
  • 举报
回复
不卡才怪,屏幕刷新60hz就行了,你1ms刷新一次,牛b
huzepiao 2012-04-04
  • 打赏
  • 举报
回复
额...都没人知道吗...等了一个下午了
huzepiao 2012-04-04
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

另外我上面介绍的是双缓冲的用法,不是绘制动画的方法,绘制动画还得用BitBlt
[/Quote]

额...但是如果依然用drawimage的方法画图的话,还是具有掉帧....请问bitblt咋弄呢?
huzepiao 2012-04-04
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

BitBlt已经10来年没用过了,忘的差不多了,你的双缓存用的方法不对

不要在OnPaint事件中去Draw,在数据改变时去Draw一个BufferedGraphics(也就是用作缓冲的Graphics),Draw完后调用Invalidate
OnPaint中就写一句:

m_MemoryDC.Render(e.Graphics);


另外,没必要整一个Image出来配合,……
[/Quote]


谢谢,我研究下

110,546

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧