Mehr von Jürgen Gutsch

Mehr von Jürgen Gutsch

Empfehlungen von Jürgen Gutsch

Blog-Empfehlungen von Jürgen Gutsch

Willkommen bei ASP.NET Zone. Anmelden | Registrieren | Hilfe

Jürgen Gutsch

ASP.NET und mehr...

News

Eine einfache Bildergalerie mit ASP.NET

Für ein kleineres Projekt benötigte ich eine einfache Bildergalerie die ich hiermit kurz vorstellen möchte

Folgende Techniken werden genutzt:

Die Bilder sollen aus einem Verzeichnis innerhalb des Webs ausgelesen und dargestellt werden. Wie die Bilder dorthin gelangen, ist erst mal nicht wichtig. Hierfür habe lese ich mit Hilfe der DirectoryInfo die enthaltenen Dateien aus, schreibe die Eigenschaften der einzelnen FileInfos in eine eigene Hilfsklasse und füge diese Klassen einer generischen Liste hinzu:

private IList<ImageFile> getData()
{
  DirectoryInfo di = new DirectoryInfo(   
      Server.MapPath("~/Images/Gallery/"));
  IList<ImageFile> files = new List<ImageFile>();
  foreach (FileInfo file in di.GetFiles())
    files.Add(new ImageFile()
      {
        FileName = file.Name,
        FullName = file.FullName,
        FileSize = file.Length,
        CreateDate = file.CreationTime,
        WriteTime = file.LastWriteTime,
        AccessTime = file.LastAccessTime
    });
  return files;
}

Die Hilfsklasse sieht so aus:

public class ImageFile
{
    public string FileName { get; set; }
    public string FullName { get; set; }
    public long FileSize { get; set; }
    public DateTime CreateDate { get; set; }
    public DateTime WriteTime { get; set; }
    public DateTime AccessTime { get; set; }
    public string GetImageLink(int width, int height)
    {
        string link = "~/ShowImage.ashx?filename=" +
            this.FileName;
        if (width > 0)
            link += "&width=" + width.ToString();
        if (height > 0)
            link += "&height=" + height.ToString();
        return link;
    }
}

Die kleine Methode GetImageLink benötige ich nachher im ListView. Sie setzt mir die URL zum generischen Handler mit allen nötigen Parametern zusammen.

Das binden der Liste an das ListView findet im PreRender Event Handler der ListView statt, denn ein Binding im Page_Load führt dazu, das die gewählte Seite erst nach dem zweiten PostBack angezeigt wird:

protected void GalleryListViewPager_PreRender( object sender, EventArgs e)
{
  this.GalleryListView.DataSource = getData();
  this.GalleryListView.DataBind();
}

Für die ListView benötige ich ein ItemTemplate und ein LayoutTamplate.

<asp:ListView ID="GalleryListView" runat="server">
    <LayoutTemplate>
    </LayoutTemplate>
    <ItemTemplate>
    </ItemTemplate>
</asp:ListView>

Das LayoutTemplate enthält die Definition des Containers welches anschließend die Items enthalten soll. Es könnte also die Definition eines TABLE Controls enthalten, oder in meinem Fall eine ungeordnete Liste mit der CSS Klasse "imagelist":

<ul class="imagelist">
    <asp:PlaceHolder ID="itemPlaceholder" runat="server" />
</ul>

Das ListView platziert den Inhalt des ItemTemplates in den angegebenen PlaceHolder hinein. Die ID des Placeholder muss "itemPlaceholder" lauten.

Der Inhalt des ItemTemplates sieht wie folgt aus:

<li>
    <asp:HyperLink ID="link" runat="server" NavigateUrl='<%# (Container.DataItem as
        GO.WebGallery.ImageFile).GetImageLink(600, 0) %>'
rel="lightbox[gallery]"
        ToolTip='<%# (Container.DataItem as GO.WebGallery.ImageFile).FileName %>'>
        <asp:Image ID="image" runat="server" Width="80px" Height="80px"
            BorderWidth="1px" ImageUrl='<%# (Container.DataItem as 
            GO.WebGallery.ImageFile).GetImageLink(80, 80) %>'
AlternateText="" />
    </asp:HyperLink>
</li>

Wieso eine ungeordnete Liste? Weil eine Bildergalerie nichts anderes ist als eine Liste mit Bildern...

Beim DataBinding mit Objekten liegt aus meiner Sicht ein weiterer klarer Vorteil darin, dass ich hier direkt mit den Objekten arbeiten kann. "Container.DataItem" ist Praktisch eines meiner gebundenen Objekte. Ein Cast ("Container.DataItem as GO.WebGallery.ImageFile") und ich kann bequem auf die Eigenschaften des Objekts zugreifen.

Das Paging übernimmt hier das DataPager Control, welches ich unterhalb der ListView Platziert habe

