Изменение размера изображения без потери качества

Мне нужно изменить размер изображения, но качество изображения не может быть затронуто этим.

Ответ 1

Как говорится в rcar, вы не можете не потерять какое-то качество, лучше всего, что вы можете сделать в С#:

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

Ответ 2

Если вы не делаете векторную графику, нет возможности изменять размер изображения без потери качества изображения.

Ответ 3

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

из здесь

Ответ 4

Я считаю, что вы хотите сделать это, "Resize/Resample" ваши изображения. Вот хороший сайт, который дает инструкции и предоставляет класс утилиты (что я также использую):

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

Ответ 5

Вы не можете изменять размер изображения без потери качества, просто потому, что уменьшаете количество пикселей.

Не уменьшайте размер клиентской стороны, потому что браузеры не делают хорошую работу по изменению размеров изображений.

Что вы можете сделать, это программно изменить размер перед его рендерингом или как пользователь его загрузит.

Вот статья, которая объясняет один из способов сделать это в С#: http://www.codeproject.com/KB/GDI-plus/imageresize.aspx

Ответ 6

Если вы не измените размер, вы не сможете сделать это с растровой графикой.

Что вы можете сделать с хорошей фильтрацией и сглаживанием, это изменить размер без потери качества примечания.

Вы также можете изменить метаданные DPI изображения (при условии, что оно есть), которое будет содержать точно такое же количество пикселей, но изменит, как редакторы изображений думают об этом в измерениях "реального мира".

И просто чтобы охватить все базы, если вы действительно имели в виду только размер файла изображения, а не фактические размеры изображения, я предлагаю вам посмотреть на без потерь кодировку данных изображения. Мое предложение для этого было бы сохранить изображение как файл .png(я обычно использую краску как бесплатный транскодер для изображений в окнах. Загружайте изображение в краску, сохраняйте как в новом формате)

Ответ 7

Посмотрите, нравится ли вам качество изменения размера этого модуля ASP.NET с открытым исходным кодом. Там есть живая демонстрация, так что вы можете возиться с ним самим. Это дает результаты, которые (для меня) невозможно отличить от вывода Photoshop. Он также имеет схожие размеры файлов - MS отлично справилась с их кодировщиком JPEG.

Ответ 8

Есть что-то там, изменение размера контекста, не знаю, сможете ли вы его использовать, но стоит посмотреть, что точно

Хорошая видео-демонстрация (Расширение появляется в середине) http://www.youtube.com/watch?v=vIFCV2spKtg

Здесь может быть какой-то код. http://www.semanticmetadata.net/2007/08/30/content-aware-image-resizing-gpl-implementation/

Было ли это лишнее? Возможно, есть несколько простых фильтров, которые вы можете применить к увеличенному изображению, чтобы немного размыть пиксели, вы могли бы изучить это.

Ответ 9

Вы изменяете размер больше или меньше? При небольшом% или большем коэффициенте, таком как 2x, 3x? Что вы подразумеваете под качество для своего приложения? И какие типы изображений - фотографии, чертежи с жесткими краями или что? Напиши свой собственный низкоуровневый код измельчения пикселей или пытаясь сделать это как можно больше с существующими библиотеками (.net или что-то еще)?

Существует большой объем знаний по этой теме. Ключевой концепцией является интерполяция.

Рекомендации по просмотру:
* http://www.all-in-one.ee/~dersch/interpolator/interpolator.html
* http://www.cambridgeincolour.com/tutorials/image-interpolation.htm
* для С#: 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

Ответ 10

Здесь вы также можете добавить коды водяного знака в этом классе:

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

    }

Ответ 11

Вот поток форума, который содержит образец кода изменения размера С#. Вы можете использовать одну из GD library для передискретизации в С#.