我有一个使用 NAudio 播放音频的应用程序。NAudio 的一个已知限制是每次垃圾收集器运行时,每个线程都会暂停,直到完成。
应用程序运行良好,所有 GC 都在可接受的时间内完成,并且没有卡顿。
但是我们还有一个单独的应用程序,它每秒通过 TCP 向主应用程序(带有音频播放器)发送一个缩略图。当编码为 JPEG 时,缩略图大约为 1300 字节。
这是我们目前用来解码图像的代码:
MemoryStream ms = new MemoryStream(data);
BitmapDecoder bdec = BitmapDecoder.Create(ms, BitmapCreateOptions.None, BitmapCacheOption.Default);
BitmapSource source = bdec.Frames[0];
imgPreview.Source = source;
并编码:
JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder();
jpgEncoder.QualityLevel = quality;
jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget));
byte[] imageArray;
using (MemoryStream outputStream = new MemoryStream())
{
jpgEncoder.Save(outputStream);
imageArray = outputStream.ToArray();
}
其中 RenderTarget 是具有图像内容的 RenderTargetBitmap。
现在我们每秒都在创建和丢弃一个 MemoryStream、一个 BitmapDecoder 和一个 BitmapSource。我已经注释掉了代码中的行,看起来 MemoryStream 和 BitmapDecoder 构造函数不会产生任何卡顿,但是一旦通过 Frames[0] 访问它,它就会开始卡顿。
我们也尝试过这种方法而不是 BitmapDecoder,但结果相同:
img.BeginInit();
img.StreamSource = ms;
img.EndInit();
当然有更好的方法来不断更新图像吗?
最好的方法是只发送原始图像数据,并创建一个 WriteableBitmap,它只是每秒重写一次。但是原始图像是 170 kb,是编码图像的 100 多倍,我们真的不想这样做。是否可以将 JPEG 流解码为现有字节数组或现有图像?