В настоящее время у меня есть приложение, которое снимает скриншот рабочего стола презентатора, а затем транслирует его через специальный протокол для зрителей. Для того, чтобы изображения были перенесены достаточно быстро, чтобы получить частоту кадров 2 - 3 изображения в секунду, мне нужно обеспечить, чтобы размер изображения был всегда меньше ~ 300 КБ.
Я использую С# для приложения-презентатора, который кодирует скриншот в JPEG через процесс ниже. Меня беспокоит то, что качество изображения может сильно различаться при использовании статической настройки сжатия. Если у меня будет приложение, захватывающее мой экран, выход изображений будет ~ 200 КБ, когда у меня будет полноэкранный режим Visual Studio, но если я скрою свой экран и появлюсь на рабочем столе, это будет ~ 400 КБ.
Я мог бы перевести процесс кодирования в цикл и постоянно уменьшать размер изображения до тех пор, пока размер байтового массива будет меньше 300 КБ, но это похоже на утомительную операцию. Есть ли другой способ, который я мог бы использовать?
Спасибо заранее.
// get the screenshot
System.Drawing.Rectangle totalSize = System.Drawing.Rectangle.Empty;
//foreach (Screen s in Screen.AllScreens)
totalSize = System.Drawing.Rectangle.Union(totalSize, Screen.PrimaryScreen.Bounds);
Bitmap screenShotBitmap = new Bitmap(totalSize.Width, totalSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
screenShotBitmap.SetResolution(96, 96);
Graphics screenShotGraphics = Graphics.FromImage(screenShotBitmap);
screenShotGraphics.CopyFromScreen(totalSize.X, totalSize.Y,
0, 0, totalSize.Size, CopyPixelOperation.SourceCopy);
screenShotGraphics.Dispose();
// image codec information
ImageCodecInfo imageCodecInfo = GetEncoderInfo("image/jpeg");
// encoder settings
System.Drawing.Imaging.Encoder encoderQuality;
System.Drawing.Imaging.Encoder encoderColor;
encoderQuality = System.Drawing.Imaging.Encoder.Quality;
encoderColor = System.Drawing.Imaging.Encoder.ColorDepth;
// compression & quality for JPEG output
Int64 quality = 40L;
// storage for exported JPEG
byte[] screenShotByteArray;
// encoder parameters
EncoderParameter encoderQualityParameter = new EncoderParameter(encoderQuality, quality);
//EncoderParameter encoderColorParameter = new EncoderParameter(encoderColor, 8L);
// encoder parameters table
EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = encoderQualityParameter;
//encoderParameters.Param[1] = encoderColorParameter;
// get the code into a memory stream
MemoryStream screenShotMemoryStream = new MemoryStream();
screenShotBitmap.Save(screenShotMemoryStream, imageCodecInfo, encoderParameters);
// convert to a byte array
screenShotByteArray = screenShotMemoryStream.GetBuffer();
// close the memory stream
screenShotMemoryStream.Close();