如何压缩高分辨率图像字节而不先转换为图像/位图

时间:2014-09-03 22:50:05

标签: c# .net image-processing compression kinect

我正在使用Kinect 2.0,尤其是颜色流。色彩流以1920×1080的分辨率到达,非常棒!除此之外,我打算捕获图像字节并将其写入磁盘。因此,对我来说最可行的解决方案是压缩每个图像帧,然后存储压缩图像而不是原始高分辨率图像。

我有一个解决方案,但我觉得它有点像“围绕房子”这样做的方式。

基本上,我得到原始像素,将它们写入WriteableBitmap,然后使用以下两种方法压缩ImageSource:

1)写入WriteableBitmap:

this.colorBitmap.WritePixels(
                new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight),
                this.colorPixels,
                this.colorBitmap.PixelWidth * (int)this.bytesPerPixel,
                0);

2)将其压缩为jpeg:

        public static byte[] CompressToBytes(ImageSource src, int compressionrate)
        {                  
            var enc = new JpegBitmapEncoder();
            enc.QualityLevel = compressionrate;

            var bf = BitmapFrame.Create((BitmapSource)src);
            enc.Frames.Add(bf);

            using (var ms = new MemoryStream())
            {
                enc.Save(ms);
                return ms.ToArray();
            }
        }

正如我所说,哪个工作正常,但我认为如果我能从Kinect获取原始像素然后直接压缩字节数组而不是写入WriteableBitmap然后压缩它会更好。这似乎是一个额外的步骤。

BTW,这是我用来从彩色帧中获取字节的代码:

    using (ColorFrame colorFrame = e.FrameReference.AcquireFrame())
    {
        if (colorFrame != null)
        {
            FrameDescription colorFrameDescription = colorFrame.FrameDescription;

            if ((colorFrameDescription.Width == this.colorBitmap.PixelWidth) && (colorFrameDescription.Height == this.colorBitmap.PixelHeight))
            {
                if (colorFrame.RawColorImageFormat == ColorImageFormat.Bgra)
                {
                    colorFrame.CopyRawFrameDataToArray(this.colorPixels);
                }
                else
                {
                    colorFrame.CopyConvertedFrameDataToArray(this.colorPixels, ColorImageFormat.Bgra);
                }
            }
        }
    }

请记住,当以每秒所有帧数处理颜色流时,您可以捕获掉落(大概从30-32到26-29),我想使用最有效的方法。

有一件事我注意到在c#中搜索压缩解决方案时,很多文章都是针对将单个映像存储到磁盘上的。虽然我需要在内存中执行此压缩,因为我正在将多个图像写入磁盘(使用二进制编写器)。

0 个答案:

没有答案