WykopGwardel.icio.us

ImageResizer - dodawanie ramek i podpisów

07 lutego 2008, 17:21

KomentarzeKomentarze: 1 KategorieKategorie: .net image

Tym razem potrzebowałem dodać ramki do wielu zdjęć, które chciałem wrzucić na forum poświęcone fotografii. ImageResizer dobrze akurat sie do tego nadaje. W jednej operacji mogę zmniejszyć i dodać ramkę i podpis :)

Wyżej widać jak obecnie wygląda interface opcji zaawansowanych, do których należy definiowanie ramek i podpisu :) Poniżej poglądowa fotka z wygenerowaną ramką i podpisem.

A teraz coś od strony technicznej. :) 

Jak widać definicja ramki i podpisu znajduje się na zakładce. Oznacza to, że przewiduję inne opcje w przyszłości. Między innymi ustawienia wyostrzania na kanale luminancji w przestrzeni barw Lab. Od strony programistycznej także wymaga to odpowiedniego przygotowania, aby nie zabrnąć w kozi róg.

Dlatego też każda funkcja przetwarzająca plik jest dedykowaną klasą, która implementuje prosty interface o nazwie IWorker.

 

   1:      public interface IWorker
   2:      {
   3:          string Name { get;}
   4:          void Process(ref Image image);
   5:      }

IWorker posiada właściwość Name zwracającą nazwę funkcjonalności (przyda się do plug'inów) oraz metodę Process, która przyjmuje jeden parametr, a krótko mówiąc obrazek do przerobienia.

Worker o nazwie Frame ma następującą implementację:

 

   1:          public void Process(ref System.Drawing.Image image)
   2:          {
   3:              Bitmap bmp = new Bitmap(image.Width + Width * 2, image.Height + Width * 2 + BottomHeight);
   4:              using (Graphics g = Graphics.FromImage(bmp))
   5:              {
   6:                  g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
   7:                  g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
   8:                  g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
   9:                  g.Clear(FrameColor);
  10:                  g.DrawImage(image, Width, Width, image.Width, image.Height);
  11:   
  12:                  if (Text.Length > 0)
  13:                  {
  14:                      SizeF textSize = g.MeasureString(this.Text, this.Font);
  15:                      g.DrawString(this.Text, this.Font, new SolidBrush(FontColor), this.GetStringLocation(textSize, new Size(bmp.Width, bmp.Height))); 
  16:                  }
  17:              }
  18:              image = bmp;
  19:          }

Po krótce - linia:

  • (3) - tworzymy nową bitmapę i nadajemy jej wymiar powiększony o ramkę;
  • (4) na podstawie nowej bitmapy tworzymy obiekt Graphics, który posłuży nam do 'rysowania';
  • (6-8) ustawiamy parametry rysowania - jak najlepsze;
  • (9) wypełniamy kolorem ramki;
  • (10) wstawiamy źródłowy (już wcześniej pomniejszony) obrazek;
  • (12) jeśli jest do dodania podpis;
  • (14) pobieramy miarę tekstu w pixelach - potrzebne do rozplanowania na docelowym zdjęciu;
  • (15) wstawiamy sam tekst.

Metoda GetStringLocation na podstawie wstępnie wybranej lokalizacji oblicza punkt, w którym ma zostać wstawiony podpis. Poniżej przykładowe wyliczenie dla typu BottomCenter:

   1:                  case ContentAlignment.BottomCenter:
   2:                      x = (imageSize.Width - textSize.Width) / 2;
   3:                      y = imageSize.Height - TextPadding - centerHeight;

Użyteczność od strony interfejsu uzytkownika oczywiście jeszcze do dopracowania. Zastanawiam się, czy aby zakładki nie powinny być przypadkiem na głównej formie bez dodatkowych okienek. Zdaje się, że tak kolejne opcje będą szybciej dostępne. Poza tym w obecnej wersji nie są zapisywane ostatnie ustawienia, co może być uciążliwe, ale niebawem dodam taką możliwość. :)

Nowe pomysły na przyszłość?

Przyszło mi do głowy, aby dodać możliwość zwinięcia programu do tray'a co przy większej ilości plików może się przydać. Natomiast rozwinięciem tego pomysłu jest dodanie możliwości skanowania zmian podanego katalogu źródłowego. ImageResizer po pojawieniu się nowych plików automatycznie wykonałby operacje wg. zadanych parametrów.

Zgrywam zdjęcia z karty, za chwilę dostaję je pomniejszone, podpisane z ramkami (plus inne nowe funkcje) i gotowe do wysłania pocztą :) Jak myślicie?

A tym czasem zapraszam do działu Projekty.Net po nową wersję :) 

PS 

Ja często fotki poddaję obróbce, ale fotki pstrykane na przyjęciu do kotleta nie zawsze tego wymagają, a rodzina już się niecierpliwi, aby je szybko obejrzeć :)

Łukasz
2008-02-09 20:39

Ja myślę że ta poczta to świetny pomysł ;D

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.