Загрузка изображения / настройка DPI, но с гарантией размера файла <= 200 КБ - PullRequest
1 голос
/ 13 декабря 2011

У меня есть форма (с использованием MVC2), в которой есть скрипт загрузки изображений, но правила для окончательного изображения, хранящегося на сервере, довольно строги.Я могу принудительно установить размер файла, который мне нужен, но он всегда превышает размер файла, требуемый ... поэтому я могу разрешить изображение размером менее 200 Кб, но после обработки моего кода оно становится немного больше.

Вот правила, которых я должен придерживаться:

  • Фотографии должны быть цветными
  • Допустимые типы изображений для фотографии: .JPG или .GIF
  • Максимальный размер изображения составляет 200 КБ
  • Размеры фотографии на значке будут составлять 274 пикселя (в ширину) x 354 пикселя (в высоту) @ 200 точек на дюйм (глубина пикселей на дюйм)

Это то, что у меня есть в данный момент:

[HttpPost]
public ActionResult ImageUpload(HttpPostedFileBase fileBase)
{
    ImageService imageService = new ImageService();

    if (fileBase != null  && fileBase.ContentLength > 0 && fileBase.ContentLength < 204800 && fileBase.ContentType.Contains("image/"))
    {
            string profileUploadPath = "~/Resources/images";

            Path.GetExtension(fileBase.ContentType);
            var newGuid = Guid.NewGuid();
            var extension = Path.GetExtension(fileBase.FileName);

            if (extension.ToLower() != ".jpg" && extension.ToLower() != ".gif") // only allow these types
            {
                return View("WrongFileType", extension);
            }

            EncoderParameters encodingParameters = new EncoderParameters(1);
            encodingParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 70L); // Set the JPG Quality percentage

            ImageCodecInfo jpgEncoder = imageService.GetEncoderInfo("image/jpeg");
            var uploadedimage = Image.FromStream(fileBase.InputStream, true, true);

            Bitmap originalImage = new Bitmap(uploadedimage);
            Bitmap newImage = new Bitmap(originalImage, 274, 354);

            Graphics g = Graphics.FromImage(newImage);
            g.InterpolationMode = InterpolationMode.HighQualityBilinear;
            g.DrawImage(originalImage, 0, 0, newImage.Width, newImage.Height);

            var streamLarge = new MemoryStream();
            newImage.Save(streamLarge, jpgEncoder, encodingParameters);

            var fileExtension = Path.GetExtension(extension);
            var ImageName = newGuid + fileExtension;

            newImage.Save(Server.MapPath(profileUploadPath) + ImageName);
            //newImage.WriteAllBytes(Server.MapPath(profileUploadPath) + ImageName, streamLarge.ToArray());

            originalImage.Dispose();
            newImage.Dispose();
            streamLarge.Dispose();

            return View("Success");
        }
    return View("InvalidImage");
}

Просто добавлю: изображения отправляются на печать на карту, поэтому значение DPI важно.Но я понимаю, что 200К - это не много для печатного изображения ... ни одно из этих правил не является моим!Как и в случае с этим кодом, загруженное изображение размером почти 200 КБ в итоге стоит 238 КБ (иш)

.

Ответы [ 3 ]

3 голосов
/ 13 декабря 2011

Очень сложно рассчитать размер JPEG заранее. Сказав это, вам не нужно много сжимать.

Давайте просто посмотрим на некоторые показатели:

274 * 354 = 96996 пикселей. Если у вас есть 8 бит на пиксель и 3 цвета каналы (то есть 24-битный цвет), то у вас есть:

274 * 354 * 8 * 3 = 2,327,904 бит = 290988 байт = 284,17 кбайт.

200 / 284,17 ~ 0,70.

Вам нужно только уменьшить его до 70% от исходного размера.

К сожалению, именно в этот момент мы достигли предела моих знаний в этой области! Но я считаю, что при сохранении в формате jpeg он все равно будет в нужном диапазоне размеров, даже если сохранится при настройке наивысшего качества.

Я бы предположил установить качество на 70 и посмотреть, что получится.

РЕДАКТИРОВАТЬ: настройки DPI

Видимо, вам нужно всего лишь изменить данные EXIF. Смотрите этот ответ: https://stackoverflow.com/a/4427411/234415

2 голосов
/ 13 декабря 2011

Вам следует поэкспериментировать с настройкой качества JPEG.В настоящее время он установлен на 90, 80 может быть достаточно и приведет к уменьшению файла.

1 голос
/ 13 декабря 2011

Я вижу некоторые проблемы с кодом:

  • Вы используете GetThumbnailImage для создания миниатюры, но это не предназначено для таких больших миниатюр.Он работает до 120x120 пикселей.Если изображение имеет встроенный эскиз, он будет использоваться вместо уменьшения полного изображения, поэтому вы будете увеличивать изображение меньшего размера с очевидными проблемами качества.
  • Вы сохраняете эскиз в потоке памяти, который вы затем просто выбрасываете.
  • Вы сохраняете миниатюру в файл, не указывая кодировщик, а это значит, что он будет сохранен в виде JPEG-файла с низким сжатием или PNG-изображения, поэтому вы получаетебольший размер файла.
  • Вы никогда не располагаете объектом uploadedImage.

Примечание. Разрешение (PPI / DPI) не имеет значения при отображении изображений в Интернете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...