最近在研究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);
        }
    }
}

解决方案 »

  1.   

    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);
      

  2.   

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

  3.   


    额...但是如果依然用drawimage的方法画图的话,还是具有掉帧....请问bitblt咋弄呢?
      

  4.   

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

  5.   


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

  6.   

    把timer 弄成17ms ,运行比较还是跟1ms一样的...至少我这里测出来是这样的...
      

  7.   

    你也把这些事当真了,如果追求完美,BitBlt速度肯定快,实际上.Net中也是有解决办法的Graphics不是也有Clip方法么?如果你刻意用BitBlt去解决,不如复制一段C++代码贴这,让人翻译如果C#中也能达到你的效果,那么非要转入DLL中就没什么意思了,另外提高阶的问题也是有学问的,因为别人在回答你的问题时,也需要考虑你的"文化层次",给你扔一段你看不懂的代码,首先是对你的不负责.我知道用GDI函数,解决你类似的问题很容易,不外乎写一段代码,也挺费时间,示例好写,翻译成C#就比较麻烦了,至少复制许多API),更关键是,未必能说明问题,也就是让你明白,比如你把一个什么类icon的复制了四遍,也许不是icon,不过四遍已经让人很头疼了,无外乎是个擦除么,擦除一个容易吧,VERY,擦四个,坐标运算??
      

  8.   

    实际上...我也有试过自己去弄一遍...只是画出了一团黑色...不知道怎么弄下去了.
    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);
      

  9.   

    [yabao=sacv][/yabao]
    我做截图速度太慢了。。怎么加速啊