2017-02-08 16 views
0

В настоящее время я работаю с C# и EmguCV (OpenCV) и хочу сжать/распаковать изображение с помощью JPEG/PNG, который в настоящее время представлен классом Mat. Я не хочу хранить его на диске, просто сжимаю его в памяти. Цель состоит в том, чтобы позже передать его TCP/IP.Как сжать изображение с помощью JPEG или PNG в C# в памяти?

Некоторые фрагмент кода для выполнения следующих задач высоко оценил:

A. Compress: Mat -> JPEG/PNG compressed byte[] 
B. Decompress: JPEG/PNG compressed byte[] -> Mat 
+1

Я не использовал EmguCV, но, глядя на документацию, кажется, что ваш объект Mat имеет свойство Bitmap. Вы можете вызвать «Сохранить в битовой карте», чтобы сериализовать его непосредственно в потоке (например, MemoryStream), чтобы получить необработанные байты. Функция сохранения позволяет указать формат (разрешены png и jpg). Идя в другом направлении, вы можете вызвать System.Drawing.Image.FromStream(), чтобы загрузить растровое изображение непосредственно из памяти. – RogerN

+0

@RogerN: Это выглядит очень многообещающим! Я собираюсь попробовать этот подход и отчитаться с моими результатами. Большое спасибо за Вашу помощь! – salocinx

+0

Эти форматы только сжимаются, когда они хранятся в файле. Пункт загрузки изображения заключается в том, чтобы сделать все, что вы делаете дальше с ним, как можно быстрее. Память очень дешевая. Вы можете произвольно использовать Image.Save(), чтобы сохранить его в MemoryStream. –

ответ

0

Вот окончательный код для сжатия Mat объекта с JPG, возвращающая массив байтов для передачи по сети:

using Emgu.CV; 
    using System.Drawing.Imaging; 

    private VideoQuality quality; 
    private ImageCodecInfo codecInfo; 
    private EncoderParameters encoderParameters; 

    public byte[] compress(Mat image) { 
     using(MemoryStream memstream = new MemoryStream()) { 
      long tstart = Toolkit.CurrentTimeMillis(); 
      image.Bitmap.Save(memstream, codecInfo, encoderParameters); 
      return memstream.ToArray(); 
     } 
    } 

    private void setVideoQuality(long quality) { 
     this.codecInfo = getEncoder(ImageFormat.Jpeg); 
     this.encoderParameters = new EncoderParameters(1); 
     encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, quality); 
    } 

    private ImageCodecInfo getEncoder(ImageFormat format) { 
     ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders(); 
     foreach(ImageCodecInfo codec in codecs) { 
      if(codec.FormatID == format.Guid) { 
       return codec; 
      } 
     } 
     return null; 
    } 

И вот соответствующий код для декодирования байтовой матрицы:

private Image createImage(byte[] bytes) { 
     using (MemoryStream memstream = new MemoryStream(bytes, 0, bytes.Length)) { 
      memstream.Position = 0; 
      return Image.FromStream(memstream, true); 
     } 
    } 

Надеюсь, это поможет кому-то :-) Спасибо за вашу помощь!