2011-12-13 2 views
1

У меня есть форма (с использованием MVC2), которая имеет сценарий загрузки изображений, но правила для окончательного изображения, хранящиеся на сервере, довольно строгие. Я могу заставить файл размер, который я хочу, но он всегда заканчивается, превышающий требуемый размер файла ... поэтому я могу разрешить изображение суб-200k, но как только мой код обработал его, он немного больше.Загрузка изображения/установка DPI, но обеспечение размера файла <= 200k

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

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

Это то, что я в настоящее время:

[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 тыс. Не очень много для печатного изображения. Ничто из этого не является моим бизнес-правилами! Как она стоит с этим кодом изображение закачанный это довольно много 200k, заканчивается стоимостью 238k (МОГ)

+1

Пожалуйста, не прикрепите свои заголовки к «C#». Для этого нужны теги. –

+0

Изменил код, чтобы он не использовал миниатюру (и некоторые другие исправления) – beebul

ответ

1

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

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

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

+0

Да, я удалил (безуспешно) некоторые другие элементы из этого кода, которые делали материал, не имеющий отношения к этому проекту. Также изображения уходят на печать на карте, поэтому DPI важен. Но я понимаю, что 200 тыс. Не очень много для печатного изображения. Ничто из этого не является моим бизнес-правилами! :) – beebul

+1

@beebul, DPI важен при печати, но обычно это определяется приложением или драйвером, а не полем, встроенным в файл. Как правило, вы должны беспокоиться о размерах пикселей и полностью игнорировать DPI, поскольку он уже используется для вычисления необходимых размеров пикселей. –

+0

На самом деле файлы заканчиваются как png. Как я могу заставить их jpg ... Я думаю, что это может быть решением. – beebul

3

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

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

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

274 ​​* 354 * 8 * 3 = 2,327,904 bits = 290988 bytes = 284.17 kb.

200/284.17 ~ 0.70.

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

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

Я думаю, при настройке качества на 70 и посмотрим, что произойдет.

EDIT: DPI настройки

Видимо вам нужно только изменить данные EXIF. См. Этот ответ: https://stackoverflow.com/a/4427411/234415

+0

Чтобы быть консервативным, вы должны принять k = 1000, а не 1024. –

+0

Справедливая точка; Я показываю свой возраст, я думаю! В этом случае это будет «68,7%», но я не думаю, что параметры качества в любом случае зависят от размера файла. –

+1

Если бы вы были достаточно взрослыми, помните, что 'k' имел смысл задолго до того, как компьютерная индустрия попробовала другое определение. Меня всегда удивляют люди, заявляющие о заговоре со стороны производителей дисков, потому что их определения размера больше, чем ОС; для меня всегда было ясно, что ошибка связана с ОС. И вы правы, настройка качества JPEG не указывает абсолютную степень сжатия. –

2

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

Смежные вопросы