【问题标题】:How to compress an image with JPEG or PNG in C# in-memory?如何在 C# 内存中使用 JPEG 或 PNG 压缩图像?
【发布时间】:2017-02-08 20:32:47
【问题描述】:

我目前正在使用 C# 和 EmguCV (OpenCV) 并希望使用当前由 Mat 类表示的 JPEG/PNG 压缩/解压缩图像。我不想将它存储在磁盘上,只需将其压缩到内存中。目标是稍后通过 TCP/IP 传输。

高度赞赏以下任务的一些代码 sn-p:

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

【问题讨论】:

  • 我没有使用过 EmguCV,但是查看文档,您的 Mat 对象似乎具有 Bitmap 属性。您可以在 Bitmap 上调用 Save 以将其直接序列化为流(例如 MemoryStream)以获得原始字节。保存功能允许您指定格式(允许使用 png 和 jpg)。反过来,你可以调用 System.Drawing.Image.FromStream() 来直接从内存中加载位图。
  • @RogerN:看起来很有希望!我将尝试这种方法并报告我的结果。非常感谢您的帮助!
  • 这些格式只有在存储在文件中时才会被压缩。加载图像的目的是尽可能快地完成下一步操作。内存很便宜。您可以任意使用 Image.Save() 将其存储在 MemoryStream 中。
  • OpenCV 有“imdecode”和“imencode”正是为此。 emgucv 可能也有它们
  • 是的,“imencode”和“imdecode”可用作 CvInvoke 类的静态成员。到目前为止,谢谢,我会尝试这两种方法并在这里发布一些结果。

标签: c# stream compression jpeg emgucv


【解决方案1】:

这是压缩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);
        }
    }

希望这对某人有所帮助 :-) 感谢您的帮助!

【讨论】:

    猜你喜欢
    • 2019-09-22
    • 2010-12-18
    • 2013-01-24
    • 2013-02-22
    • 2012-09-02
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 2019-08-30
    相关资源
    最近更新 更多