7

一部の画像のサイズをユーザーの画面解像度に合わせています。アスペクト比が間違っている場合は、画像をカットする必要があります。私のコードは次のようになります。

protected void ConvertToBitmap(string filename)
    {
        var origImg = System.Drawing.Image.FromFile(filename);
        var widthDivisor = (double)origImg.Width / (double)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
        var heightDivisor = (double)origImg.Height / (double)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
        int newWidth, newHeight;

        if (widthDivisor < heightDivisor)
        {
            newWidth = (int)((double)origImg.Width / widthDivisor);
            newHeight = (int)((double)origImg.Height / widthDivisor);
        }
        else
        {
            newWidth = (int)((double)origImg.Width / heightDivisor);
            newHeight = (int)((double)origImg.Height / heightDivisor);
        }

         var newImg = origImg.GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero);
        newImg.Save(this.GetBitmapPath(filename), System.Drawing.Imaging.ImageFormat.Bmp);
    }

ほとんどの場合、これは正常に機能します。ただし、一部の画像では、結果の品質が非常に低くなります。非常に小さいサイズ(サムネイルサイズ)にサイズ変更され、再び拡大されたように見えます。ただし、画像の解像度は正しいです。私に何ができる?

元の画像の例: 代替テキストhttp://img523.imageshack.us/img523/1430/naturaerowoods.jpg

サイズ変更された画像の例: 代替テキスト

注:私はWPFアプリケーションを持っていますが、サイズ変更にはWinForms関数を使用しています。これは、サイズ変更が簡単であり、トレイアイコンのSystem.Windows.Formsへの参照がすでに必要なためです。

4

10 に答える 10

8

メソッドの最後の2行を次のように変更します。

var newImg = new Bitmap(newWidth, newHeight);
Graphics g = Graphics.FromImage(newImg);
g.DrawImage(origImg, new Rectangle(0,0,newWidth,newHeight));
newImg.Save(this.GetBitmapPath(filename), System.Drawing.Imaging.ImageFormat.Bmp);
g.Dispose();
于 2009-04-29T20:02:50.940 に答える
7

現時点では.NETソースを確認できませんが、問題はImage.GetThumbnailImageメソッドにある可能性があります。MSDNでさえ、「要求されたサムネイル画像のサイズが約120 x 120ピクセルの場合はうまく機能しますが、サムネイルが埋め込まれている画像から大きなサムネイル画像(たとえば、300 x 300)を要求すると、サムネイル画像の品質が著しく低下します。」真のサイズ変更(つまり、サムネイルではない)を行うには、このGraphics.DrawImage方法を使用する必要があります。Graphics.InterpolationModeまた、必要に応じて、より良い品質を得るためにで遊ぶ必要があるかもしれません。

于 2009-04-29T19:57:02.607 に答える
3

サムネイルを作成していない場合は、と呼ばれる方法を使用することはGetThumbnailImageおそらくお勧めできません...

その他のオプションについては、このCodeProjectの記事をご覧ください。特に、新しい画像を作成し、その画像Graphics用に作成し、補間モードをに設定しHighQualityBicubicて、元の画像をグラフィックに描画します。少なくとも試してみる価値はあります。

于 2009-04-29T19:57:35.990 に答える
2

MSDNに示されてGetThumbnailImage()いるように、任意の画像スケーリングを行うようには設計されていません。120x120を超えるものは、手動でスケーリングする必要があります。代わりにこれを試してください:

using(var newImg = new Bitmap(origImg, newWidth, newHeight))
{
    newImg.Save(this.GetBitmapPath(filename), System.Drawing.Imaging.ImageFormat.Bmp);
}

編集

明確にするために、Bitmapコンストラクターのこのオーバーロードはを呼び出しGraphics.DrawImageますが、補間を制御することはできません。

于 2009-04-29T19:57:08.177 に答える
2

このコードの代わりに:

newImg.Save(this.GetBitmapPath(filename), System.Drawing.Imaging.ImageFormat.Bmp);

これを使用してください:

System.Drawing.Imaging.ImageCodecInfo[] info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
System.Drawing.Imaging.EncoderParameters param = new System.Drawing.Imaging.EncoderParameters(1);
param.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
newImg.Save(dest_img, info[1], param);
于 2012-05-02T06:20:53.993 に答える
0

たとえば、元の画像はJPGで、サイズ変更された画像はPNGです。意図的にフォーマット間で変換していますか?異なるロッシー圧縮スキームを切り替えると、品質が低下する可能性があります。

于 2009-04-29T19:57:11.717 に答える
0

画像のサイズを変更するときに、画像のサイズを拡大または縮小していますか?小さい画像から大きい画像を作成する場合、この種の劣化が予想されます。

于 2009-04-29T20:13:40.493 に答える
0

拡大すると画像が劣化します。

于 2009-07-18T12:16:47.700 に答える
0

一部のカメラは、おそらくデバイス自体でのプレビュー目的で、サイズ変更されたサムネイルをファイル自体に配置します。

GetThumbnailメソッドは、高解像度のメソッドを取得する代わりに、画像ファイルに埋め込まれているこのサムネイル画像を実際に取得します。

簡単な解決策は、サイズ変更やその他の操作を行う前に、.Netをだましてそのサムネイル情報を破棄することです。そのようです....

img.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX); 
//removes thumbnails from digital camera shots
img.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX);

制約のある比率のサイズを変更しようとしている場合は、System.Drawing.Imageに拡張メソッドを作成しました。これは便利です。

/// <summary>
/// 
/// </summary>
/// <param name="img"></param>
/// <param name="size">Size of the constraining proportion</param>
/// <param name="constrainOnWidth"></param>
/// <returns></returns>
public static System.Drawing.Image ResizeConstrainProportions(this System.Drawing.Image img,
    int size, bool constrainOnWidth, bool dontResizeIfSmaller)
{
    if (dontResizeIfSmaller && (img.Width < size))
        return img;
    img.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX); 
    img.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX);
    float ratio = 0;
    ratio = (float)img.Width / (float)img.Height;

    int height, width = 0;
    if (constrainOnWidth)
    {
        height = (int)(size / ratio);
        width = size;
    }
    else
    {
        width = (int)(size * ratio);
        height = size;
    }
    return img.GetThumbnailImage(width, height, null, (new System.IntPtr(0)));
}
于 2009-09-20T21:52:08.773 に答える
-1

これは、次の要因に基づいて大きく異なります。

  1. 宛先の解像度が元の解像度の「自然な」スケールとどの程度一致しているか
  2. ソース画像の色深度
  3. 画像の種類-一部の画像は他の画像よりも損失が大きくなります
于 2009-04-29T19:58:32.917 に答える