品質を維持したまま画像のサイズを変更する[終了]


108

画質に影響を与えずに画像のサイズを変更するにはどうすればよいですか?


詳細を教えてください。画像はどのくらいの大きさで、どのくらいのサイズにする必要がありますか?
Mark Ransom


6
imageresizing.net-このライブラリは、.NETで取得できる最高品質の画像を生成します
Lilith River

回答:


217

以下のようRCARは言う、あなたはいくつかの品質を失うことなく、あなたがC#でできる最善のですができません。

Bitmap newImage = new Bitmap(newWidth, newHeight);
using (Graphics gr = Graphics.FromImage(newImage))
{
    gr.SmoothingMode = SmoothingMode.HighQuality;
    gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
    gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
    gr.DrawImage(srcImage, new Rectangle(0, 0, newWidth, newHeight));
}

2
(可能であれば)ユーザーが、たとえば必要な2倍のビットマップ画像から始めて、縮小する必要があることを付け加えます。結果の画像はかなり滑らかになるはずです。
プレッツェル

2
gr.SmoothingMode = SmoothingMode.HighQualityの方が優れたコードです。現在、HighQualityとAntiAliasは同じものですが、将来的にはMicrosoftが何か新しいものを発明するでしょう。HighQualityは常に最良のもののエイリアスである必要があります。
Eyal

4
メソッド「System.Drawing.Image.Save(string filename、ImageFormat format)」は、JPGを品質75で保存します。画像はぼやけており、クライアントには受け入れられませんでした。どのような品質の問題を修正することは代わりに保存(文字列のファイル名、ImageCodecInfoエンコーダ、EncoderParameters encoderParams)を使用し、100に近い品質の値を指定することだった
リガ

3
これにより、画像の境界にアーティファクトが
残る

1
これを使うと国境にアーティファクトがありました。提案はありますか?
Gopichandar

32

ベクターグラフィックを使用している場合を除き、画像の品質を損なう可能性がない限り、画像のサイズを変更する方法はありません。


1
あなたがそれを拡大しているのでなければ...
ブレア・コンラッド

情報を失うことなく拡張できますが、さまざまな種類のフィルターを使用して、さまざまな結果を得ることができます-ゼロ次ホールド、ローパスなど
Adam Rosenfield

24
private static Image resizeImage(Image imgToResize, Size size)
{
    int sourceWidth = imgToResize.Width;
    int sourceHeight = imgToResize.Height;

    float nPercent = 0;
    float nPercentW = 0;
    float nPercentH = 0;

    nPercentW = ((float)size.Width / (float)sourceWidth);
    nPercentH = ((float)size.Height / (float)sourceHeight);

    if (nPercentH < nPercentW)
        nPercent = nPercentH;
    else
        nPercent = nPercentW;

    int destWidth = (int)(sourceWidth * nPercent);
    int destHeight = (int)(sourceHeight * nPercent);

    Bitmap b = new Bitmap(destWidth, destHeight);
    Graphics g = Graphics.FromImage((Image)b);
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;

    g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
    g.Dispose();

    return (Image)b;
}

ここから


これは機能しますが、クリス・エリクソの答えと同じ品質を返します。サイズが使用されているのを見るのはうれしい...
サムジョーンズ


3

サイズを変更しない限り、これをラスターグラフィックスで行うことはできません。

優れたフィルタリングとスムージングでできることは、目立つものを失うことなくサイズを変更することです品質です。

画像のDPIメタデータを変更することもできます(一部の画像があると仮定)。これにより、正確に同じピクセル数が維持されますが、「実際の」測定における画像エディターの考え方が変更されます。

そして、すべてのベースをカバーするために、実際の画像サイズではなく画像のファイルサイズだけを意味している場合は、画像データのロスレスエンコーディングを検討することをお勧めします。これについての私の提案は、画像を.pngファイルとして再保存することです(私はWindowsの画像の無料トランスコーダーとしてペイントを使用する傾向があります。ペイントで画像を読み込み、新しい形式で保存します)


3

ピクセル数を減らしているからといって、品質を落とさずに画像のサイズを変更することはできません。

ブラウザは画像のサイズ変更をうまく処理しないため、クライアント側のサイズを縮小しないでください。

できることは、レンダリングする前に、またはユーザーがアップロードするときに、プログラムでサイズを変更することです。

