Przeglądarka zdjęć w C#

Przeglądarka zdjęć w C#

Autor: Marcin Hałaczkiewicz

Opublikowano: 4/30/2007, 12:00 AM

Liczba odsłon: 93733

Tym razem napiszemy prostą przeglądarkę plików graficznych. Będzie ona obsługiwać kilka popularnych formatów takich jak jpeg, gif czy bmp. Aby ją stworzyć wykorzystamy kontrolkę PictureBox. Nauczymy się również wykorzystywać kółko myszki, gdyż aplikacja będzie je wykorzystywać do powiększenia.

Po standardowym utworzeniu nowego projektu (np. o nazwie Zdjecia), wybieramy menu Project a w nim Add Class. W oknie, które się otworzy wpisujemy nazwę klasy - MyPictureBox.

Nowo utworzona klasa będzie naszą własną kontrolką. Posłuży do wyświetlania obrazków, jednak w odróżnieniu od zwykłego PictureBoxa będzie wyposażona w paski przewijania, jeśli zdjęcie będzie za duże. Aby było to możliwe wyprowadzimy MyPictureBox z klasy Panel. Przechodzimy do pliku MyPictureBox.cs. Aby były dostępne standardowe kontrolki "okienkowe" u góry dopisujemy:

using System.Windows.Forms;

Następnie wyprowadzamy naszą klasę z klasy Panel, wewnątrz którego będzie wyświetlany PictureBox. Teraz klikamy prawym przyciskiem w Solution Explorer na pliku MyPictureBox.cs i wybieramy opcję View Designer. W nowo otwartym oknie dodajemy z Toolboxa kontrolkę PictureBox. W okienku z właściwościami zmieniamy jej nazwę na pic, a następnie klikamy na dowolnym pustym miejscu głównego okna. Dzięki temu w oknie Properties pojawią się właściwości naszej klasy (czyli po części Panelu). Ustawiamy pole AutoScroll na true. Spowoduje to wyświetlanie pasków przewijania, jeśli obrazek nie będzie się cały mieścił wewnątrz panelu. Zmieniamy również BackColor na Black oraz  Dock na Fill. Dzięki ostatniej operacji po umieszczeniu naszej kontrolki wewnątrz formy, wypełni ona całą jej powierzchnię.

Powróćmy do widoku kodu. Zauważmy, że przybyła nam nowa funkcja InitializeComponents. Zapisane jest w niej to, co stworzyliśmy za pomocą graficznego interfejsu. Stwórzmy konstruktor bezparametrowy i w jego wnętrzu umieśćmy wywołanie tej funkcji.

public MyPictureBox()
{
    InitializeComponent();
    this.Controls.Add(pic);
}

Ostatnią linijkę dopisaliśmy, gdyż chcemy, aby PictureBox był kontrolką "należącą" do Panelu, a nie żeby istniał równolegle obok niego. Gdybyśmy tego nie zrobili, żadne zdjęcie by się nie wyświetliło. Następnie wewnątrz klasy dopisujemy stałą:

const int MAXZOOM = 5;

Określa ona maksymalną krotność przybliżenia/oddalenia. Zajmijmy się teraz pisaniem własnych funkcji. Pierwszą z nich będzie LoadFromFile.

