【发布时间】:2014-08-01 05:59:43
【问题描述】:
我正在寻找一种可以将大小至少减少 50% 的压缩方法,不幸的是我找不到...
我使用过 .net 的 GzipStream 和 DeflateStream,但它们的压缩率很差。 然后我找到了 7-zip,特别是SevenZipSharp
所以,我下载了 7-zip(实际程序),将 7z.dll 指定为 SevenZipSharp 使用的库,并像这样使用它:
这是一个客户端-服务器应用程序。
Private Shared Function SevenZip_Compress(ms As MemoryStream) As Byte()
Using compressedstream As New MemoryStream
Dim compressor As New SevenZip.SevenZipCompressor
compressor.CompressionMethod = CompressionMethod.Lzma2
compressor.CompressionLevel = CompressionLevel.Ultra
compressor.CompressStream(ms, compressedstream)
ms.Dispose()
Return compressedstream.ToArray
End Using
End Function
使用此压缩流从 131000~ 压缩到 103000~ 字节,这仍然太高而无法通过 Internet 发送,我们在 CompressionLevel.Ultra 中讨论,如果我放低,压缩只会降低到125000~。为什么压缩率这么低?
我正在压缩分辨率为 1280x720 的 Jpeg 图像。 我知道 Jpeg 已经被压缩了,但是如果我使用 Png 原始流是 262000 并且压缩流是 350000 字节(我不明白为什么)所以我坚持使用 Jpeg。 我在运行时创建图像,如果这很重要,则不涉及磁盘文件。
为了在客户端解压缩流,我使用这个:
Private Function SevenZip_Decompress(bytes As Byte()) As Byte()
Dim compressedstream As New MemoryStream(bytes)
Dim decompressor As New SevenZip.SevenZipExtractor(compressedstream)
Using decompressedstream As New MemoryStream
decompressor.ExtractFile(0, decompressedstream)
compressedstream.Dispose()
Return decompressedstream.ToArray
End Using
End Function
我也尝试过使用这个库提供的“共享”方法,如下所示:
Dim bytes() = SevenZip.SevenZipCompressor.CompressBytes(ms.ToArray)
然后提取:
Dim ms As New MemoryStream(SevenZip.SevenZipExtractor.ExtractBytes(bytes)
这工作得更好一些,它将相同的流压缩到 50000~ 这是一个 65% 的压缩率,这非常好,(尽管我仍然想要更多..)但是它为每个图像使用 12% 的 CPU,这是太高了,而第一种方法无论是Low还是Ultra都只使用了3%的最大CPU,这是可以接受的。
cpu 是 i7-3610QM 2.3ghz。
这个结果是我们在服务器和客户端之间以每秒 9 帧的速度进行远程桌面会话,我没有使用远程桌面协议,我每秒发送 9 个全屏截图。
那么,我问,有没有比 SevenZipSharp 库功能更好的压缩方法? 如果没有,我能做些什么来减少发送的图像字节数,这样我就不需要只在这个上刻录我的上传带宽了?不使用远程桌面协议有没有更好的方法?
【问题讨论】:
-
如果您担心会消耗带宽,RDP 将无济于事!
-
如果您正在创建/捕获图像,最好的选择可能是使用 ImageEncoder 并降低 jpg 质量。压缩每增加 5% 都会导致相当大的尺寸减小。您也可以尝试保持高质量,但将大小减小到 50% 或 75%,然后在另一侧调整为原始大小。
-
jpeg 图像已经被压缩,因此很难使用 gzip 等进一步压缩,正如@Plutonix 通过降低质量或图像分辨率所指出的那样。另一种选择是使用另一种图像压缩格式,例如JPEG 2000
-
@Grim 我以为它只会发送屏幕的更改部分,而不是像我正在做的那样发送整个屏幕截图,这样可以节省带宽......(从未使用过它),@ Plutonix 你的意思是它就像 [pastebin.com/wtkkWgKW](this?) 我已经尝试过,但我再次测试了它,它会将相同的图像缩小到 30kb,这太棒了,我想要少一点,但这相当不错,@ Phillip Trelford,你个人用过吗,你能告诉我在c#中使用它是否容易?
-
对不起,我误会了。我以为您正在尝试找到一种使用尽可能少的带宽发送“图像”的方法;我的评论是指出 RDP 将使用比 ONE 图像更多的带宽(显然!)。如果您有监控带宽的工具,我很想知道标准 RDP 会话使用了多少带宽...
标签: vb.net image winforms compression 7zip