web-dev-qa-db-ja.com

品質を損なうことなく画像のサイズを変更する

画像のサイズを変更する必要がありますが、これにより画質が影響を受けることはありません。

104
public static

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));
}
211
Kris Erickson

ベクターグラフィックを使用している場合を除き、画像の品質を潜在的に損なうことなく画像のサイズを変更する方法はありません。

32
Randy
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;
}

from ここ

24
ozba

あなたがやろうとしているのは、画像の「サイズ変更/リサンプル」だと思います。これは、指示を提供し、ユーティリティクラスを提供する優れたサイトです(たまたま使用しています)。

http://www.codeproject.com/KB/GDI-plus/imgresizoutperfgdiplus.aspx

5
Ashlocke

ピクセル数を減らしているという理由だけで、品質を損なうことなく画像のサイズを変更することはできません。

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

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

C#でこれを行う1つの方法を説明する記事を次に示します。 http://www.codeproject.com/KB/GDI-plus/imageresize.aspx

3
AaronS

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

適切なフィルタリングとスムージングでできることは、顕著な品質を失うことなくサイズを変更することです。

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

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

3
workmad3

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

2
Nathanael Jones

そこに何かがあります、コンテキストを意識したサイズ変更、あなたがそれを使用できるかどうかわかりませんが、それは見る価値があります、それは確かです

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

ここにいくつかのコードがあります。 http://www.semanticmetadata.net/2007/08/30/content-aware-image-resizing-gpl-implementation/

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

1
Victor

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

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

    }
1
cagin

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

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

閲覧の推奨事項:
* http://www.all-in-one.ee/~dersch/interpolator/interpolator.html
* http://www.cambridgeincolour.com/tutorials/image-interpolation.htm
* for 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
DarenW

コードサンプルのサイズを変更するC#イメージを提供する フォーラムスレッド を次に示します。 Gdライブラリ バインダーのいずれかを使用して、C#でリサンプリングを実行できます。

0
jimg