合成图片源码:
elements是6个Bitmap对象数组合成一张图片的时间约莫1秒,由于项目每次要多次合成图片,每次要耗费时间7、8秒,速度太慢,希望高手提供更好的方法!this.s_image = new Bitmap(this.Body.Width, this.Body.Height);
                Graphics g = Graphics.FromImage(this.s_image);
                for (int i = 0; i < elements.Length; i++)
                {
                    if (elements[i] != null)
                    {
                        if (i != 4)
                        {
                            g.DrawImage(elements[i], p_list.PointArray[i].X, p_list.PointArray[i].Y, this.Body.Width, this.Body.Height);
                        }
                        else
                        {
                            if (has_glassses)
                            {
                                g.DrawImage(elements[i], p_list.PointArray[i].X, p_list.PointArray[i].Y, this.Body.Width, this.Body.Height);
                            }
                        }
                    }
                }
                g.Dispose();

解决方案 »

  1.   

    这是个头痛的问题
    我曾经处理两张大图融合(要做个特效出来),花了10几秒
    C++如果让我用估计也快不到哪去
    对Photoshop的图片处理技术一直很眼红
    曾经尝试过国外牛人们写的Paint(C#),速度真是慢到家了,要不Photoshop怎么能卖钱呢
      

  2.   

       你所说的拼接图像,其实是简单组成一个新图(一个矩阵),没有其它复杂操作吧,那就可以先创建一个目标的位图,可以用API或unsafe code快速将原来的6块图片拷到目标位图的对应位置啊~~
        年末,有点忙要赶回家~代码有时间给你上啊~O(∩_∩)O哈哈~
      

  3.   

    到我的资源去下一段代码,BITMAP 与 数组之间的转换,然后在数组内进行操作,速度很快的
      

  4.   

    拼接图片?可以学习下Bitmap图片的格式,然后直接把图像Data部分合并起来。按需要生成头结构,保存。
      

  5.   

    你的方法不对。绘制是很慢的,所以合成过程在内存中进行.
    用 Bitmap 中的 LockBits 索定 this.s_image ,
    然后 把DrawImage 换成直接操作 LockBits的指针数据就可以 了。
    速度应该可以提高50倍,或更多
      

  6.   

    GDI+ 的DrawImage 好像比较慢
    如果没有透明和拉伸的需求,建议直接用GDI的函数
      

  7.   

    忘了说明了所有的原始图片都是PNG格式的有透明地方!必须保持透明!
      

  8.   

    还用了其他方法:
    1.利用BitBlt合成图片
    public void SetImage()
    {
    DateTime dt = DateTime.Now;
                if (this.Body != null)
                {
                    this.s_image = new Bitmap(this.Body.Width, this.Body.Height);
                    using (Graphics g = Graphics.FromImage(this.s_image))
                    {
                        IntPtr hdc = g.GetHdc();
                        DateTime dt4 = DateTime.Now;
                        IntPtr memdc = Win32Support.CreateCompatibleDC(hdc);
                        Console.WriteLine("创建层:" + (DateTime.Now - dt4));
                        for (int i = 0; i < elements.Length; ++i)
                        {
                            if (elements[i] != null)
                            {
                                DateTime dt3 = DateTime.Now;
                                Win32Support.SelectObject(memdc, elements[i].GetHbitmap());
                                Console.WriteLine("创建第" + i + "层:" + (DateTime.Now - dt3));
                                using (Graphics memDc = Graphics.FromHdc(memdc))
                                {
                                    IntPtr shdc = memDc.GetHdc();
                                    if (i != 4)
                                    {
                                        DateTime dt1 = DateTime.Now;
                                        Win32Support.BitBlt(hdc, p_list.PointArray[i].X, p_list.PointArray[i].Y, this.Body.Width, this.Body.Height,
                        shdc, 0, 0, Win32Support.TernaryRasterOperations.SRCCOPY);
                                        Console.WriteLine("绘制第" + i + "层:" + (DateTime.Now - dt1));
                                    }
                                    else
                                    {
                                        if (has_glassses)
                                        {
                                            DateTime dt1 = DateTime.Now;
                                            Win32Support.BitBlt(hdc, p_list.PointArray[i].X, p_list.PointArray[i].Y, this.Body.Width, this.Body.Height,
                             shdc, 0, 0, Win32Support.TernaryRasterOperations.SRCCOPY);
                                            Console.WriteLine("绘制第" + i + "层:" + (DateTime.Now - dt1));
                                        }
                                    }
                                    memDc.ReleaseHdc(shdc);
                                }
                            }
                        }
                        g.ReleaseHdc(hdc);
                    }
                }
                Console.WriteLine("总共:" + (DateTime.Now - dt));
    }速度没有提高,并只显示最后一层,透明处全部成黑色2.利用BitmapData合成图片public void SetImage(){
    DateTime dt = DateTime.Now;
                if (this.Body != null)
                {
                    int w = Convert.ToInt32(this.Body.Width * _scale);
                    int h = Convert.ToInt32(this.Body.Height * _scale);                this.s_image = new Bitmap(w, h);
                    BitmapData dataOut = this.s_image.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                    for (int i = 0; i < elements.Length; ++i)
                    {
                        if (elements[i] != null)
                        {
                            if (i != 4)
                            {
                                try
                                {
                                    DateTime dt1 = DateTime.Now;
                                    Rectangle rect = new Rectangle(0, 0, w, h);
                                    DrawImage(ref dataOut, elements[i], rect);
                                    Console.WriteLine("绘制第" + i + "层:" + (DateTime.Now - dt1));
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine(ex.StackTrace);
                                }
                            }
                            else
                            {
                                if (has_glassses)
                                {
                                    DateTime dt1 = DateTime.Now;
                                    Rectangle rect = new Rectangle(0, 0, w, h);
                                    DrawImage(ref dataOut, elements[i], rect);
                                    Console.WriteLine("绘制第" + i + "层:" + (DateTime.Now - dt1));
                                }
                            }
                        }
                    }
                    this.s_image.UnlockBits(dataOut);
                }
                Console.WriteLine("共用时间:" + (DateTime.Now - dt));
    }
    private void DrawImage(ref BitmapData dataOut, Bitmap btpIn, Rectangle rect)
            {
                BitmapData dataIn = btpIn.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                unsafe
                {
                    byte* pIn = (byte*)(dataIn.Scan0.ToPointer());
                    byte* pOut = (byte*)(dataOut.Scan0.ToPointer());                for (int y = 0; y < dataIn.Height; y++)
                    {
                        for (int x = 0; x < dataIn.Width; x++)
                        {
                            if ((int)pIn[4] != 0)
                            {
                                pOut[0] = pIn[0];
                                pOut[1] = pIn[1];
                                pOut[2] = pIn[2];
                                pOut[4] = pIn[4];
                            }
                            pIn += 3;
                            pOut += 3;
                        }
                        pIn += dataIn.Stride - dataIn.Width * 3;
                        pOut += dataOut.Stride - dataOut.Width * 3;
                    }
                }
                btpIn.UnlockBits(dataIn);
            }
    速度没有提高,也是显示最后一层,透明处全部成白色还没有其他方法!现在项目一运行就的等待10多秒钟!慢死了
      

  9.   


    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;using System.Drawing.Imaging;
    namespace neicun
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }        private void button1_Click(object sender, EventArgs e)
            {
                Bitmap m_Bmp = new Bitmap("d:\\nvhai.bmp");
                int h = m_Bmp.Height;
                int w = m_Bmp.Width;            Bitmap bmpOut = new Bitmap(w, h, PixelFormat.Format24bppRgb);            BitmapData dataIn = m_Bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                BitmapData dataOut = bmpOut.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);            unsafe
                {
                    byte* pIn = (byte*)(dataIn.Scan0.ToPointer());
                    byte* pOut = (byte*)(dataOut.Scan0.ToPointer());                for (int y = 0; y < dataIn.Height; y++)
                    {
                        for (int x = 0; x < dataIn.Width; x++)
                        {                        pOut[1] = pOut[0];
                            pOut[2] = pOut[0];                        pIn += 3;
                            pOut += 3;
                        }                    pIn += dataIn.Stride - dataIn.Width * 3;
                        pOut += dataOut.Stride - dataOut.Width * 3;
                    }
                }            bmpOut.UnlockBits(dataOut);
                m_Bmp.UnlockBits(dataIn);
                pictureBox1.Image = bmpOut;
            }
        }
    }
    指针法,要勾上允许执行不安全代码,还有个内存法,不过现在找不到代码了
      

  10.   


     //内存法,大概2.5毫秒一张.
            private void memory_Click(object sender, EventArgs e)
            {
                if (curBitmap != null)
                {
                    myTimer.ClearTimer();
                    myTimer.Start();
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height * 3;
                    byte[] rgbValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
                    double colorTemp = 0;
                    for (int i = 0; i < rgbValues.Length; i += 3)
                    {
                        colorTemp = rgbValues[i + 2] * 0.299 + rgbValues[i + 1] * 0.587 + rgbValues[i] * 0.114;
                        rgbValues[i] = rgbValues[i + 1] = rgbValues[i + 2] = (byte)colorTemp;
                    }
                    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                    myTimer.Stop();
                    timeBox.Text = myTimer.Duration.ToString("####.##") + " 毫秒"; 
                    Invalidate();
                }
            }
      

  11.   

    我大概明白了,你有36张A4大小的图片,要一层一层涂在一起。
    也就是要绘制36张A4大小的图。
    A4大小2479x3508像素
    每个像素4个通道。
    每次绘制,需要计算颜色重叠,也就是2479*3508*4*3*36=3756815424次乘法运算。
    37亿次乘法运算。
    cpu累死了,大哥。怎么着也要6,7秒啊。
    除非你能自己重写图片重叠的算法,并且能优化它。
    万一你写出来了,记得去申请个专利,卖个100w没问题。
      

  12.   

    其实,有快速的方法,不过你要支持透明图层就麻烦太大了。
    首先,检测最后一张图片,完全不透明的点,先绘制上去,因为他们会把前面35张都挡掉,也就是前面35张都百画了。
    然后检测透明点(alpha不为255的点)。
    对于每一个不透明点,检测35--1张,发现有alpha==255的点,则不再往前检测。比如,23-35的这一点alpha值都小于255,22张的这一点alpha为255.则只需要计算22--36的像素半透明融合。
    这个算法可以在非常大程度上改进速度,但是也要看你的36张图具体而言。比如第36张为全不透明,那几十毫秒就结束了。
    如果36张全他妈的是半透明的,那没办法,10s钟像素覆盖融合算法自己找找吧,我写过,但是忘记扔哪里去了。
      

  13.   

    我合成图片的目的不是显示到屏幕上,而是将PNG非透明部分合成在一起成新的图片!并不是拼接而是合层透明显示!
      

  14.   

    不知道你的合成图片是嘛意思???
    为什么要一个象素一个象素的弄。直接画整个图片不可以嘛??g.DrawImage(picture)