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?
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.ContentType), 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.Drawing.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žením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 319x (160.69 kB)
Aplikace je včetně zdrojových kódů v jazyce C#