1

我正在尝试获取输入流(图像的 zip 文件)并提取每个文件。但是我必须在保存之前降低每张图像的质量(如果质量 < 100)。我尝试了以下方法,但它从不压缩图像:

public void UnZip(Stream inputStream, string destinationPath, int quality = 80) {
    using (var zipStream = new ZipInputStream(inputStream)) {
        ZipEntry entry;

        while ((entry = zipStream.GetNextEntry()) != null) {
            var directoryPath = Path.GetDirectoryName(destinationPath + Path.DirectorySeparatorChar + entry.Name);
            var fullPath = directoryPath + Path.DirectorySeparatorChar + Path.GetFileName(entry.Name);

            // Create the stream to unzip the file to
            using (var stream = new MemoryStream()) {
                // Write the zip stream to the stream
                if (entry.Size != 0) {
                    var size = 2048;
                    var data = new byte[2048];

                    while (true) {
                        size = zipStream.Read(data, 0, data.Length);

                        if (size > 0)
                            stream.Write(data, 0, size);
                        else
                            break;
                    }
                }

                // Compress the image and save it to the stream
                if (quality < 100)
                    using (var image = Image.FromStream(stream)) {
                        var info = ImageCodecInfo.GetImageEncoders();
                        var @params = new EncoderParameters(1);
                        @params.Param[0] = new EncoderParameter(Encoder.Quality, quality);
                        image.Save(stream, info[1], @params);
                    }
                }

                // Save the stream to disk
                using (var fs = new FileStream(fullPath, FileMode.Create)) {
                    stream.WriteTo(fs);
                }
            }
        }
    }
}

如果有人能告诉我我做错了什么,我将不胜感激。由于代码变得有点难看,任何关于整理它的建议都会受到赞赏。谢谢

4

2 回答 2

2

您真的不应该使用相同的流来保存压缩图像。MSDN 文档明确指出:“不要将图像保存到用于构建图像的同一流中。这样做可能会损坏流。” (关于 Image.Save(...) 的 MSDN 文章

using (var compressedImageStream = new MemoryStream())
{
    image.Save(compressedImageStream, info[1], @params);
}

另外,你编码成什么文件格式?你没有指定。您刚刚找到了第二个编码器。你不应该依赖结果的顺序。而是搜索特定的编解码器:

var encoder = ImageCodecInfo.GetImageEncoders().Where(x => x.FormatID == ImageFormat.Jpeg.Guid).SingleOrDefault()

...并且不要忘记检查您的系统上是否不存在编码器:

if (encoder != null)
{ .. }

质量参数并不适用于所有文件格式。我假设您可能正在使用 JPEG?另外,请记住 100% JPEG 质量!= 无损图像。您仍然可以使用 Quality = 100 进行编码并减少空间。

于 2012-07-17T15:28:01.500 回答
1

从 zip 流中提取图像后,没有用于压缩图像的代码。您似乎正在做的只是将解压缩的数据放入 MemoryStream 中,然后根据质量信息(可能会或可能不会压缩图像,具体取决于编解码器)将图像写入同一流。我首先建议不要写入您正在阅读的同一流。此外,您从 Encoder.Quality 属性中获得的“压缩”取决于图像的类型——您没有提供任何详细信息。如果图像类型支持压缩,并且传入的图像质量低于 100 开始,您将不会得到任何缩小。此外,您还没有提供任何相关信息。长话短说,你没有

于 2012-07-17T15:24:07.800 回答