画質に影響を与えずに画像のサイズを変更するにはどうすればよいですか?
11 に答える
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));
}
ベクター グラフィックスを使用している場合を除き、画像のサイズを変更して画質を損なう可能性はありません。
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;
}
ここから
サイズを大きくしない限り、ラスター グラフィックスでこれを行うことはできません。
優れたフィルタリングとスムージングでできることは、目立った品質を失うことなくサイズを変更することです。
画像の DPI メタデータを変更することもできます (いくつかあると仮定します)。これにより、まったく同じピクセル数が維持されますが、画像編集者が「実際の」測定でそれをどのように考えるかが変更されます。
そして、すべてのベースをカバーするために、実際の画像のサイズではなく、画像のファイルサイズだけを本当に意味している場合は、画像データのロスレスエンコーディングを検討することをお勧めします. これに対する私の提案は、画像を .png ファイルとして再保存することです (私は Windows で画像の無料のトランスコーダーとしてペイントを使用する傾向があります。ペイントで画像を読み込み、新しい形式で保存します)。
単純にピクセル数を減らしているという理由だけで、ある程度の品質を失わずに画像のサイズを変更することはできません。
ブラウザは画像のサイズ変更をうまくできないため、クライアント側でサイズを縮小しないでください。
できることは、レンダリングする前、またはユーザーがアップロードするときに、プログラムでサイズを変更することです。
C# でこれを行う 1 つの方法を説明する記事を次に示します: http://www.codeproject.com/KB/GDI-plus/imageresize.aspx
このオープンソースASP.NETモジュールの画像サイズ変更品質が気に入ったかどうかを確認してください。ライブデモがあるので、自分でいじることができます。Photoshopの出力と(私には)区別できない結果が得られます。また、同様のファイルサイズがあります-MSはJPEGエンコーダーで良い仕事をしました。
ここでは、このクラスに透かしコードを追加することもできます。
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>();
}
}
コンテキストに応じたサイズ変更というものがあります。それを使用できるかどうかはわかりませんが、一見の価値はあります。それは確かです
素敵なビデオ デモ (中央に向かって拡大表示されます) http://www.youtube.com/watch?v=vIFCV2spKtg
ここにいくつかのコードがある可能性があります。 http://www.semanticmetadata.net/2007/08/30/content-aware-image-resizing-gpl-implementation/
それはやり過ぎでしたか?拡大した画像に適用してピクセルを少しぼかすことができる簡単なフィルターがいくつかあるかもしれません。
サイズを大きくしますか、小さくしますか? 小さな%で、または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