【问题标题】:C# Bitmap screenshot sizeC#位图截图大小
【发布时间】:2019-08-13 07:34:08
【问题描述】:

我试图了解如何计算大小(以字节为单位,而不是宽度 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 结果仍在变化。

【问题讨论】:

  • Jpeg 是一种压缩格式。如果屏幕内容发生变化,其压缩大小预计会发生变化。 - 另外:不应该是 Width x Height x 3 你知道 Stride 吗?
  • 用bmp格式更新Q,现在结果不一样了
  • 嗯,很有趣。一旦我确定屏幕内容不会改变(隐藏输出窗格并停止时钟的秒针),数组大小就会保持不变。否则,一些小的变化会不断发生。正如 ms 的数字所暗示的那样,可能是一些(很可能是无损)压缩。
  • 它编译得很好,因为它是 Check 类的构造函数,无论如何对应用程序都没有关系,如果你不创建单独的类,你可以使用 void Check()。这不是一个完整的应用程序,只是一个检查这个的应用程序。
  • 编译好,是Check类的构造函数 嗯,我是直接粘贴的,没有类。对不起。有趣的是 PNG - 所以看起来 ImageConverter 实际上为 PNG 生成了一个字节数组。我还没有来测试这种格式,但并不奇怪,因为它很常见而且效果很好..-所以我想我们已经准备好了所有的拼图..?

标签: c# bitmap byte screenshot


【解决方案1】:

这是一个有趣的谜题。

由三个问题组成:

  • 为什么流的数字会发生变化?
  • 为什么字节数组的数字会发生变化?
  • 为什么流和数组的数字不同?

任何压缩结果都取决于内容;即使是微小的变化,例如移动的时钟指针或 VS 输出窗格中的附加线也会产生一些不同..

让我们添加另一个结果,这次是Png,并且屏幕内容不变:

MS: 618997  --- byte[]: 618997
MS: 618997  --- byte[]: 618997
MS: 618997  --- byte[]: 618997
MS: 618997  --- byte[]: 618997

现在我们可以得出结论:

  • 只要我们不确保屏幕内容不会改变或者我们使用像bmp 这样的非压缩格式,流编号就会有所不同。我们必须隐藏输出窗格,用第二只手禁用任何时钟等。

  • 只要屏幕内容发生变化,数组编号就不同

  • 当我们存储为png时,流和数组的编号是一样的。

由此我们可以得出结论,ImageConverter 将图像压缩为Png 格式的字节数组;这很好,因为它可以节省内存。但是,MSDN 没有记录它。 (他们可能不想保证这一点..)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-28
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    相关资源
    最近更新 更多