Jak udělat galerii fotografií včetně náhledů a informací o zdrojové fotografii? Nechcete nebo nemůžete použít databázi či XML? Chcete jenom „vysypat“ obsah foťáku na server a mít hotovo? Zkuste tedy použít ASP.NET, trochu programování a následující postup.

Možná si ještě vzpomenete na „klasické“ ASP a procházení adresářové struktury. I v ASP.NET existuje tato možnost. Oproti klasickému ASP máme i zde možnost pracovat s obrázky a nejen obrázky číst, ale i vytvářet. V dnešním praktickém článku vám ukáži malou část z možností práce se soubory a obrázky v ASP.NET.

Jak projít adresář a zpracovat soubory ?

Možná si vzpomenete na sérii článků o rozhraní pro download v ASP (Rozhraní pro download souborů pomoci ASP, Rozhraní pro download souborů pomoci ASP – statistika a Rozhraní pro download souborů pomoci ASP – třídění souborů), kde jsem použil procházení adresářů. Podobnou funkčností samozřejmě disponuje i ASP.NET. Možnosti pro práci s adresáři i soubory hledejte ve jmenném prostoru System.IO. Podrobný popis tohoto jmenného prostoru najdete v MSDN.

Z tohoto jmenného prostoru použijeme pro naše účely zejména třídu Directory a její metodu GetFiles, která umožní načíst seznam souboru v adresáři. Obecný postup přístupu k seznamu souboru pak vypadá zhruba takto:

string [] fileEntries = Directory.GetFiles(targetDirectory);
foreach(string fileName in fileEntries)
{
// kod pro zpracovani
}

Získaný seznam souborů je vlastně pole, ve kterém jsou uloženy plné cesty k souborům.


Obsah pole v debuggeru Visual Studia .NET

O souborech ale chceme vědět více než jen jméno a cestu. Proto budeme muset použít třídu FileInfo, kde již máme k dispozici kompletní balík informací o souborech.

Zájemce o podrobný popis této třídy opět odkazuji na příslušnou část MSDN.

Díky třídě FileInfo jsme sice již získali poměrně dost informací o souboru samotném, ale stále nám chybí například informace o rozměrech obrázku, počet barev či jeho rozlišení. Vezmeme si tedy na pomoc třídu Bitmap ze jmenného prostoru System.Drawing. S její pomocí získáme množství informací o vlastním obrázku. Podrobný popis této třídy najdete opět v MSDN.

Jak stanovit rozměry obrázku pro náhled?

Lze s jistotou říci, že při psaní aplikace nemáme ani ponětí o tom, jak velký bude originální obrázek. Jediná informace, kterou můžeme předem znát, je maximální rozměr náhledového obrázku. Pokud tedy budeme chtít, aby měl větší rozměr obrázku přesně tolik, kolik požadujeme, stačí použít následující funkci:

Size velikost_nahledu(int sirka, int vyska,int rozmer)
{
   double konstanta;
      if(vyska>sirka)
      {
         konstanta = Convert.ToDouble(rozmer) / Convert.ToDouble(vyska);
      }
      else
      {
         konstanta= Convert.ToDouble(rozmer) / Convert.ToDouble(sirka);
      }
   Size novavelikost= new    Size(Convert.ToUInt16(sirka*konstanta),Convert.ToUInt16(vyska*konstanta));
   return novavelikost;
}

Pokud však budete chtít, aby šířka či výška měly požadovaný rozměr, budete si muset funkci drobně upravit. Proč vlastně počítáme rozměry náhledu a nezadáme je napevno? Při pevném zadání bychom museli požadovat zdrojové obrázky v předem definovaném rozměru, jinak by docházelo při změně velikosti k deformaci obrázku. Funkce má tři parametry: výšku, šířku a požadovaný rozměr. Jako výsledek své činnosti vrací naplněnou strukturu Size. Strukturu Size najdete ve jmenném prostoru System.Drawing. Detailní popis najdete v MSDN .

Jak vytvořit náhled obrázku?

Pro tvorbu náhledu obrázku bychom mohli použít funkci GetThumbnailImage, která je obsažena přímo ve třídě Image. Nepoužijeme ji však, neboť náhled vytváří z náhledu, který do obrázku uložil například digitální fotoaparát. Pokud není tento náhled k dispozici, udělá se náhled z velké fotografie. O kvalitě „náhledu z náhledu“ není již potřeba mluvit.

K vytvoření nového obrázku použijeme metodu FromImage ze třídy Graphics a novou instanci třídy Bitmap, kde si nastavíme rozměry obrázku. Nakonec obrázek pomocí metody Save uložíme na disk a máme náhled hotov. Záměrně jsem zvolil uložení náhledu na disk proto, aby se nevytvářel pro každého návštěvníka zvlášť.

