4

.tif イメージを開き、後でそれを保存するオプションを提供する ac# プログラムがあります。ただし、画像を保存すると、常に品質が低下します。

(編集:画質が 100% で圧縮されないように、画像を保存するときにいくつかのパラメーターを渡しましたが、画像のプロパティが 8bpp を示していても、実際の一意の色の数は 254 から 16 になります)

(EDIT2:問題の画像は、ピクセルあたり8ビットのグレースケール画像です-256色/グレーの色合い-これは、すべての色が保持されている場所でテストしたピクセルあたり24ビットのカラー画像では発生しません。開始しています。画像クラスが 16 階調のグレーしかサポートしていない可能性があると考えること)

どうすればこれを回避できますか?

画像を開くコードは次のとおりです。

public Image imageImport()
{
    Stream myStream = null;
    OpenFileDialog openTifDialog = new OpenFileDialog();
    openTifDialog.Title = "Open Desired Image";
    openTifDialog.InitialDirectory = @"c:\";
    openTifDialog.Filter = "Tiff only (*.tif)|*.tif";
    openTifDialog.FilterIndex = 1;
    openTifDialog.RestoreDirectory = true;
    if (openTifDialog.ShowDialog() == DialogResult.OK)
    {   
        try
        {
            if ((myStream = openTifDialog.OpenFile()) != null)
            {
                using (myStream)
                {
                    String tifFileName= openTifDialog.FileName;
                    imgLocation = tifFileName;
                    Bitmap tifFile = new Bitmap(tifFileName);
                    return tifFile;
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
        }
    }
    return null;
}

これは私が画像を保存する方法です:

private void saveImage(Image img)
{
    SaveFileDialog sf = new SaveFileDialog();
    sf.Title = "Select File Location";
    sf.Filter = " bmp (*.bmp)|*.bmp|jpeg (*.jpg)|*.jpg|tiff (*.tif)|*.tif";
    sf.FilterIndex = 4;
    sf.RestoreDirectory = true;
    sf.ShowDialog();

    // If the file name is not an empty string open it for saving.
    if (sf.FileName != "")
    {
        // Saves the Image via a FileStream created by the OpenFile method.
        System.IO.FileStream fs =
           (System.IO.FileStream)sf.OpenFile();

        // Saves the Image in the appropriate ImageFormat based upon the
        // File type selected in the dialog box.
        // NOTE that the FilterIndex property is one-based.
        switch (sf.FilterIndex)
        {
           case 1:
               img.Save(fs,
                   System.Drawing.Imaging.ImageFormat.Bmp);
           break;

           case 2:
               img.Save(fs,
                   System.Drawing.Imaging.ImageFormat.Jpeg);
           break;

           case 3://EDITED -STILL DOES NOT RESOLVE THE ISSUE
               ImageCodecInfo codecInfo = ImageClass.GetEncoderInfo(ImageFormat.Tiff);
               EncoderParameters parameters = new EncoderParameters(2);
               parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality,100L);
               parameters.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionNone);
               img.Save(fs,codecInfo, parameters);
           break;
       }
       fs.Close();
    }
}

画像のサイズを変更したり変更したりしなくても、品質が低下します。何かアドバイス?

4

4 に答える 4

1

System.Drawingは、8ビット画像のサポートが不十分です。24ビットまたは32ビットの画像から8ビットに変換する場合。常に固定のデフォルトカラーパレットを使用します。そのデフォルトのカラーパレットには16階調のグレーしか含まれていませんが、他のエントリはさまざまな色です。

'.bmp'として保存するときに同じ問題がありますか?はいの場合、8ビット形式への変換はすでに以前に行われています。プログラムがそれを行う場所を特定し、そこで問題を修正する必要があります。8ビットに変換するのがtiffエンコーダーのみの場合は、最初に別の手順で8ビット変換を実行する必要があります。8ビット画像を作成Image.Paletteし、グレースケールパレットで塗りつぶしてから、ビットマップデータをコピーします。

ただし、System.Drawingは8ビット画像のサポートが不十分であり、そのような画像を処理するときにいくつかのメソッド(たとえばSetPixel)がスローされます。ビットマップデータをコピーするにInvalidOperationExceptionは、おそらく安全でないコード(withなど)を使用する必要があります。LockBits私があなたなら、使用できる代替のグラフィックライブラリがあるかどうかを調べます。

于 2012-11-02T21:05:06.563 に答える
0

.NET ライブラリを使用して画質とサイズの適切なバランスを見つけるのに問題がありました。私は自分で開発することをあきらめ、いくつかのイメージング ライブラリを試しました。私はhttp://imageresizing.net/が一貫して良い結果を生み出すことを発見しました。

あなた自身の方法が一貫してうまく機能しない場合に備えて、プランBとしてそれを捨ててください。

于 2012-11-02T13:10:58.550 に答える
0

本当に1つの提案だけ....使用する画像をロードするときnew Bitmap(fileName)...ビットマップを使用するのではなく、使用することを検討しましたか

Image tiffImage = Image.FromFile(tiffFileName, true);

true は「埋め込みカラー管理」を使用するように指示し、Bitmap の代わりに Image を使用すると、舞台裏で発生する可能性のあるイメージ キャスティングを回避できます。

于 2012-11-02T18:56:16.397 に答える
0

Image.Saveデフォルトでは、75% の品質設定が使用されます。品質設定パラメーターを指定できるメソッドの他のオーバーロードの 1 つを使用してみてください。この質問を参照してください。

于 2012-11-02T13:31:47.963 に答える