MinYoung Lee Ответов: 3

C# есть ли способ минимизировать размер изображения в байтах перед отправкой на сервер с помощью sokcet


Я пытался разработать программу удаленного рабочего стола на языке C# и хочу уменьшить размер моего изображения в байтах. Вот моя попытка ниже до сих пор.

//
                int w = Screen.PrimaryScreen.Bounds.Width;
                int h = Screen.PrimaryScreen.Bounds.Height;

                //
                Size s = new Size(w, h);

                Bitmap ScreenImage = new Bitmap(w, h);

                Graphics graphics = Graphics.FromImage(ScreenImage);
                graphics.CopyFromScreen(0, 0, 0, 0, s);

                int width = ScreenImage.Width / 2;
                int height = ScreenImage.Height / 2;
                Size resize = new Size(width, height);
                Bitmap resizeImage = new Bitmap(ScreenImage, resize);

                // Bitmap To byte[]
                MemoryStream ms = new MemoryStream();
                resizeImage.Save(ms, ImageFormat.Jpeg);
                ms.Position = 0;
                byte[] data = ms.ToArray();

                byte[] compressedByte = Compress(data);



    public static Byte[] Compress(Byte[] buffer)
    {
        Byte[] compressedByte;
        using (MemoryStream ms = new MemoryStream())
        {
            using (DeflateStream ds = new DeflateStream(ms, CompressionMode.Compress))
            {
                ds.Write(buffer, 0, buffer.Length);
            }

            compressedByte = ms.ToArray();
        }

        return compressedByte;
    }


Я попытался сделать растровое изображение измененным и сжатым, чтобы уменьшить его размер в байтах, но мне все равно нужно сделать его меньше. Может ли кто-нибудь дать мне другие способы? Заранее благодарю вас!

Что я уже пробовал:

Bitmap resizeImage = новое растровое изображение(ScreenImage, resize);
byte[] compressedByte = сжатие(данные);

3 Ответов

Рейтинг:
1

OriginalGriff

Не совсем: файлы JPEG уже сжаты, и дальнейшее сжатие часто делает их больше, а не меньше. Вы уже используете сжатие ZIP, но это вряд ли даст значительный выигрыш в файле JPEG в любом случае. Если вы получаете дополнительные 10%, значит, у вас все хорошо.

Но...вы понимаете, что JPEG-это формат "сжатия с потерями"? Каждый раз, когда вы сохраняете файл в формате JPEG, вы теряете информацию (и обычно получаете меньший файл) и более "нечеткую" картинку?
Я бы посоветовал вам использовать его как формат без потерь (например, BMP (несжатый, но хорошо сжимается) или PNG (сжатый)) и сжать его вместо этого.


MinYoung Lee

- Спасибо, Грифф. Как вы сказали о "сжатии с потерями, нечеткой картинке", моя программа внезапно перестает отправлять растровые изображения на сервер через несколько минут после запуска. Я думаю, что причина этого в том, что вы сказали именно так. Вместо этого я буду использовать BMP или PNG.

0x01AA

.

Рейтинг:
0

CPallini

Как уже отмечалось, вы обычно не можете получить много, пытаясь сжать изображение JPEG, которое уже сжато. В своем коде вы изменили размер изображения, сделав его меньше. Если это приемлемо, чтобы сделать его еще меньше, то вы можете сохранить некоторую память.


MinYoung Lee

Спасибо за помощь, CPallini!

CPallini

Добро пожаловать.

Рейтинг:
0

AntonioLeonardo

The imagem compression follow another objects and features that different of trivial files; image compreession has properties to equalize the compression. Like code bellow, the compression act on Quality property:


static byte[] CompressByImageAlg(int jpegQuality, byte[] data)
        {
            using (MemoryStream inputStream = new MemoryStream(data))
            {
                using (Image image = Image.FromStream(inputStream))
                {
                    ImageCodecInfo jpegEncoder = ImageCodecInfo.GetImageDecoders()
                        .First(c => c.FormatID == ImageFormat.Jpeg.Guid);
                    var encoderParameters = new EncoderParameters(1);
                    encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, jpegQuality);
                    byte[] outputBytes = null;
                    using (MemoryStream outputStream = new MemoryStream())
                    {
                        image.Save(outputStream, jpegEncoder, encoderParameters);
                        return outputStream.ToArray();
                    }
                }
            }
        }


OriginalGriff

Хотя я аплодирую вашему стремлению помогать людям, это хорошая идея-придерживаться новых вопросов, а не 2-летних. После такого количества времени маловероятно, что оригинальный плакат вообще заинтересован в проблеме больше!
Ответы на старые вопросы можно рассматривать как охоту за репостами, которая является формой злоупотребления сайтом. Более триггерные счастливые среди нас начнут процесс запрета вас с сайта, если вы не будете осторожны. Придерживайтесь новых вопросов, и все будет хорошо.