Jak na popisky fotografii ?

Pro co největší jednoduchost jsou popisky k jednotlivým fotografiím načítány z textového souboru, který se jmenuje stejně jako obrázek a má příponu txt. Pro ještě větší jednoduchost je možné tento soubor nechat vygenerovat

if (!File.Exists(Server.MapPath(path)+“/“+FI.Name+“.txt“))
{
   StreamWriter writer = new StreamWriter( Server.MapPath(path)+“/“+FI.Name+“.txt“);
   writer.Write(“ „);
   writer.Close();
}
   else
{
   StreamReader reader = new StreamReader(Server.MapPath(path)+“/“+FI.Name+“.txt“);
   Popisek = reader.ReadLine().ToString();
   reader.Close();
}

Jak získané informace zobrazit?

Pokud jste dříve používali klasické ASP, napadne vás možnost jednoduše vložit data do stránky pomocí response.write. I tento způsob je v ASP.NET možný, ale myslím si, že to není ta správná cesta. Pokusíme se tedy vydat cestou správnější, cestou DataSetu. Objekt DataSet obsažený ve jmenném prostoru System.Data sice přímo data nezobrazuje, ale slouží jako datový sklad v paměti.

V objektu DataSet mohou být uloženy tabulky s daty reprezentované objektem DataTable. Jak takovou tabulku udělat a umístit do DataSetu?

  • vytvoříme instanci objektu DataTable
  • do tabulky přidáme potřebný počet sloupců
  • vytvoříme instanci obejktu DataSet
  • do vytvořeného DataSetu vložíme referenci na vytvořenou tabulku

Potřebnou tabulku již máme nadefinovanou a můžeme ji postupně naplnit požadovanými údaji. Stačí jen vytvořit nový řádek, ten naplnit údaji a následně řádek vložit do DataSetu.

public DataSet napln_dataset(string path)
{
   DataTable dt = new DataTable(„polozka“);

   dt.Columns.Add(„jmeno_souboru“, System.Type.GetType(„System.String“));
   dt.Columns.Add(„nahled“, System.Type.GetType(„System.String“));
   dt.Columns.Add(„velikost_souboru“, System.Type.GetType(„System.Int32“));
   dt.Columns.Add(„datum_vytvoreni“, System.Type.GetType(„System.DateTime“));
   dt.Columns.Add(„vyska“, System.Type.GetType(„System.Int16“));
   dt.Columns.Add(„sirka“, System.Type.GetType(„System.Int16“));
   dt.Columns.Add(„rozliseni“, System.Type.GetType(„System.String“));
   dt.Columns.Add(„popisek“, System.Type.GetType(„System.String“));

   DataSet ds = new DataSet(„adresar“);
   ds.Tables.Add(dt);
   string Popisek=““;
   string cesta=Server.MapPath(path);
   string[] file = (Directory.GetFiles(cesta,“*.jpg“));
   foreach(string nfile in file)
   {
      FileInfo FI = new FileInfo(nfile);
      DataRow dr = dt.NewRow();
      dr[„jmeno_souboru“] = FI.Name;
      dr[„velikost_souboru“] = FI.Length;
      dr[„datum_vytvoreni“] = FI.CreationTime;

      Bitmap obr = new Bitmap(nfile);
      dr[„vyska“] = obr.Height;
      dr[„sirka“] =obr.Width;
      dr[„rozliseni“]=obr.HorizontalResolution+“x“+obr.VerticalResolution;
      if (!File.Exists(Server.MapPath(path)+“/“+FI.Name+“.txt“))
      {
         StreamWriter writer = new StreamWriter( Server.MapPath(path)+“/“+FI.Name+“.txt“);
         writer.Write(„Zde je možné doplnit popisek“);
         writer.Close();
      }
      else
      {
         StreamReader reader = new StreamReader(Server.MapPath(path)+“/“+FI.Name+“.txt“);
         Popisek = reader.ReadLine().ToString();
         reader.Close();
      }
      if (!File.Exists(Server.MapPath(path)+“/nahled/“+FI.Name))
      {
         Size nvo;
         nvo=velikost_nahledu(obr.Width,obr.Height,100);
         Bitmap picture_vystup = new Bitmap(obr,nvo);
         Graphics g = Graphics.FromImage(picture_vystup);
         g.SmoothingMode = SmoothingMode.HighQuality;
         StringFormat format = new StringFormat();
         format.Alignment = StringAlignment.Center;
         picture_vystup.Save(Server.MapPath(path)+“/nahled/“+FI.Name, ImageFormat.Jpeg);
         g.Dispose();
         picture_vystup.Dispose();
      }
      obr.Dispose();
      dr[„popisek“]=Popisek;
      dr[„nahled“] = „<a href=‘./“+path+“/“+FI.Name+“‚><Img src=‘./“+path+“/nahled/“+FI.Name+“‚ alt='“+Popisek+“‚></a>“;
      dt.Rows.Add(dr);
   }
   return (ds);
}

