Изменение размера изображений в C#

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

     public Image ResizeImage(Size size)
    {
        int sourceWidth = _Image.Width;
        int sourceHeight = _Image.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(_Image, 0, 0, destWidth, destHeight);
        g.Dispose();

        return (Image)b;
    }

Я обычно передаю размер с шириной 100 пикселей и высотой 100 пикселей - как часть моих требований, я не могу иметь ни одно измерение (высота или ширина) меньше 100 пикселей, поэтому, если соотношение сторон не является квадратным, другое размер был бы выше.

Что я обнаружил с помощью этого метода, так это то, что иногда один из размеров будет меньше 100 пикселей, например 96 пикселей или 99 пикселей. Как я могу изменить этот метод, чтобы этого не произошло?


person Chris    schedule 14.04.2013    source источник
comment
Я думаю, что самым простым способом было бы проверить destWidth или height на ‹100, если они есть, а затем умножить как w, так и h на скаляр, полученный из минимального/ошибочного значения vals (надеюсь, это даст число, подобное 1,05 (не написано как ответ как с телефона проще писать комментарии!)   -  person Sayse    schedule 14.04.2013
comment
его bcz сохраняет соотношение сторон вашего оригинального изображения   -  person Amit Singh    schedule 14.04.2013


Ответы (1)


Код просто не подходит. Он не набирает очков за использование математики с плавающей запятой, которая умеет неправильно округлять, поэтому вы можете легко получить 99 пикселей вместо 100. Всегда отдавайте предпочтение целочисленной математике, чтобы вы могли контролировать округление. И он просто ничего не делает, чтобы гарантировать, что одно из измерений достаточно велико, чтобы получить 96 пикселей. Просто напишите лучший код. Нравиться:

    public static Image ResizeImage(Image img, int minsize) {
        var size = img.Size;
        if (size.Width >= size.Height) {
            // Could be: if (size.Height < minsize) size.Height = minsize;
            size.Height = minsize;
            size.Width = (size.Height * img.Width + img.Height - 1) / img.Height;
        }
        else {
            size.Width = minsize;
            size.Height = (size.Width * img.Height + img.Width - 1) / img.Width;
        }
        return new Bitmap(img, size);
    }

Я оставил комментарий, чтобы показать, что вы делаете, если хотите убедиться, что изображение достаточно большое, и принимаете изображения большего размера. Из вопроса было непонятно. Если это так, то скопируйте этот оператор if в предложении else.

person Hans Passant    schedule 14.04.2013
comment
Для чего + img.Height - 1? - person DasKrümelmonster; 14.04.2013
comment
Это гарантирует, что размер всегда округляется в большую сторону. - person Hans Passant; 14.04.2013
comment
Да, но почему? Есть ли угловой случай, где это необходимо? Это вносит небольшие ошибки (‹ 1 пиксель), но я не вижу необходимости... - person DasKrümelmonster; 14.04.2013
comment
ОП не указал предпочтения, кроме того, что ему действительно не нравилось округление исходного кода в меньшую сторону. Ошибка 0,5 среднего пикселя неизбежна, выбор состоит в том, чтобы увеличить или уменьшить. Код по-прежнему идеально подходит, если позволяет масштабирование. - person Hans Passant; 14.04.2013