С# Уменьшить изображение до определенного количества пикселей

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

public void downscaleByCalculateInSampleSize(string filePath, string newPath)
    {
        int reqNumberOfPixels = 6000000;

        double inSampleSize = 1;

        using (System.Drawing.Image oImage = System.Drawing.Image.FromFile(filePath))
        {
            int newWidth = oImage.Width;
            int newHeight = oImage.Height;

            int actualNumberofPixels = oImage.Width * oImage.Height;

            if (actualNumberofPixels > reqNumberOfPixels)
            {
                inSampleSize = Math.Sqrt(actualNumberofPixels / reqNumberOfPixels);

                newWidth = Convert.ToInt32(Math.Round((float)oImage.Width / inSampleSize));
                newHeight = Convert.ToInt32(Math.Round((float)oImage.Height / inSampleSize));
            }

            var newImage = new Bitmap(newWidth, newHeight);

            Graphics graphics = Graphics.FromImage(newImage);

            graphics.DrawImage(oImage, 0, 0, newWidth, newHeight);

            newImage.Save(newPath);
        }
    }

Я попытался уменьшить изображение с разрешением 6367 x 4751 пикселей и разрешением 72 dpi (глубина 24 бита) размером 8,03 МБ. Я изменил размер этого изображения и ожидал, что оно будет гораздо меньше по размеру (ниже 8 МБ), но у меня 17. Масштабированное изображение составляет 2847 x 2125 (96 точек на дюйм с глубиной 32 бита). Почему это происходит? Есть ли способ уменьшить изображение до запрошенного количества пикселей, чтобы результат был намного меньше? Меня не волнует разрешение...


person Dana    schedule 06.11.2017    source источник
comment
Вопрос: ваш ввод jpeg, а вывод bmp?   -  person Stefan    schedule 06.11.2017
comment
Оба файла JPG   -  person Dana    schedule 06.11.2017
comment
Это странно, потому что, когда я занимаюсь математикой: 2847 x 2125 x 24bpp, я получаю прибл. 17 МБ. Таким образом, вы можете сохранить файл в формате jpeg, размер файла указывает на то, что это bmp.   -  person Stefan    schedule 06.11.2017
comment
Возможно, это даст дополнительную информацию: stackoverflow.com/questions/21218017/   -  person Stefan    schedule 06.11.2017
comment
Забыл упомянуть: у первого битовая глубина 24, а у измененного - 32. Я отредактирую свой вопрос.   -  person Dana    schedule 06.11.2017
comment
Возможный дубликат сохранения изображения в файл   -  person Stefan    schedule 06.11.2017
comment
Вы пробовали: newImage.Save(newPath, ImageFormat.Jpeg);?   -  person Stefan    schedule 06.11.2017
comment
расширение .jpg не означает, что этот файл в формате jpeg. используйте 1_   -  person L.B    schedule 06.11.2017
comment
Спасибо за совет @L.B. я этого не знал   -  person Dana    schedule 06.11.2017


Ответы (1)


Вы используете целочисленное деление и усекаете результаты по адресу:

inSampleSize = Math.Sqrt(actualNumberofPixels / reqNumberOfPixels);

Вместо этого попробуйте:

inSampleSize = Math.Sqrt((double)actualNumberofPixels / (double)reqNumberOfPixels);

Кроме того, сохраните с помощью:

newImage.Save(newPath, ImageFormat.Jpeg);

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

person Ehz    schedule 06.11.2017