Stránkování obrázku v ASP.NET

C# .NET ASP.NET Web Forms Stránkování obrázku v ASP.NET

Tak přátelé jsem opět zde :-), dneska si uděláme malou blbůstku. Vytvoříme webovou stránku, ktera bude stránkovat obrázek. Stránkování znamená, že máme větší množství dat (třebas články, všemožné seznamy atp. ale i obrázek) a tyto nemůžeme poslat celé do stránky, protože by to prohlížeč nebo počítač nezvládl přechroustat. Budeme mít tedy větší obrázek řekněme 1600x1200 pixelů, ale může být třebas i mnohem větší např 20000x20000 bodů. Do stránky ale dorazí obrázek mnohem menších rozměrů např 300x300px. Jak na to?

Ukažme si výsledek

Nejprve vyjděme z nějakého datového zdroje. Zde vyjdu z 24bitového obrázku rozměrů 1600x1200, který převedu do nepakované formy tak, že každý pixel je reprezentován třemi byty. Dostanu tak soubor velikosti 1600x1200x3 (složky{byty} red/green/blue) = dostávám soubor velikosti 5760000 B, kde celý obrázek je zaznamenán řádek po řádku. Tuto operaci mi umožní jakýkoliv kvalitní bitmapový program, nazvěme takto připravený soubor např. praha.rgb.

Nenechejme se zmást extrémní velikostí souboru, ta nám v ničem nevadí (pouze soubor zabírá velké místo na disku :-), protože přístup ke skutečnému aktuálnímu výřezu provedeme skokem v souboru na přesné místo začátku řádků. Skoky v souborech jsou od pradávna běžně používané a proto velmi rychlé. Celý program je pak sledem pár příkazů:

private void Page_Load(object sender, System.EventArgs e)
{

   // odchytime vstupni souradnice
   int X = Int32.Parse(Request.QueryString.Get("x"));
   int Y = Int32.Parse(Request.QueryString.Get("y"));

   // do hlavicky odpovedi dosadime, ze se jedna o obrazek
   Response.ContentType = "image/jpeg";

   String strBitmapFile = @"D:\Cesta\k\souboru\data\praha.rgb";

   // originalni velikosti obrazku
   int OriginalWidth = 1600;
   int OriginalHeight = 1200;

   int Width = 300;
   int Height = 300;

   // aktualni levy horni roh vyrezu
   int SeekX = X;
   int SeekY = Y;

   // dochytani souradnic mimo obrazek <0
   if (SeekX < 0) SeekX = 0;
   if (SeekY < 0) SeekY = 0;

   // totez, ale > jak rozmery obrazku
   if (SeekX > OriginalWidth - Width) SeekX = OriginalWidth - Width;
   if (SeekY > OriginalHeight - Height) SeekY = OriginalHeight - Height;

   FileStream fs =
        new FileStream(strBitmapFile, FileMode.Open, FileAccess.Read);
   byte[] bin = new byte[Width*Height*3];
   // cyklujem celou vyskou obrazku
   for (int i=0; i<Height; i++)
   {
           // skocime na pozici, kde skutecne zacina radek
           fs.Seek((OriginalWidth*3)*(SeekY+i)+SeekX*3, SeekOrigin.Begin);
           fs.Read(bin, i*Width*3, Width*3);
   }

   fs.Close();

   // Vytvor bitmapu
   System.Drawing.Bitmap Obr =
       new Bitmap(Width, Height, PixelFormat.Format24bppRgb);

   // vytvor bitmapu z dat (cyklujem celou mrizkou bodu)
   for(int i=0; i<Height; i++)
           for(int j=0; j<Width; j++)
           {
                   Obr.SetPixel(j, i, Color.FromArgb(bin[(i*Height+j)*3+0], bin[(i*Height+j)*3+1], bin[(i*Height+j)*3+2]));
           }

   // pridame blbinku / informacni textik
   Graphics objGrafika = Graphics.FromImage(Obr);
   objGrafika.DrawString("by Michael – Hepbeg Club 2004", new Font("Arial", 8), Brushes.Black, 5.0f, 5.0f, StringFormat.GenericDefault);
   Obr.Save(Response.OutputStream, ImageFormat.Jpeg);

}

Nejprve vezmeme jako vstup do stránky (z querystringu) souřadnice levého horního rohu. Do hlavičky HTTP odpovědi dáme, že výstupní stream je obrázek (Response.Con­tentType), dále deklarujem stringovou proměnnou určující umístění hlavního souboru. Deklarujeme také promenné určující velikosti zdroj. a cíl. obrázku. Následuje kontrola levého horního rohu (souřadnice, zda není mimo rozsah), zamezíme tím runtime chybu chybného skoku v souboru. Dále otevřeme soubor a deklarujeme pole bytů ve velikosti výsledného obrázku * 3 složky (red/green/blue). No a načítáme data do pole, přičemž si skáčeme vždy na pozici, kde je začátek řádku výsledného obrázku. Po načtení dat, zavřeme soubor, vytvoříme bitmapu (System.Drawin­g.Bitmap), a nakopírujeme data – pixel po pixelu do bitmapy. Přidáme informační text a výsledek naší práce uložíme, v našem případě do výstupního streamu ASPx stránky, ale můžeme i do souboru... Hlavní ovládací stránka ale bude obyčejná HTML stránka s IFRAME, kde budeme načítat obrázek. Na stránku dáme ještě 4 obrázky, pro směr posunu a jednoduchý klientský script, který bude občerstvovat IFRAME. Takto může vypadat JS:

<SCRIPT LANGUAGE="JavaScript">

        // 2004 by Michael

        var intAktX = 870;
        var intAktY = 580;
        var cstPlus = 290;              // pripocitaci / odecitaci promenna

        function fncNahoru()  { intAktY -= cstPlus; fncOdesli(); }
        function fncDolu()    { intAktY += cstPlus; fncOdesli(); }
        function fncDoleva()  { intAktX -= cstPlus; fncOdesli(); }
        function fncDoprava() { intAktX += cstPlus; fncOdesli(); }

        function fncOdesli()
        {
                var elmCurr = document.getElementById('MyIFrame');
                elmCurr.src = 'str_obr.aspx?x='+ intAktX + '&y=' + intAktY;
        }

</SCRIPT>

Nepředpokládám valné použití stránkování obrázku (hlavně kvůli velikosti zdrojového souboru :-), spíše popsaný postup lze bezproblému modifikovat a použít např. pro hromadné rozesílání novoročních pozdravů speciálně modifikované pro každého zákazníka (budou např. v databázi), může se takto vytvářet on-line výstupní grafy (tuším že některé zde použité objekty mají jíž nějaké metody na grafy např. koláčový zabudované), různé statistiky apod. ve fantazii se meze nekladou, tak vše, příště konečně začněme rozebírat 8 dam.


 

Stáhnout

Staženo 314x (160.69 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

  Aktivity (1)

Článek pro vás napsal Michael Stavěla
Avatar
Jméno: Michael Stavěla, místo nejčastějšího pobytu: Morava, vzdělání technicko-ekonomické, záliby: rekreační sport (floorball, cyklistika, plavání), programování, šifry, příroda – poznávání nových míst, hlavně ne rutina – ať se něco děje, čím víc zm...

Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!


 


Miniatura
Předchozí článek
ADO.NET a kontroly v ASP.NET
Miniatura
Všechny články v sekci
ASP.NET Web Forms

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!