【问题标题】:create bitmap with filestream使用文件流创建位图
【发布时间】:2011-03-27 13:45:06
【问题描述】:

我需要使用文件流创建位图。到目前为止,我有这个代码:

 using (FileStream bmp = File.Create(@"C:\test.bmp"))
        {
            BinaryWriter writer = new BinaryWriter(bmp);
            int i = 0;

          //  writer.Write((char*)&fileheader, sizeof(fileheader));
          //  writer.Write((char*)&infoheader, sizeof(infoheader));

            for (int rows = 0; rows < 160; rows++)
            {
                for (int cols = 0; cols < 112; cols++)
                {
                    writer.Write(CamData[i]);
                    i++;
                }
            }

            bmp.Close();
        }

但我仍然需要位图的标题信息。我的问题是,我不知道如何在 C# 中实现它们。我知道分辨率(320 x 240)和我的像素数据是 ushort 数组中给出的 16 位灰度值。

谢谢

【问题讨论】:

    标签: c# header bitmap filestream


    【解决方案1】:

    有一个构造函数可以从字节数组创建Bitmap。然后,使用Bitmap 的成员函数将其保存为bmp 格式的流。请参阅herehere

    【讨论】:

    • 我不能使用 Bitmap 类,因为我没有字节数组!我有 USHORT 值
    • 当我使用 PixelFormat.Format16bppGrayScale 我总是得到一个 gdi+ 错误。其他像素格式效果很好。使用 PixelFormat.Format24bppRgb 后我得到这个结果:第一行中的图片 3 次![test.bmp][1] [1]:i.imgur.com/Cls1e.png
    【解决方案2】:

    似乎 System.Drawing 类不喜欢处理 16 位灰度,可能是因为底层 GDI+ 对象将其颜色分量视为 0 到 255 之间的值,而 16 位灰度实际上意味着您可以拥有 65535 种灰度。

    这意味着您有两个选择:要么切换到 PresentationCore,然后使用它创建图像,要么将值下采样到字节大小并制作 8 位灰度图像。

    this answer 中解释了第一个选项。

    第二个选项包括三个步骤:

    • 将数据下采样到每像素 1 个字节
    • 生成灰度调色板(因为 8 位灰度在技术上是调色板)
    • 根据您的下采样数据和调色板创建一个 8 位索引图像。

    代码:

    Byte[] camDataBytes = new Byte[CamData.Length];
    for(Int32 i = 0; i < camData.Length; i++)
        camDataBytes[i] = (Byte)(CamData[i] / 256);
    
    Color[] palette = new Color[256];
    for(Int32 i = 0; i < 256; i++)
        palette[i] = Color.FromArgb(i,i,i);
    
    using(Bitmap b = BuildImage(camDataBytes, 320, 240, 320, PixelFormat.Format8bppIndexed, palette, null))
        b.Save(@"C:\test.bmp", ImageFormat.Bmp); 
    

    BuildImage 函数可以从字节数组中创建图像,可以在 here 中找到。假设图像数据是紧凑的 320x240,最终字节数组的步幅应该正好是宽度,因此是 320。

    【讨论】:

      【解决方案3】:

      试试这个:

      /// From stream to bitmap...
      FileStream fs = new FileStream("test.bmp", FileMode.Open);
      Bitmap bmp = new Bitmap(fs);
      

      【讨论】:

      • 但我不想打开现有位图。我想用文件流创建一个新的位图
      • @Klaus 将 FileMode 更改为 FileMode.Create(或任何其他合适的选择)。无论如何,我想知道 fs.Close();可以在上面两行之后立即发出,或者在使用位图时是否应该保持流打开。
      猜你喜欢
      • 2015-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多