本帖最后由 u011672494 于 2014-10-29 09:12:52 编辑

解决方案 »

  1.   

    csv格式读取读成数组
    lockbits移动块~
      

  2.   

    一副灰度图 像素点就是上面的数据啊
    但是其实我的数据有6000*10000个。。我试了用SetPixel画 直接outofmemory了
      

  3.   

    一副灰度图 像素点就是上面的数据啊
    但是其实我的数据有6000*10000个。。我试了用SetPixel画 直接outofmemory了换个64位的系统,内存就没问题了。另外换用bitmapdata操作。
      

  4.   

    一副灰度图 像素点就是上面的数据啊
    但是其实我的数据有6000*10000个。。我试了用SetPixel画 直接outofmemory了分批画 如10000个画一次,如果还溢出,则每10000个画完就保存本地磁盘,再重新打开画。(虽然我觉得直接画也不该溢出的)
      

  5.   

    不会溢出 溢出的原因是我画好后再对panel绘上这个图 这时候就溢出了。我想问setpixel速度太慢了  如何改善
      

  6.   

    下面的代码是画了一个6000*10000的随机灰度图,你可以参考
    // 初始化6000*10000个0-99的数字
    int width = 6000, height = 10000;
    var max = 100;
    var rnd = new Random();
    var data = Enumerable.Range(0, width * height).Select(_ => rnd.Next(max)).ToArray();// 8bit索引方式位图,设置灰度调色板
    var fmt = PixelFormat.Format8bppIndexed;
    var bmp = new Bitmap(width, height, fmt);
    var palette = bmp.Palette;
    for (var i = 0; i < 256; i++)
    {
        palette.Entries[i] = Color.FromArgb(i, i, i);
    }
    bmp.Palette = palette;// 把数据映射到256灰度,unsafe填充到位图
    var step = 255f / (max - 1);
    var bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, fmt);
    unsafe
    {
        var p = (byte*)bmpData.Scan0;
        for (var i = 0; i < data.Length; i++)
        {
            *p = (byte)(step * data[i]);
            p++;
        }
    }
    bmp.UnlockBits(bmpData);
    bmp.Save(@"e:\x.png");
      

  7.   

    很给力 之前数据是读出来以泛型的double二维数组形式 再将其setpixel 保存  时间大约1分半。用了您的方法  我数据读取后就以double[]数组保存,然后颜色映射过去,时间18s,(两者进行时电脑都不做其他事情 等待的状况下测试)
      

  8.   

    我感觉读取文件的地方还有优化的空间,那段代码release模式我这里(CPU 2.66GHz,内存1600MHz)执行的时间是5s左右。如果不包括生成数据,时间只需2.3s
      

  9.   

     /// <summary>
            /// 从指定的路径保存成一维数组
            /// </summary>
            /// <param name="path"></param>
            /// <returns></returns>
          private double[] Read(string path)
            {
                double[] arrary = new double[bmpHeight * bmpWidth];
                int row = 0;//行
                int col = 0;//lie            FileStream fs;
                fs = new FileStream(path, FileMode.Open, FileAccess.Read);
                StreamReader sr;
                sr = new StreamReader(fs);
                while (!sr.EndOfStream)
                {
                    string[] arr = sr.ReadLine().Split(',');
                    col = arr.Length;
                    for (int x = 0; x < col - 1; x++)
                    {
                        if (arr[x] != "")
                        {
                           arrary[row*bmpWidth+x] = Convert.ToDouble(arr[x]);
                        }
                    }
                    row++;
                }
                sr.Close();
                fs.Close();            return arrary;
            }
    这是我的数据读取方式
      

  10.   

    代码优化了下,用了并发,我这里是8s左右(数据是随机生成的6000*10000的csv,0.0-1.0间的浮点数)。而且因为边读边处理,内存占用小了很多。int width = 6000, height = 10000;// 8bit索引方式位图,设置灰度调色板
    var fmt = PixelFormat.Format8bppIndexed;
    var bmp = new Bitmap(width, height, fmt);
    var palette = bmp.Palette;
    for (var i = 0; i < 256; i++)
    {
        palette.Entries[i] = Color.FromArgb(i, i, i);
    }
    bmp.Palette = palette;var step = 255f;
    var count = height; // 任务计数器
    var bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, fmt);
    using (var sr = new StreamReader(@"e:\data.txt"))
    {
        var ptr = bmpData.Scan0;
        while (!sr.EndOfStream)
        {
            // 每次读一行数据,在其它线程执行SetData,之后计数器减一
            var line = sr.ReadLine();
            var p = ptr;
            Task.Factory.StartNew(() => {
                SetData(p, step, line); Interlocked.Decrement(ref count);
            });
            ptr += bmpData.Stride;
        }
    }// 等待所有任务完成(计数器清零)
    while (count > 0) { Thread.Sleep(20); }bmp.UnlockBits(bmpData);
    bmp.Save(@"e:\x.png");// 处理一行数据,把数据映射到256灰度,unsafe填充到位图
    private unsafe void SetData(IntPtr ptr, float step, string line)
    {
        var p = (byte*)ptr;
        var data = line.Split(',');
        for (var i = 0; i < data.Length; i++)
        {
            *p = (byte)(step * float.Parse(data[i]));
            p++;
        }
    }
      

  11.   

    new FileStream(path, FileMode.Open, FileAccess.Read);
    改为 File.OpenRead(path);
      

  12.   


    嗯 不过代码这里有点小问题吧
    Interlocked.Decrement(ref count);这句放到ptr += bmpData.Stride;后面 就行啦
      

  13.   

    那个是为了线程工作完成后计数器减一的,放外面就不对了,会导致unlockbits的时候工作线程可能还没有完全结束
      

  14.   

    那个是为了线程工作完成后计数器减一的,放外面就不对了,会导致unlockbits的时候工作线程可能还没有完全结束我这边试了  放里面 count的值始终是height。 因此一直在循环内  放在外面才是正常的!