Изменение размера изображения без потери качества
Мне нужно resize изображения, но качество изображения не может быть затронуто этим.
- Обнаружение мыши с динамической формой
- Прозрачные изображения с помощью C # WinForms
- Разработка Android: использование образа из активов в HTML-формате WebView
- Метод Image.FromStream () возвращает исключение Invalid Argument
- Изменение размера изображения в asp.net без потери качества изображения
- Преобразование байт-массива в изображение и отображение в режиме просмотра бритвы
- Как конвертировать TIFF в JPEG / PNG в java
- Как ограничить тип файла в элементе управления FileUpload
Как говорит 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)); }
Если вы не делаете векторную графику, невозможно resize изображения без потенциального потери качества изображения.
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; }
отсюда
Я считаю, что вы хотите сделать это, «Resize / Resample» ваши изображения. Вот хороший сайт, который дает инструкции и предоставляет class утилиты (что я также использую):
http://www.codeproject.com/KB/GDI-plus/imgresizoutperfgdiplus.aspx
Если вы не измените размер, вы не сможете сделать это с растровой графикой.
То, что вы можете сделать с хорошей фильтрацией и сглаживанием, – это resize без потери качества.
Вы также можете изменить метаданные DPI изображения (при условии, что у него есть некоторые), которые будут содержать точно такое же количество пикселей, но изменят, как редакторы изображений думают об этом в измерениях «реального мира».
И просто чтобы охватить все базы, если вы действительно имели в виду только размер файла изображения, а не фактические размеры изображения, я предлагаю вам посмотреть на без потерь кодирование данных изображения. Мое предложение для этого было бы сохранить изображение как файл .png (я, как правило, использую краску как бесплатный транскодер для изображений в windowsх. Загружайте изображение в краску, сохраняйте как в новом формате)
Вы не можете изменять размер изображения без потери качества, просто потому, что уменьшаете количество пикселей.
Не уменьшайте размер клиентской стороны, потому что браузеры не делают хорошую работу по изменению размеров изображений.
Что вы можете сделать, это программно resize, прежде чем вы его визуализируете, или как пользователь его загрузит.
Вот статья, в которой объясняется один из способов сделать это в 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/
Это было лишнее? Возможно, есть несколько простых фильтров, которые вы можете применить к увеличенному изображению, чтобы немного размыть пиксели, вы могли бы изучить это.
Вы изменяете размер больше или меньше? При небольшом% или большем коэффициенте, таком как 2x, 3x? Что вы подразумеваете под качество для своего приложения? И какие типы изображений – фотографии, чертежи с жесткими краями или что? Написание собственного низкоуровневого кода для измельчения пикселей или попытки сделать это как можно больше с существующими библиотеками (.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-specific, но может быть образовательным – http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html
Здесь вы также можете добавить коды водяных знаков в этом classе:
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(); } if (w1 < newWidth) { ratio = newWidth / w1; height = h1 * ratio; return height.To (); } return height.To (); } }
Вот тема форума, в которой приведен пример кода изменения размера изображения C #. Вы можете использовать один из связующих библиотек GD для повторной дискретизации в C #.