C# 位图截图大小
C# Bitmap screenshot size
我正在尝试了解大小(以字节为单位,而不是以宽度 x 高度为单位)的计算方式。我制作了一个检查应用程序,每秒以 24bbp 状态截取当前桌面的屏幕截图,然后将其写入 MemoryStream 并使用 ImageConverter 写入 byte[],然后比较大小。每张截图的尺寸都不一样,但它不应该是 Width x Height 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 结果仍在变化。
这是一个有趣的谜题。
它由三个问题组成:
- 为什么流的数字会发生变化?
- 为什么字节数组的数字会发生变化?
- 为什么流和数组的数字不同?
任何压缩结果都将取决于内容;即使是轻微的变化,例如移动时钟指针或 VS 输出窗格中的附加行也会有所不同..
让我们添加另一个结果,这次是 Png
并且屏幕内容不变:
MS: 618997 --- byte[]: 618997
MS: 618997 --- byte[]: 618997
MS: 618997 --- byte[]: 618997
MS: 618997 --- byte[]: 618997
现在我们可以得出结论:
只要我们不确保屏幕内容不会改变或我们使用非压缩格式(如 bmp
),流编号就会不同。我们必须隐藏输出窗格,用二手手禁用任何时钟等。
只要屏幕内容改变数组编号就不同
- 当我们存储为
png
时,流和数组编号相同。
从这里我们可以得出结论,ImageConverter
以Png
格式存储压缩为字节数组的图像;这很好,因为它可以节省内存。不过,MSDN 没有记录它。 (他们可能不想保证这一点..)
我正在尝试了解大小(以字节为单位,而不是以宽度 x 高度为单位)的计算方式。我制作了一个检查应用程序,每秒以 24bbp 状态截取当前桌面的屏幕截图,然后将其写入 MemoryStream 并使用 ImageConverter 写入 byte[],然后比较大小。每张截图的尺寸都不一样,但它不应该是 Width x Height 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 结果仍在变化。
这是一个有趣的谜题。
它由三个问题组成:
- 为什么流的数字会发生变化?
- 为什么字节数组的数字会发生变化?
- 为什么流和数组的数字不同?
任何压缩结果都将取决于内容;即使是轻微的变化,例如移动时钟指针或 VS 输出窗格中的附加行也会有所不同..
让我们添加另一个结果,这次是 Png
并且屏幕内容不变:
MS: 618997 --- byte[]: 618997
MS: 618997 --- byte[]: 618997
MS: 618997 --- byte[]: 618997
MS: 618997 --- byte[]: 618997
现在我们可以得出结论:
只要我们不确保屏幕内容不会改变或我们使用非压缩格式(如
bmp
),流编号就会不同。我们必须隐藏输出窗格,用二手手禁用任何时钟等。只要屏幕内容改变数组编号就不同
- 当我们存储为
png
时,流和数组编号相同。
从这里我们可以得出结论,ImageConverter
以Png
格式存储压缩为字节数组的图像;这很好,因为它可以节省内存。不过,MSDN 没有记录它。 (他们可能不想保证这一点..)