【问题标题】:System.Drawing.Bitmap to Byte ArraySystem.Drawing.Bitmap 到字节数组
【发布时间】:2014-03-13 12:20:36
【问题描述】:

我有一个来自资源的位图,需要将它放在一个字节数组中。我有一个 SetPixel Methode 用于操作字节数组中的像素。这一切都很好。我想要做的是首先在数组中加载一张图片,以便以后可以对其进行操作。

为了实现这一点,我做了很多尝试。首先我有什么:

var resources = new ComponentResourceManager(typeof(Game));
var bmp = (Bitmap)(resources.GetObject("imgBall.Image"));

到目前为止唯一没有给我错误消息(但显示图片错误)的是:

width = (int)bmp.Width;
height = (int)bmp.Height;
System.Windows.Media.PixelFormat pf = PixelFormats.Rgb24;
rawStride = (width * pf.BitsPerPixel + 7) / 8;
byte[] pixelData = new byte[rawStride * height];    

MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
pixelData = ms.GetBuffer();

然后我尝试了可以​​在堆栈溢出中找到的解决方案:

ImageConverter imgConverter = new ImageConverter();
pixelData = (System.Byte[])imgConverter.ConvertTo(bmp, Type.GetType("System.Byte[]"));

这会改变pixelData的大小,所以我不能再使用它了……

using (MemoryStream memory = new MemoryStream())
            {
                bmp.Save(memory, ImageFormat.Bmp);
                memory.Position = 0;
                var bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                memory.Seek(0, SeekOrigin.Begin);
                bitmapImage.StreamSource = memory;
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.EndInit();
                int stride = width * ((bitmapImage.Format.BitsPerPixel + 7) / 8);                                

                bitmapImage.CopyPixels(pixelData, stride, 0);                
            }

在 CopyPixels 行,我很困惑:当我从上方 (84) 获取 rawStride 时,我收到一条错误消息,它需要至少为 112。当我计算 bitmapImage (112) 的步幅时,它会抱怨它需要最小 3136。我什至尝试手动输入步幅数,它总是需要更大。

我觉得我在这里完全理解错了。

【问题讨论】:

  • 我知道你说过你已经有一个 SetPixel 方法可以工作,但我不得不问为什么你不只是使用 Bitmap 已经有的 SetPixel 方法?似乎这会消除您在这里遇到问题的复杂性......
  • 对于设置字节,它可能更容易(对你来说更清晰)循环遍历像素手动获取字节数据。我想您的许多尝试失败的原因可能是当将Bitmap 转换为内存流或类似内容时,它会创建有关您实际上不想要的格式的元数据。;
  • Bitmap 的 SetPixel 方法不适用于 windows phone。我应该写到我以后也需要在 windows phone 上使用它。
  • dmitry,该解决方案适用于 lockbits。那是记者很慢。但如果其他一切都失败了,我会试一试,谢谢你的链接。克里斯,我会尝试循环遍历像素并发布我的结果,谢谢。

标签: c# arrays wpf bitmap picturebox


【解决方案1】:
public string BitmapToBase64(BitmapImage bi)
{
  MemoryStream ms = new MemoryStream();
  PngBitmapEncoder encoder = new PngBitmapEncoder();
  encoder.Frames.Add(BitmapFrame.Create(bi));
  encoder.Save(ms);
  byte[] bitmapdata = ms.ToArray();

  return Convert.ToBase64String(bitmapdata);
}

这应该做的事情。如果这是您想要的,只需返回 byteArray。

【讨论】:

  • Max,我尝试了您的解决方案,但我不返回字符串,而是返回数组本身。问题似乎是字节数组 pixelData 最初的大小为 2352,但从您的方法返回的数组只有 285,类似于使用 ImageConverter 的尝试。
  • 嗯。看到了,自己没试过。我使用这种方法,将位图/图片转换并保存为带有 Base64 字符串的 xml。
猜你喜欢
  • 2011-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-19
  • 1970-01-01
  • 2021-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多