Nyní máme všechny údaje bez problému k dispozici a zbývá pouze nashromážděná data zobrazit. Pro toto zobrazení lze použít některý ze serverových ovládacích prvků (DataGrid, DataList či Repeater). V tomto případě použiji DataGrid a ukáži vám, jak lze právě pomocí DataGridu udělat velice jednoduše stránkování záznamů.

<%@ Page language=“c#“ Culture=“cs-CZ“ Codebehind=“default.aspx.cs“ AutoEventWireup=“false“ Inherits=“galerie.galerie“ %>
<!DOCTYPE HTML PUBLIC „-//W3C//DTD HTML 4.0 Transitional//EN“ >
<HTML>
<HEAD>
<title>defaul</title>
<meta content=“Microsoft Visual Studio 7.0″ name=“GENERATOR“>
<meta content=“C#“ name=“CODE_LANGUAGE“>
<meta content=“JavaScript“ name=“vs_defaultClientScript“>
<meta content=“http://schemas.microsoft.com/intellisense/ie5″ name=“vs_targetSchema“>
</HEAD>
<body MS_POSITIONING=“GridLayout“>
<form id=“defaul“ method=“post“ runat=“server“>
<asp:datagrid id=“DataGrid1″ style=“Z-INDEX: 101; LEFT: 9px; POSITION: absolute; TOP: 8px“ runat=“server“ BorderColor=“#CC9966″ BorderStyle=“None“ BorderWidth=“1px“ BackColor=“White“ CellPadding=“4″ AllowPaging=“True“ PageSize=“5″>
<SelectedItemStyle Font-Bold=“True“ ForeColor=“#663399″ BackColor=“#FFCC66″></SelectedItemStyle>
<ItemStyle ForeColor=“#330099″ BackColor=“White“></ItemStyle>
<HeaderStyle Font-Bold=“True“ ForeColor=“#FFFFCC“ BackColor=“#990000″></HeaderStyle>
<FooterStyle ForeColor=“#330099″ BackColor=“#FFFFCC“></FooterStyle>
<PagerStyle HorizontalAlign=“Center“ ForeColor=“#330099″ BackColor=“#FFFFCC“ Mode=“NumericPages“></PagerStyle>
</asp:datagrid></form>
</body>
</HTML>

Tím máme vše připraveno a stačí pouze „nabindovat“ data na DataGrid, což je vhodné provést ve funkci Page_Load:

private void Page_Load(object sender, System.EventArgs e)
{
   DataGrid1.DataSource=napln_dataset(„obr“);
   DataGrid1.DataBind();
}

Ve vlatnostech DataGridu jsem uvedl atributy AllowPaging=“True“ a PageSize=“5″. Atributy říkají, že je povoleno zobrazování po stránkách a na každé stránce bude maximálně pět záznamů. Tyto atributy však nezajistí načtení požadované fukne. Zajistí pouze to, že DataGrid předá uživatelské funkci číslo požadované stránky. Proto vytvoříme funkci zmena_stranky, která je návázána na událost DataGridu PageIndexChanged. Index požadované stránky je obsažen ve vlastnosti NewPageIndex.

private void zmena_stranky(object source, System.Web.UI.WebControls.DataGridPageChangedEventArgs e)
{
   DataGrid1.DataSource=napln_dataset(„obr“);
   DataGrid1.CurrentPageIndex=e.NewPageIndex;
   DataGrid1.DataBind();
}

Jak vypadá aplikace v činnosti se samozřejmě můžete podívat a případně si stáhnout zdrojové kódy.

Jak dostat obrázky na server?

V dnešním článku vůbec neřeším metody, jak dostat obrázky na server. V podstatě máte dvě možnosti:

  1. použít jakéhokoli FTP klienta, pomocí kterého obrázky na server nahrajete
  2. vytvořit si web rozhraní pro zprávu souborů a zabezpečit si je (viz série článků o zabezpečení)

O tom jak jednoduše „dostat“ soubor na server přes web rozhraní pomocí ASP.NET, si můžete přečíst v článku Upload souboru na server pomocí ASP.NET.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

1 Příspěvěk v diskuzi

  1. Po prozkoumáni příkladu jsem dospěl k názoru, že nesplňuje zadání.
    Vše funguje pokud pracujete na vývojovém webserveru. Jakmile přenesete kód na skutečný webový server, načitání lokálních souborů již neni z principu možné. Soubory z fyzické cesty lze načíst pouze na webserveru a překopírovat je opět na webserver.

Odpovědět