我试图获取大小(以字节为单位,而不是以宽度x高度为单位)的计算方式。我制作了一个检查应用程序,该应用程序每秒以24bbp状态获取当前桌面的屏幕快照,然后将其写入MemoryStream并使用ImageConverter写入byte [],然后比较大小。每个屏幕截图的大小都不同,但是不应该是宽x高x 3或类似的大小吗?这是测试代码:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
class Check
{
System.Timers.Timer t;
ImageConverter converter;
MemoryStream ms;
byte[] arr;
public Check()
{
converter = new ImageConverter();
t = new System.Timers.Timer();
t.Interval = 1000;
t.Elapsed += T_Tick;
t.Start();
}
private void T_Tick(object sender, EventArgs e)
{
var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height,
PixelFormat.Format24bppRgb);
var gfxScreenshot = Graphics.FromImage(bmpScreenshot);
gfxScreenshot.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size);
ms = new MemoryStream();
bmpScreenshot.Save(ms, ImageFormat.Jpeg);
arr = (byte[])converter.ConvertTo(bmpScreenshot, typeof(byte[]));
Console.WriteLine($"MS: {ms.Length} --- byte[]: {arr.Length}");
}
}
class Program
{
static void Main()
{
new Check();
Console.ReadLine();
}
}
这是输出
MS: 76638 --- byte[]: 94893
MS: 90487 --- byte[]: 107863
MS: 92424 --- byte[]: 109281
MS: 93692 --- byte[]: 110295
MS: 95222 --- byte[]: 111055
MS: 96586 --- byte[]: 112314
MS: 104584 --- byte[]: 117970
MS: 108438 --- byte[]: 120089
...and so on
因此,每帧尺寸的改变最终都会开始减小,但是那不应该是静态的吗?或者有没有办法实现图像的静态尺寸?
UDP:将格式更改为bmp,这是另一个输出:
MS: 3148854 --- byte[]: 104699
MS: 3148854 --- byte[]: 116002
MS: 3148854 --- byte[]: 121262
MS: 3148854 --- byte[]: 125048
所以MemoryStream现在是静态的,但是ImageConverter的结果仍在变化。
答案 0 :(得分:0)
这是一个有趣的难题。
它包含三个问题:
任何压缩结果都取决于内容;即使是细微的变化(例如移动的时针或VS输出窗格中的其他行)也会有所不同。
让我们添加另一个结果,这次是Png
,并且具有恒定的屏幕内容:
MS: 618997 --- byte[]: 618997
MS: 618997 --- byte[]: 618997
MS: 618997 --- byte[]: 618997
MS: 618997 --- byte[]: 618997
现在我们可以得出结论:
流编号有所不同,只要我们不确定屏幕内容不会更改,或者我们使用bmp
之类的非压缩格式即可。我们必须隐藏输出窗格,用秒针等禁用任何时钟。
只要屏幕内容更改,数组编号就不同
png
时,流和数组号相同。由此我们可以得出结论,ImageConverter
以Png
格式存储压缩为字节数组的图像;这很好,因为它可以节省内存。但是,MSDN没有对此进行记录。 (他们可能不想保证这一点。)