我正在尝试向现有图像添加一些矩形。使用以下代码时,一切正常:
var bytes = File.ReadAllBytes("myPath\\input.jpg");
var stream = new MemoryStream(bytes);
using (var i = new Bitmap(stream))
{
using (var graphics = Graphics.FromImage(i))
{
var selPen = new Pen(Color.Blue);
graphics.DrawRectangle(selPen, 10, 10, 50, 50);
i.Save("myPath\\output.jpg", ImageFormat.Jpeg);
}
}
但是将图像保存到相同的MemoryStream中,然后再将所有字节写入文件,就可以得到几乎只有灰色的图像。
这不起作用:
var bytes = File.ReadAllBytes("myPath\\input.jpg");
var stream = new MemoryStream(bytes);
using (var i = new Bitmap(stream))
{
using (var graphics = Graphics.FromImage(i))
{
var selPen = new Pen(Color.Blue);
graphics.DrawRectangle(selPen, 10, 10, 50, 50);
i.Save(stream, ImageFormat.Jpeg);
}
}
File.WriteAllBytes("myPath\\output.jpg", stream.ToArray());
如您所见,图像的仅一部分是灰色的。实际图像中仍有一部分可见(白色)。
为什么会这样?正确的解决方法是什么?
谢谢!
答案 0 :(得分:3)
在第二个示例中,您已经双层写入Stream
;它仍然包含原始数据,然后您用Save
追加了更多数据。 Stream
的作用就像录像带一样。如果要覆盖流,则需要非常小心地执行此操作(并且:并非所有流都支持该概念-请考虑“网络流”,“加密流”等)。请注意,ToArray
(和GetBuffer
/ TryGetBuffer
方法)可以看到所有数据,而不仅仅是您认为的“新”数据(甚至不存在一个概念,就像录像带一样,您只有“当前”位置和长度-如果您需要知道第一场演出在哪里结束而第二场演出在哪里开始,您需要注意自己,手动)。在这种情况下,添加:
stream.Position = 0; // rewind
stream.SetLength(0); // truncate (important in case the new data is *shorter* than the old)
在阅读后Save
之前,应对其进行修复。
答案 1 :(得分:1)
您正在将图像从字节数组保存到已初始化的流中。
创建一个新流并将其保存。
var stream2 = new MemoryStream();
i.Save(stream2, ImageFormat.Jpeg);
或者只是重置上一个
memoryStream = new MemoryStream(stream.Capacity());