これは、c#でこれを行う1つの方法を説明する記事です。http//www.codeproject.com/KB/GDI-plus/imageresize.aspx


「ブラウザは画像のサイズ変更をうまく行いません」-これは'08年には本当だったかもしれませんが、幸い、現在この領域では数マイル進んでいます(古いIEバージョンが徐々に消えていくため、かなりの程度です)。
Camilo Martin

2

このオープンソースASP.NETモジュール画像サイズ変更品質が気に入っているかどうかを確認してくださいライブデモがあるので、自分でいじってみてください。Photoshopの出力と区別するのは(私には)不可能です。また、ファイルサイズも同様です。MSはJPEGエンコーダで優れた機能を果たしました。


JPEGは比較的単純な形式です。最終的には一般的な圧縮を使用したDCT係数に過ぎないため、品質/ファイルサイズの点でリファレンス実装に勝つためにできることは多くありません。
Camilo Martin

1

状況に応じたサイズ変更があり、使用できるかどうかはわかりませんが、一見の価値があります。

素敵なビデオデモ(拡大は中央に向かって表示されます) http://www.youtube.com/watch?v=vIFCV2spKtg

ここにいくつかのコードがあるかもしれません。 http://www.semanticmetadata.net/2007/08/30/content-aware-image-resizing-gpl-implementation/

やりすぎでしたか?たぶん、拡大画像に適用してピクセルを少しぼかすことができる簡単なフィルターがあるかもしれません。


元の質問とは関係ないのではないかと思いますが、この手法は大好きです。
Matt Cruikshank

1

サイズを変更していますか、それとも小さくしていますか?小さな%または2倍、3倍のような大きな係数 アプリケーションの品質とはどういう意味ですか?そして、どのような種類の画像-写真、ハードエッジの線画、または何ですか?独自の低レベルのピクセルグラインディングコードを作成するか、それを既存のライブラリ(.netなど)で可能な限り実行しようとしていますか?

このトピックについては多くの知識があります。重要な概念は補間です。

閲覧の推奨事項:
* http://www.all-in-one.ee/~dersch/interpolator/interpolator.html
* http://www.cambridgeincolour.com/tutorials/image-interpolation.htm
* C#の場合:https: //secure.codeproject.com/KB/GDI-plus/imageprocessing4.aspx?display=PrintAll&fid=3657&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26&select=629945 *これは、Java固有のものですが、参考になるかもしれません-http : //today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html


1

ここでは、このクラスに透かしコードを追加することもできます。

public class ImageProcessor
    {
        public Bitmap Resize(Bitmap image, int newWidth, int newHeight, string message)
        {
            try
            {
                Bitmap newImage = new Bitmap(newWidth, Calculations(image.Width, image.Height, newWidth));

                using (Graphics gr = Graphics.FromImage(newImage))
                {
                    gr.SmoothingMode = SmoothingMode.AntiAlias;
                    gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    gr.DrawImage(image, new Rectangle(0, 0, newImage.Width, newImage.Height));

                    var myBrush = new SolidBrush(Color.FromArgb(70, 205, 205, 205));

                    double diagonal = Math.Sqrt(newImage.Width * newImage.Width + newImage.Height * newImage.Height);

                    Rectangle containerBox = new Rectangle();

                    containerBox.X = (int)(diagonal / 10);
                    float messageLength = (float)(diagonal / message.Length * 1);
                    containerBox.Y = -(int)(messageLength / 1.6);

                    Font stringFont = new Font("verdana", messageLength);

                    StringFormat sf = new StringFormat();

                    float slope = (float)(Math.Atan2(newImage.Height, newImage.Width) * 180 / Math.PI);

                    gr.RotateTransform(slope);
                    gr.DrawString(message, stringFont, myBrush, containerBox, sf);
                    return newImage;
                }
            }
            catch (Exception exc)
            {
                throw exc;
            }
        }

        public int Calculations(decimal w1, decimal h1, int newWidth)
        {
            decimal height = 0;
            decimal ratio = 0;


            if (newWidth < w1)
            {
                ratio = w1 / newWidth;
                height = h1 / ratio;

                return height.To<int>();
            }

            if (w1 < newWidth)
            {
                ratio = newWidth / w1;
                height = h1 * ratio;
                return height.To<int>();
            }

            return height.To<int>();
        }

    }

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.