I'm trying to get how the size (in bytes, not in Width x Height) is calculated. I made a checking application which takes screenshot of current desktop in 24bbp state each second, then write it to MemoryStream and to byte[] with ImageConverter, then compare sizes. Each screenshot is different in size, but shouldn't it be Width x Height x 3 or smth like that? Here's testing code:
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();
}
}
and here's the output
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
So the size changes each frame it can begin to decrease eventually, but shouldn't that be static, or is there a way to achieve static size of images?
UDP: Changed format to bmp, here's another output:
MS: 3148854 --- byte[]: 104699
MS: 3148854 --- byte[]: 116002
MS: 3148854 --- byte[]: 121262
MS: 3148854 --- byte[]: 125048
so the MemoryStream is static now, but ImageConverter result is still changing.
This is an interesting puzzle.
It consists of three questions:
Any compression result will depend on content; even slight changes, like a moving clock hand or an additional line in the the VS output pane will make some difference..
Let's add another result, this time for Png
and with a constant screen content:
MS: 618997 --- byte[]: 618997
MS: 618997 --- byte[]: 618997
MS: 618997 --- byte[]: 618997
MS: 618997 --- byte[]: 618997
Now we can conclude:
The stream numbers differ as long as we don't make sure that either the screen content won't change or we use a non-compressed format like bmp
. We must hide the output pane, disable any clocks with a seond hand etc..
The array numbers differ as long as the screen content changes
png
.From this we can conclude that ImageConverter
stores images compressed as byte arrays in the Png
format; this is nice as it saves memory. MSDN doesn't document it, though. (They probably don't want to guarantee this..)