Stránkovanie obrázku v ASP.NET
Tak priatelia som opäť tu , Dnes si urobíme malú srandičku. Vytvoríme webovú stránku, ktora bude stránkovať obrázok. Stránkovanie znamená, že máme väčšie množstvo dát (trebárs články, všemožné zoznamy atp. Ale aj obrázok), a tieto nemôžeme poslať celé do stránky, pretože by to prehliadač alebo počítač nezvládol přechroustat. Budeme mať teda väčší obrázok povedzme 1600x1200 pixelov, ale môže byť trebárs aj oveľa väčšie napr 20000x20000 bodov. Do stránky ale dorazí obrázok oveľa menších rozmerov napr 300x300px. Ako na to?
Najprv vyjdeme z nejakého dátového zdroja. Tu vyjdem z 24bitového obrázku rozmerov 1600x1200, ktorý prevediem do nepakované formy tak, že každý pixel je reprezentovaný tromi bytmi. Dostanem tak súbor veľkosti 1600x1200x3 (zložky {byty} red / green / blue) = dostávam súbor veľkosti 5760000 B, kde celý obrázok je zaznamenaný riadok po riadku. Túto operáciu mi umožní akýkoľvek kvalitný bitmapový program, nazvime takto pripravený súbor napr. Praha.rgb.
Nenechajme sa zmiasť extrémne veľkosťou súboru, tá nám v ničom nevadí (iba súbor zaberá veľké miesto na disku , Pretože prístup k skutočnému aktuálnemu výrezu vykonáme skokom v súbore na presné miesto začiatku riadkov. Skoky v súboroch sú od pradávna bežne používané a preto veľmi rýchle. Celý program je potom sledom pár príkazov:
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); }
Najprv vezmeme ako vstup do stránky (z querystringu) súradnice ľavého horného rohu. Do hlavičky HTTP odpovede dáme, že výstupné stream je obrázok (Response.ContentType), ďalej deklarujte stringové premennú určujúcu umiestnenie hlavného súboru. Deklarujeme tiež premenné určujúce veľkosti zdroj. a cieľ. obrázku. Nasleduje kontrola ľavého horného rohu (súradnice, či nie je mimo rozsahu), zamedzíme tým runtime chybu chybného skoku v súbore. Ďalej otvoríme súbor a deklarujeme poľa bytov vo veľkosti výsledného obrázku * 3 zložky (red / green / blue). No a načítame dáta do poľa, pričom si skáčeme vždy na pozícii, kde je začiatok riadka výsledného obrázku. Po načítaní dát, zavrieme súbor, vytvoríme bitmapu (System.Drawing.Bitmap), a nakopírujeme dáta - pixel po pixeli do bitmapy. Pridáme informačný text a výsledok našej práce uložíme, v našom prípade do výstupného streamu ASPX stránky, ale môžeme aj do súboru ... Hlavné ovládacie stránka ale bude obyčajná HTML stránka s IFRAME, kde budeme načítavať obrázok. Na stránku dáme ešte 4 obrázky, pre smer posunu a jednoduchý klientsky script, ktorý bude občerstvovať IFRAME. Takto môže vyzerať 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>
Nepredpokladám valnom použitie stránkovanie obrázku (hlavne kvôli veľkosti zdrojového súboru , Skôr popísaný postup možno bezproblému modifikovať a použiť napr. Pre hromadné rozosielanie novoročných pozdravov špeciálne modifikované pre každého zákazníka (budú napr. V databáze), môže sa takto vytvárať on-line výstupné grafy (tuším že niektoré použité objekty majú ktorej nejaké metódy na grafy napr. koláčový zabudované), rôzne štatistiky a pod. vo fantázii sa medze nekladú, tak všetko, nabudúce konečne začnime rozoberať 8 dám.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 319x (160.69 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#