V předchozím článku jsem vám ukázal jak lze ukládat obrázky do databáze MS SQL. Nyní se naučíte, jak takto uložené obrázky zobrazit ve svých stránkách.

Z předchozího článku máme uloženo v databázi několik obrázků, které si nyní zobrazíme.

Aplikace bude umět:

  • zobrazit obrázky s pevně definovanou výškou (show.aspx?id=4&height=200)
  • zobrazit obrázky s pevně definovanou šířkou (show.aspx?id=4&width=200)
  • zobrazit obrázky s pevně definovanou výškou a šířkou (show.aspx?id=4&width=200&height=200)

Poslední z výše jmenovaných možností sice v praxi moc nevyužijete, ale uvádím ji zde pro úplnost.

Je tu také ještě možnost zobrazit (show.aspx?id=4) obrázek v původní velikosti, což využijete velice často například při nějaké tvorbě fotogalerie.

Obrázky uložené v databázi mají různou velikost, ale my budeme chtít, aby se nám obrázek zobrazil přesně tak široký nebo vysoký, jak potřebujeme a jak předvádím v příkladu o kousek výše. Možná si řeknete, že by stačilo použít atributy Height a Width u tagu <img>. Pokud se však podíváte na velikost obrázků, které si zobrazíte z databáze , zjistíte, že se přenáší jen potřebný objem dat. Při použití parametru u tagu <img> by se přenášel vždy kompletní obrázek a změna velikosti by se prováděla až na straně klienta. Právě z výše uvedeného důvodu budeme měnit rozměry obrázku přímo na serveru. Pro změnu velikosti obrázků použijeme vylepšenou funkci ze článku Fotogalerie v ASP.NET snadno a rychle.

Size velikost(int sirka, int vyska,int rozmersirka, int rozmervyska)
      {
         double konstanta=0;;
      Size novavelikost;
         if(rozmersirka==0)
         {
            konstanta = Convert.ToDouble(rozmervyska) / Convert.ToDouble(vyska);
         }
            if(rozmervyska==0)
         {
            konstanta=Convert.ToDouble(rozmersirka) / Convert.ToDouble(sirka);
         }
         if (konstanta!=0)
         {
            novavelikost=new Size(Convert.ToUInt16(sirka*konstanta),Convert.ToUInt16(vyska*konstanta));
         }
         else if (rozmersirka!=0 && rozmervyska!=0)
         {
            novavelikost=new Size(rozmersirka,rozmervyska);
         }
         else
         {
            novavelikost=new Size(sirka,vyska);
         }
         return novavelikost;
      }

Jako součást URL se budou zadávat rozměry obrázku a který obrázek se má zobrazit. Vřele doporučuji převzaté parametry překonvertovat na potřebný datový typ (v tomto případě int) vyhnete se tím možnosti, že se někdo pokusí vaši aplikaci napadnout.

int width=0;
int height=0;
int id=0;
if (Request.QueryString[„width“] != null)
    id= Convert.ToInt32(Request.QueryString[„id“]);
if (Request.QueryString[„width“] != null)
   width=Convert.ToInt32(Request.QueryString[„width“]);
if (Request.QueryString[„height“] != null)
   height=Convert.ToInt32(Request.QueryString[„height“]);

Pokud se podíváte na přechozí článek, najdete v něm část kódu, kde se obrázek načítá do paměti a zjištuje se jeho velikost. Tento postup ve spojení se znalostmi získanými v článku Fotogalerie v ASP.NET snadno a rychle využijeme k vytvoření obrázku požadované velikosti.

Odlišnost od postupu v minulém článku spočívá v tom, že obrázek již není k dispozici jako proud dat od klienta, ale je uložen v databázi. Popisovat jak získat data z databáze by bylo pro vás nošením dříví do lesa a proto se omezím na popis jak získaná data zpracovat.

   // připojovací řetězec do SQL serveru
               const string sqlConnectionString=“Data Source=localhost;User ID=sa;Password=asdf;Initial Catalog=PictureToSQL;“;
               // vytvoření spojení do databáze
               SqlConnection conn=new SqlConnection(sqlConnectionString);
               conn.Open();
               SqlCommand cmd=new SqlCommand(„select picture from Pictures where id=@id“,conn);
               cmd.Parameters.Add(„@id“,id);
               SqlDataReader rdr=cmd.ExecuteReader();
               rdr.Read();
               byte[] data= (byte[])rdr[„picture“];
               rdr.Close();
               conn.Close();