public void LoadFromFile(string txt)
{
    try
    {
        pic.Load(txt);
    }
    catch
    {
        MessageBox.Show("Nie można odczytać pliku", "Błąd",
            MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }
    pic.Size = pic.Image.Size;
    pic.SizeMode = PictureBoxSizeMode.CenterImage;
    dopasuj();
}

Próbuje ona wczytać grafikę z pliku, a gdy to się nie powiedzie wyświetla komunikat o błędzie. Następnie ustawia rozmiar PictureBoxa na rozmiar wyświetlanego obrazka. Ostatnia funkcja dopasuj jeszcze nie istnieje. Będzie ona wyświetlać zdjęcie w odpowiednim miejscu. Jeśli nie będzie się ono mieścić wewnątrz kontrolki to ulokuje je w lewym górnym rogu. Gdy kontrolka będzie większa niż grafika, to funkcja ją wycentruje. Oto treść funkcji:

private void dopasuj()
{
    if (pic.Width < this.Width &&
        pic.Height<this.Height)
    {
        pic.Location = new System.Drawing.Point(
            (this.Width - pic.Width) / 2,
            (this.Height - pic.Height) / 2);
    }
    else
    {
        pic.Location = new System.Drawing.Point(0, 0);
    }
}

Chcielibyśmy móc powiększać i pomniejszać obrazki, w związku z czym wyposażymy klasę MyPictureBox w funkcje ZoomIn oraz ZoomOut. Oto ich kod:

public void ZoomIn()
{
    if (pic.Image == null) return;
    if (pic.Width >= MAXZOOM * pic.Image.Width ||
        pic.Height >= MAXZOOM * pic.Image.Height)
    {
        return;
    }
    pic.Width = (int)(pic.Width + pic.Image.Width / MAXZOOM);
    pic.Height = (int)(pic.Height + pic.Image.Height / MAXZOOM);
    pic.SizeMode = PictureBoxSizeMode.StretchImage;
    dopasuj();
}


public void ZoomOut()
{
    if (pic.Image == null) return;
    if (pic.Width =< pic.Image.Width / MAXZOOM ||
        pic.Height =< pic.Image.Height / MAXZOOM)
    {
        return;
    }
    pic.Width = (int)(pic.Width - pic.Image.Width / MAXZOOM);
    pic.Height = (int)(pic.Height - pic.Image.Height / MAXZOOM);
    pic.SizeMode = PictureBoxSizeMode.StretchImage;
    dopasuj();
}

Funkcje działają analogicznie, więc omówię tylko ZoomIn Na początku sprawdzamy czy jakiś obrazek jest wyświetlany, a następnie czy któryś z rozmiarów PictureBoxa nie przekroczył odpowiedniego rozmiaru obrazka pomnożonego przez MAXZOOM (odpowiada to maksymalnemu powiększeniu), jeśli tak - funkcja kończy działanie. W przeciwnym wypadku wymiary PictureBoxa są powiększane o 1/5 w stosunku do oryginału. Następnie sposób wyświetlania ustalany jest na "rozciągnij", co wywołuje efekt zooma. Na końcu przy pomocy funkcji dopasuj wyświetlamy obrazek w odpowiednim miejscu, czyli na środku lub w lewym górnym rogu.

Pozostało nam jeszcze do oprogramowania jedno zdarzenie. Będzie ono kontrolować położenie obrazka podczas zmieniania rozmiaru kontrolki. Jego jedynym zadaniem będzie wywoływanie funkcji dopasuj. Tak więc tworzymy dla naszej klasy zdarzenie Resize. Robimy to oczywiście w graficznym edytorze. Wybieramy naszą klasę przez kliknięcie na szarym miejscu, a następnie w oknie właściwości klikamy żółty piorunek i tam znajdujemy Resize i klikamy 2 razy. Wewnątrz funkcji wpisujemy:

private void MyPictureBox_Resize(object sender, EventArgs e)
{
    dopasuj();
}

Tak oto stworzyliśmy własną kontrolkę, którą możemy teraz stosować. Przechodzimy do pliku z formą i zmieniamy właściwość Text na Zdjęcia. Po zbudowaniu projektu (klawisz F6) w toolboxie pojawi się nasza kontrolka.

Wybieramy ją i wstawiamy do formy. Nazywamy ją obrazek. .Następnie wybieramy kontrolkę MenuStrip i dodajemy ją do projektu. Należy zwrócić uwagę, aby dodać menu do formy, a nie do obrazka. Najlepiej przeciągnąć MenuStrip na górny pasek formy. W miejscu Type Here wpisujemy Plik, pod spodem Otwórz. Następnie obok Plik wpisujemy Opcje, a niżej Zoom In i Zoom Out.

Wybieramy teraz opcję Otwórz i klikamy na niej 2 razy, dzięki czemu zostanie utworzone zdarzenie Click. We wnętrzu funkcji wpisujemy:

private void otwórzToolStripMenuItem_Click(object sender, EventArgs e)
{
    OpenFileDialog dialog = new OpenFileDialog();
    dialog.ShowDialog();
    if (dialog.FileName != "")
        obrazek.LoadFromFile(dialog.FileName);
}

Zdarzenie to wykorzystuje OpenFileDialog do pobrania nazwy pliku i jeśli jakiś plik został wybrany to zostaje on otworzony. OpenFileDialog omawiałem już kilkukrotnie, więc nie będę zagłębiał się w szczegóły.

Pozostały nam jeszcze opcje Zoom In i Zoom Out. Tworzymy zdarzenia identycznie jak dla Otwórz. Wewnątrz wpisujemy tylko ZoomiIn() lub ZoomOut() - odpowiednio dla odpowiednich opcji menu.

Na końcu dorzucimy obsługę kółka myszki, za pomocą którego będziemy zmieniać powiększenie obrazka. Odpowiedzialne jest za to zdarzenia MouseWheel. Niestety nie ma go na liście zdarzeń w edytorze graficznym, więc dodamy je ręcznie. Zrobimy to w konstruktorze formy. Po funkcji InitializeComponent wpisujemy:

this.MouseWheel+=

Następnie naciskamy 2 razy tabulator, spowoduje to automatyczne wygenerowanie odpowiedniej funkcji. W jej wnętrzu wpisujemy:

if (e.Delta == 120)
    obrazek.ZoomIn();
else if (e.Delta == -120)
    obrazek.ZoomOut();

We właściwości e.Delta ukryta jest informacja o tym czy kółko zostało przesunięte. Jeśli wartość ta wynosi 120, to kółko przeskoczyło jeden "ząbek" do przodu, jeśli -120, to do tyłu. W zależności od tego czy kółko poszło w przód czy w tył, przybliżamy lub oddalamy obraz.

Tak oto ukończyliśmy kolejny program. Możemy go śmiało używać do oglądania zdjęć z wakacji z aparatu cyfrowego lub do różnych obrazków z Internetu.