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);
}

また、どのファイル形式にエンコードしていますか?指定していません。2番目のエンコーダーが見つかりました。結果の順序に依存するべきではありません。代わりに、特定のコーデックを検索してください。

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

...そしてエンコーダがシステムに存在しないかどうかを確認することを忘れないでください:

if (encoder != null)
{ .. }

Qualityパラメータは、すべてのファイル形式で意味があるわけではありません。JPEGを使用している可能性があると思いますか?また、100%JPEG品質!=ロスレス画像であることを忘れないでください。Quality = 100でエンコードし、スペースを減らすことができます。

于 2012-07-17T15:28:01.500 に答える
1

zipストリームから画像を抽出した後、画像を圧縮するコードはありません。解凍したデータをMemoryStreamに取り込み、品質情報に基づいて同じストリームに画像を書き込みます(コーデックによっては、画像を圧縮する場合としない場合があります)。まず、読んでいるのと同じストリームに書き込まないことをお勧めします。また、Encoder.Qualityプロパティから得られる「圧縮」は、画像のタイプによって異なります。これについては、詳細を提供していません。画像の種類が圧縮をサポートしていて、受信する画像の品質が最初から100未満の場合、サイズを縮小することはできません。また、あなたはそれに関する情報を提供していません。簡単に言えば、あなたはしていません

于 2012-07-17T15:24:07.800 に答える