2016-10-03 67 views
0

我有一些原始的传感器数据是在一个单维的字节数组。数据实际上是IEEE单精度浮点格式。我知道X轴和Y轴的边距,我想从我的数据创建Windows位图(灰度 - 只有一个包含亮度数据的颜色平面)。如何在C#中从头开始创建Windows位图?

这里就是我试图至今:

 var bitmap = new Bitmap(xAxis, yAxis, PixelFormat.Format16bppGrayScale); 
     var pixelReader = GetPixelReader(hdu.MandatoryKeywords.BitsPerPixel); 
     using (var stream = new MemoryStream(hdu.RawData, writable: false)) 
      { 
      using (var reader = new BinaryReader(stream, Encoding.ASCII)) 
       { 
       for (var y = 0; y < yAxis; y++) 
        { 
        for (var x = 0; x < xAxis; x++) 
         { 
         var pixel = pixelReader(reader); 
         var argb = Color.FromArgb(pixel, pixel, pixel); 
         bitmap.SetPixel(x, y, argb); 
         } 
        } 
       } 
      } 
     return bitmap; 

pixelReader是一个委托并定义为:

private static int ReadIeeeSinglePrecision(BinaryReader reader) 
     { 
     return (int) reader.ReadSingle(); 
     } 

当我运行这段代码,我上线那里得到一个异常InvalidArgumentException我尝试设置像素值。我在调试器中加入了它,x = 0,y = 0,像素= 0。它没有说哪个参数是无效的或为什么(谢谢微软)。

很显然,我做错了事实上,我怀疑可能有更有效的方法来解决这个问题。我将不胜感激任何建议。由于我无法完全理解的原因,我发现这些代码非常具有挑战性。

+1

不要使用'SetPixel'进行批量操作,[改用'LockBits'](http://stackoverflow.com/questions/1563038/fast-work-with-bitmaps-in-c-sharp)。此外,请[获取例外详情](https://blogs.msdn.microsoft.com/saraford/2008/08/07/did-you-know-you-can-copy-the-exception-details-with-一键从异常助手-276 /)的InvalidArgumentException并将其包括在这里。这将有助于大大发现问题所在。 –

+0

@ScottChamberlain是的,我已经阅读过文档中的内容,但我认为这只是一个表现问题,不是吗?我需要先解决问题,然后再优化它,或者永远不要。说实话,LockBits的文档对我来说更不明智。 –

+1

你在argb中获得一个有效的颜色还是只是得到一个null?我怀疑你的问题更早,但隐式类型变量模糊了这个问题。我强烈建议使用实际的类型,而不是将所有的代码都定义为变量,而这些代码中的大部分/全部都不需要。 – AgapwIesu

回答

0

确定这里是最后的工作。基于从马克·道森的回答带到这个问题代码:https://social.msdn.microsoft.com/Forums/vstudio/en-US/10252c05-c4b6-49dc-b2a3-4c1396e2c3ab/writing-a-16bit-grayscale-image?forum=csharpgeneral

private static Bitmap CreateBitmapFromBytes(byte[] pixelValues, int width, int height) 
    { 
    //Create an image that will hold the image data 
    Bitmap pic = new Bitmap(width, height, PixelFormat.Format16bppGrayScale); 
    //Get a reference to the images pixel data 
    Rectangle dimension = new Rectangle(0, 0, pic.Width, pic.Height); 
    BitmapData picData = pic.LockBits(dimension, ImageLockMode.ReadWrite, pic.PixelFormat); 
    IntPtr pixelStartAddress = picData.Scan0; 
    //Copy the pixel data into the bitmap structure 
    System.Runtime.InteropServices.Marshal.Copy(pixelValues, 0, pixelStartAddress, pixelValues.Length); 
    pic.UnlockBits(picData); 
    return pic; 
    } 

于是我修改了我自己的代码从IEEE浮点数据转换成16个整数,然后直接从创建位图,像这样:

 var pixelReader = GetPixelReader(hdu.MandatoryKeywords.BitsPerPixel); 
     var imageBytes = new byte[xAxis * yAxis * sizeof(Int16)]; 
     using (var outStream = new MemoryStream(imageBytes, writable: true)) 
     using (var writer = new BinaryWriter(outStream)) 
     using (var inStream = new MemoryStream(hdu.RawData, writable: false)) 
     using (var reader = new BinaryReader(inStream, Encoding.ASCII)) 
      for (var y = 0; y < yAxis; y++) 
       { 
       for (var x = 0; x < xAxis; x++) 
        { 
        writer.Write(pixelReader(reader)); 
        } 
       } 
     var bitmap = CreateGreyscaleBitmapFromBytes(imageBytes, xAxis, yAxis); 
     return bitmap; 

这似乎也解决了评论中强调的效率问题。

+0

一旦我尝试显示我创建的图像,那不起作用。所以我仍然有办法解决这个问题。当我找到更好的解决方案时,我会更新我的答案。 –

相关问题