Z minulého článku si možná pamatujete, že je bitová mapa obrázku uložena v položce picture. Obsah této položky si uložíme do pole, se kterým budeme dále pracovat. Údaje z databáze již nebudeme potřebovat, proto zavřeme recorset a spojeni do databáze.

               // zjištění rozměrů obrázku
               MemoryStream stream = new MemoryStream();
               stream.Write(data,0,data.Length);
               Bitmap objBitmap = new Bitmap(stream);
               Size SizePicture=objBitmap.Size;
               
               // výpočet nových rozměrů
               Size nvo;
               nvo=velikost(SizePicture.Width,SizePicture.Height,width,height);
               // vytvoření obrázku s novými rozměry
               Bitmap objBitmapResize = new Bitmap(objBitmap,nvo);
                        
               // odeslání výsledku na klienta
               objBitmapResize.Save (Response.OutputStream,ImageFormat.Jpeg);
            // uvolnění paměti
               objBitmap.Dispose();
               stream.Close();
               objBitmapResize.Dispose();

Zjistíme rozměry obrázku uloženého v databazi a na základě hodnot zadaných v URL vytvoříme nový obrázek s požadovanými rozměry. Vytvořený obrázek odešleme na klienta a uvolníme obsazenou paměť.

Poslední důležitou věcí na kterou nesmíme zapomenout je ošetření aplikace tak, aby nešla použít na jiných než našich stránkách. Návod najdete v článku Pavla Růžicky Dynamické obrázkové nadpisy v ASP.NET. V našem případě se nezobrazí vůbec nic. Nevidím důvod proč vyvíjet nějakou další činnost a zbytečně plýtvat výkonem serveru, když se někdo snaží neoprávněně použít naší aplikaci.

Pro pořádek ještě celý kód, ze kterého jsem postupně uváděl důležité fragmenty:

   private void Page_Load(object sender, System.EventArgs e)
      {
         if (Request.UrlReferrer != null)
            if (Request.UrlReferrer.Authority == Request.ServerVariables[„SERVER_NAME“])
            {// referer je v pořádku, naplnit parametry

               // Put user code to initialize the page here
               int width=0;
               int height=0;
               int id=0;
                  if (Request.QueryString[„width“] != null)
                id= Convert.ToInt32(Request.QueryString[„id“]);
               if (Request.QueryString[„width“] != null)
                  width=Convert.ToInt32(Request.QueryString[„width“]);
               if (Request.QueryString[„height“] != null)
                  height=Convert.ToInt32(Request.QueryString[„height“]);
               // připojovací řetězec do SQL serveru
               const string sqlConnectionString=“Data Source=localhost;User ID=sa;Password=asdf;Initial Catalog=PictureToSQL;“;
               // vytvoření spojení do databáze
               SqlConnection conn=new SqlConnection(sqlConnectionString);
               conn.Open();
               SqlCommand cmd=new SqlCommand(„select * from Pictures where id=@id“,conn);
               cmd.Parameters.Add(„@id“,id);
               SqlDataReader rdr=cmd.ExecuteReader();
               rdr.Read();
               byte[] data= (byte[])rdr[„picture“];
               rdr.Close();
               conn.Close();
               // zjištění rozměrů obrázku
               MemoryStream stream = new MemoryStream();
               stream.Write(data,0,data.Length);
               Bitmap objBitmap = new Bitmap(stream);
               Size SizePicture=objBitmap.Size;
               // výpočet nových rozměrů
               Size nvo;
               nvo=velikost(SizePicture.Width,SizePicture.Height,width,height);
               // vytvoření obrázku s novými rozměry
               Bitmap objBitmapResize = new Bitmap(objBitmap,nvo);
               // odeslání výsledku na klienta
               objBitmapResize.Save (Response.OutputStream,ImageFormat.Jpeg);
               
      
         
            // uvolnění paměti
               objBitmap.Dispose();
         
               stream.Close();
               objBitmapResize.Dispose();
      
            }
      }

zdrojové kódy ke stažení

Příšte celou aplikaci doplním o možnost listování obrázky a umožním jejich mazání a editaci popisu. Pokud vás napadne nějaká další funkce, neváhejte a napište ji třeba do diskuze.

Žádný příspěvek v diskuzi

Odpovědět