Как я могу изменить размер изображения, не влияя на качество изображения?
Как я могу изменить размер изображения, не влияя на качество изображения?
Ответы:
Как говорит 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 (я обычно использую paint как бесплатный транскодер для изображений в Windows. Загрузите изображение в краске, сохраните как в новом формате)
Вы не можете изменить размер изображения без потери качества, просто потому, что вы уменьшаете количество пикселей.
Не уменьшайте размер на стороне клиента, потому что браузеры плохо меняют размер изображений.
Что вы можете сделать, так это программно изменить размер перед его визуализацией или по мере его загрузки пользователем.
Вот статья, в которой объясняется один из способов сделать это в C #: 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>();
}
}
Вот ветка форума, которая предоставляет пример кода C # для изменения размера изображения. Вы можете использовать одно из связывателей библиотеки GD для повторной выборки в C #.