画質に影響を与えずに画像のサイズを変更するにはどうすればよいですか?
画質に影響を与えずに画像のサイズを変更するにはどうすればよいですか?
回答:
以下のよう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;
}
あなたがしようとしているのは、画像の「サイズ変更/リサンプル」だと思います。指示を出し、ユーティリティクラスを提供する優れたサイトを次に示します(私もたまたま使用しています)。
http://www.codeproject.com/KB/GDI-plus/imgresizoutperfgdiplus.aspx
サイズを変更しない限り、これをラスターグラフィックスで行うことはできません。
優れたフィルタリングとスムージングでできることは、目立つものを失うことなくサイズを変更することです品質です。
画像のDPIメタデータを変更することもできます(一部の画像があると仮定)。これにより、正確に同じピクセル数が維持されますが、「実際の」測定における画像エディターの考え方が変更されます。
そして、すべてのベースをカバーするために、実際の画像サイズではなく画像のファイルサイズだけを意味している場合は、画像データのロスレスエンコーディングを検討することをお勧めします。これについての私の提案は、画像を.pngファイルとして再保存することです(私はWindowsの画像の無料トランスコーダーとしてペイントを使用する傾向があります。ペイントで画像を読み込み、新しい形式で保存します)
ピクセル数を減らしているからといって、品質を落とさずに画像のサイズを変更することはできません。
ブラウザは画像のサイズ変更をうまく処理しないため、クライアント側のサイズを縮小しないでください。
できることは、レンダリングする前に、またはユーザーがアップロードするときに、プログラムでサイズを変更することです。
これは、c#でこれを行う1つの方法を説明する記事です。http: //www.codeproject.com/KB/GDI-plus/imageresize.aspx
このオープンソースASP.NETモジュールの画像サイズ変更品質が気に入っているかどうかを確認してください。ライブデモがあるので、自分でいじってみてください。Photoshopの出力と区別するのは(私には)不可能です。また、ファイルサイズも同様です。MSはJPEGエンコーダで優れた機能を果たしました。
状況に応じたサイズ変更があり、使用できるかどうかはわかりませんが、一見の価値があります。
素敵なビデオデモ(拡大は中央に向かって表示されます) 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
ここでは、このクラスに透かしコードを追加することもできます。
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>();
}
}