WykopGwardel.icio.us

Masowe zmniejszanie zdjęć

22 stycznia 2008, 16:45

KomentarzeKomentarze: 0 KategorieKategorie: .net image

Kilka dni temu postanowiłem zgrać sobie na dysk wszystkie fotki, które z czasem zgrywałem na płytki robiąc kopię bezpieczeństwa. Fotki te chciałem zgrać na dysk, aby móc je przeglądać. Do przeglądania nie potrzebna mi jest pełna wielkość z 8 megapikselowej matrycy, więc chciałem je masowo pomniejszyć. Pomyślałem, że zastosuję się do rady kolegi i zainstaluję fajny poniekąd programik IrfanView.

Niestety ów programik podczas zgrywania paczki kilkuset zdjęć z płyty na dysk i pomniejszając je zawieszał mi się uporczywie po około 100 przetworzonych. Próbowałem kilka razy na różne sposoby i za każdym razem efekt był taki sam.

Postanowiłem wtedy szybko naskrobać sobie własny programik, który wykona czarną robotę i nazwałem go umownie ImageResizer. Użyłem do tego napisanej kiedyś kiedyś klasy GraphicHelper, w którą co i raz dorzucam jakieś fajne, znalezione na sieci rozwiązania. Między innymi swoje rozwiązanie szybkiego ładowania obrazków do pamięci. :)

Cały program składa się z kilkunastu linijek. Najpierw odczytuję wszystkie pliki typu JPG z zadanego katalogu. Dla każdego pliku następuje skalowanie do zadanej maksymalnej szerokości i wysokości z zachowaniem stosunku długości boków. Do wczytania obrazka do pamięci użyłem następującej metody:

 

   1:          public static Image LoadImage(string fileName, bool validateImageData)
   2:          {
   3:              MemoryStream mem = new MemoryStream(File.ReadAllBytes(fileName), true);
   4:              return Image.FromStream(mem, true, validateImageData);
   5:          }

Parametr validateImageData ustawiam na false, dzięki temu załadowanie trwa ułamki sekundy.

Dalej kiedy mam już "w ręku" obiekt typu Image wykonuję skalowanie stosując rodzaj interpolacji ustawiony jako HighQualityBicubic, czyli krótko mówiąc dającą najlepszą jakość. Poniżej kolejna metoda klasy GraphicsHelper:

 

   1:          public static Image Resize(Image oryginal, int maxWidth, int maxHeight, System.Drawing.Drawing2D.InterpolationMode interpolationMode)
   2:          {
   3:              int w, h;
   4:              ScaleImage(oryginal.Width, oryginal.Height, maxWidth, maxHeight, out w, out h);
   5:              Bitmap bitmap = new Bitmap(w, h);
   6:              bitmap.SetResolution(72, 72);
   7:              using (Graphics graphics = Graphics.FromImage(bitmap))
   8:              {
   9:                  graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;
  10:                  graphics.InterpolationMode = interpolationMode;
  11:                  graphics.DrawImage(oryginal,
  12:                      new Rectangle(0, 0, w, h),
  13:                      new Rectangle(0, 0, oryginal.Width, oryginal.Height),
  14:                      GraphicsUnit.Pixel);
  15:              }
  16:              return bitmap;
  17:          }

Niektórzy zauważą, że ustalona jest na stałe rozdzielczość na 72dpi. Jest to zrobione celowo ze względu na osiągnięcie jak najlepszego obrazu przy jak najlepszym zmniejszeniu wielkości pliku wynikowego. Domyślnie metody tej używam do tworzenia podglądów, czyli z angielska - thumbnails.

Na koniec pozostaje już tylko zapisanie przetworzonego obrazka do pliku:

 

   1:          public static void SaveJPG(Image image, string filename, int quality)
   2:          {
   3:              ImageCodecInfo codecInfo = GetEncoderInfo("image/jpeg");
   4:              Encoder encoder = Encoder.Quality;
   5:              EncoderParameters encoderParams = new EncoderParameters(1);
   6:              EncoderParameter encoderParam = new EncoderParameter(encoder, (long)quality);
   7:              encoderParams.Param[0] = encoderParam;
   8:              image.Save(filename, codecInfo, encoderParams);
   9:          }

W ImageResizer stosuję JPEG quality ustawiony jako 90% dobrej jakości pliku wynikowego.

Programik test programem konsolowym, czyli bez interfejsu. Może w wolnej chwili się zdecyduję dorobić do niego ten fjuczer, ale tylko wtedy, gdy ilość opcji wzrośnie, a chcę dodać jeszcze do niego między innymi opcję podostrzania zdjęć po zmianie wielkości czy masowa edycja parametrów EXIF(w tym masowe usuwanie EXIF).  W obecnej wersji programik jest do pobrania w dziale Projekty.NET. Zapraszam :)

Ale o tym już inną razą.. :)

Ten post jest widoczny także na: ZINE.NET

Dodaj komentarz Dodaj komentarz

Twój email (niepublikowany/opcjonalnie):

Twoja strona (opcjonalnie):

Imię i nazwisko/nick (wymagane):

Treść (wymagane):

Chcę być poinformowany o kolejnych komentarzach:

To pole zostaw puste

Uwaga! Zastrzegam sobie prawo do usuwania obraźliwych i wulgarnych komentarzy.