<asp:DataPager ID="GalleryListViewPager" runat="server"
        PagedControlID="GalleryListView" PageSize="12"
        OnPreRender="GalleryListViewPager_PreRender">
    <Fields>
        <asp:NextPreviousPagerField FirstPageText="&lt;&lt;"
                ShowFirstPageButton="True" ShowNextPageButton="False"
                PreviousPageText="&lt;" />
        <asp:NumericPagerField />
        <asp:NextPreviousPagerField LastPageText="&gt;&gt;"
                ShowLastPageButton="True" ShowPreviousPageButton="False"
                NextPageText="&gt;" />
    </Fields>
</asp:DataPager>

Die letzte Komponente die ich hier kurz beschreiben möchte, ist der generische HttpHandler. Aufgerufen mit der URL ("~/ShowImage.ashx?filename=100_2116.JPG&width=80&height=80") liefert er das entsprechende Bild in der angegebenen Größe.

Zuerst wird geprüft, ob es von dem angegebenen Bild bereits ein generiertes Thumbnail gibt, wenn nicht wird das Bild in ein Bitmap Objekt geladen und bearbeitet. Mit Hilfe einiger Hilfsmethoden aus dem sharpcms (im Projekt in der Klasse "Tools") werden die Bilder verkleinert und geschärft um anschließend im HttpHandler im Ordner "Thumbs" abgelegt zu werden.

Die Ausgabe des Bildes an den ResponseStream erfolgt mit folgenden Zeilen:

context.Response.ContentType = "image/jpeg";
if (System.IO.File.Exists(thumbPath))
  context.Response.TransmitFile(thumbPath);
else
  context.Response.TransmitFile(filePath);

Das Projekt kann hier heruntergeladen werden:
WebGallery.zip (ca. 1MB)

Posted: Mittwoch, 23. April 2008 12:11 von Jürgen Gutsch
Abgelegt unter: , , , ,

Kommentare

Peter Bucher sagte:

Sieht cool aus. Danke für den Beitrag Jürgen :-)

# April 23, 2008 14:09

luckyman sagte:

Sieht wirklich gut aus, danke. Mal eine Frage am Rande: Wie erzeuge ich diese Codepassagen im Textteil, die so aussehen wie im Visual Studio ?

# April 23, 2008 17:19

Jürgen Gutsch sagte:

danke :-)

@luckyman, such mal nach "Code Format". Dazu gibt sicher einige gute Lösungen.

# April 23, 2008 18:28

Andreas_Maier sagte:

Echt super! Sieht klasse aus!!

# April 23, 2008 23:26

dstem sagte:

Wirklich eine super Bildergallerie! Ich habe mir das Projekt heruntergeladen und versuche das Ganze jetzt etwas zu modifizieren/erweitern. Erster Schritt - per Menü soll wählbar sein welcher Ordner ausgelesen wird. Leider gibt es ein Problem welches mir gerade wirklich Kopfschmerzen bereitet. :/

Error 1 Could not create type 'GO.WebGallery.ShowImage'. C:\Documents and Settings\Administrator\Desktop\WebSite\ShowImage.ashx 1

Ich komm nicht drauf was schief läuft. Besonders weil ich bisher ja nicht wirklich etwas verändert habe.

Bin für jeden Tipp dankbar!

# Mai 3, 2008 15:37

dstem sagte:

Problem gelöst! :)

Habe die ShowImage.ashx.cs in den App_Code Ordner verschoben - im CodeBehind den Pfad geändert und plötzlich hat es funktioniert. Warum? :)

# Mai 3, 2008 15:54

Jürgen Gutsch sagte:

Hallo David,

wahrscheinlich haben einfach die Pfade nicht mehr gestimmt.

# Mai 5, 2008 17:44

strahler70 sagte:

Hallo,

funktioniert die Bildgallerie auch mit Tif Dateien?

Wäre über eine Antwort dankbar.

# Mai 6, 2008 14:21

Jürgen Gutsch sagte:

Hallo strahler70,

das hab ich nicht ausprobiert. Wenn .NET deine TIF Dateien lesen kann, dann ja.

Ansonsten musst du die entsprechende funktionalität noch einbauen. ;-)

# Mai 6, 2008 14:45

Peter Bucher sagte:

Salue Jürgen

> Ansonsten musst du die entsprechende funktionalität noch einbauen. ;-)

Was bestimmt gaaaaanz einfach ist :)

# Juli 8, 2008 01:20

frosenw23 sagte:

Hallo Jürgen,

hab mal eine grundsätzliche Frage was die Ladezeit der Thumbs angeht. So wie ich das verstanden habe, werden aus den original Dateien, on the fly, Thumbs generiert. Wie schauts den da mit der Dateigrösse aus?

Wenn ich jetzt z. B. 20 Bilder mit 120KB pro Bild habe, wird dann auch beim generieren 120KB für ein Thumb geladen?

# September 15, 2009 09:20

Jürgen Gutsch sagte:

Hallo Frank,

am Browser kommt immer nur das generierte Thumbnail an, auch beim ersten laden. Also wenn das Original 120KB hat und das Thumbnail 30KB, kommen beim Browser auch nur 30KB an.

# September 15, 2009 20:35
Anonyme Kommentare sind nicht zugelassen