A jedeme dál ...
Človíčkův Weblog aneb Michal Horák bloguje

Programování


Histogram obrázku, C# .NET

 | 3.11.2007

Naposledy jsme zvětšovali a zmenšovali obrázek, nyní si spočítáme jeho histogram. Obrázek máme uložený v dvojrozměrném poli double[,] BitmapArray, zde je uložena jeho černobílá varianta, aby se nám vše lépe počítalo. Histogram spočítáme následujícím způsobem:

        private int[] SpocitejHistogram()
        {
            int vyska = this.BitmapArray.GetLength(1);
            int sirka = this.BitmapArray.GetLength(0);
            int[] histogram = new int[256];
            int N = sirka * vyska;
            for (int y = 0; y < vyska; y++)
            {
                for (int x = 0; x < sirka; x++)
                {
                    histogram[(int)this.BitmapArray[x, y]] = histogram[(int)this.BitmapArray[x, y]] + 1;
                }
            }

            return histogram;

        }

Tento histogram můžeme následně uložit jako bitmapu:

        private Bitmap VykresliHistogram(double[] histogram) {
            
            double max = 0;
            Point[] body=new Point[256];
            Bitmap bitmap = new Bitmap(256, 100);
            Graphics g = Graphics.FromImage(bitmap);
            g.FillRectangle(Brushes.White, 0, 0, 256, 100);
            Pen pen = new Pen(Color.Black, 1);
            for (int i = 0; i < histogram.Length; i++) {
                if (histogram[i] > max) {
                    max = histogram[i];
                }
            }
            for (int j = 0; j < histogram.Length; j++)
            {
                g.DrawLine(pen, new Point(j, 100), new Point(j, (100-(int)(((double)histogram[j]/(double)max)*100))));
            }

            
            g.DrawLines(pen, body);
            g.Dispose();
            return bitmap;

        }

Kterou lze následně vykreslit.

3.11.2007 15:22 | Programování | Komentáře (0) | Trvalý odkaz | 7875x | Linkuj.cz

Zvětšování a zmenšování obrázků

 | 6.10.2007

Jestlipak víte jak funguje zvětšování a zmenšování obrázků na počítači? Nevíte? Tak čtěte dál …

Body

Hlavním problémem při zmenšování či zvětšování obrázku je, že potřebujete vykreslit některé body, které neznáte a tak si je musíte nějak odvodit. Existuje několik algoritmů a já se pokusím dva popsat.

Metoda nejbližšího souseda

Nejjednodušší algoritmus, který asi po nějaké době napadne každého je metoda nejbližšího souseda. Nejdříve si vytvoříme nový obrázek, tak že přepočítáme šířku a výšku obrázku. Pak přes tuto šířku a výšku procházíme body a těm musíme přiřadit barvu. Ale jak vzít správnou barvu? Přepočítáme si souřadnice na starý obrázek, tam nám vyjde nějaké číslo, které není celým číslem. To je problém, protože souřadnice jsou určeny celými čísly 0,…,n. Proto si vezmeme nejbližšího souseda a do obrázku na hledanou pozici vložíme jeho barvu.

Bilineární interpolace

Když budeme mít stejný případ jako v předchozím algoritmu, pak u bilineární interpolace se barva bodu na hledané pozici určí z barev sousedních bodů bodu, který máme na starém obrázku. Tato barva se vypočítá pomocí vzorce:

Bilineární interpolace

Kde barva je určena v RGB a musí se spočítat každá šást barvy zvlášť.

Zdrojový kód

Tento zdrojový kód jsem dělal na cvičení ve škole, takže nečekejte žádné zázraky. Je velmi pomalý, ale důležité je pochopení problému a funkčnost.

        private Bitmap NejblizsiSousedBitmapArray(int percent) {
            int vyska = (int)(((double)this.BitmapArray.GetLength(1)/100)*percent);
            int sirka = (int)(((double)this.BitmapArray.GetLength(0) / 100) * percent);
            richTextBox1.Text += "stara sirka: "+BitmapArray.GetLength(1)+"\n";
            richTextBox1.Text += "stara vyska: "+BitmapArray.GetLength(0) + "\n";
            Bitmap bitmap = new Bitmap(sirka, vyska);
            int xx;
            int yy;

            for (int y = 0; y < vyska; y++)
            {
                for (int x = 0; x < sirka; x++)
                {
                    double a = (x * 100) / percent;
                    double b = (y * 100) / percent;
                    xx = (int)Math.Truncate(a);
                    yy = (int)Math.Truncate(b);
                    bitmap.SetPixel(x, y, this.BitmapArray[xx,yy]);
                }
            }
        
            return bitmap;

        }


        private Bitmap BilinearniBitmapArray(int percent)
        {
            int vyska = (int)(((double)this.BitmapArray.GetLength(1) / 100) * percent);
            int sirka = (int)(((double)this.BitmapArray.GetLength(0) / 100) * percent);
            Bitmap bitmap = new Bitmap(sirka, vyska);
            int xx;
            int yy;
            double lx;
            double ly;
            byte red;
            byte green;
            byte blue;

            for (int y = 0; y < vyska; y++)
            {
                for (int x = 0; x < sirka; x++)
                {
                    double a = (x * 100) / percent;
                    double b = (y * 100) / percent;
                    xx = (int)Math.Truncate(a);
                    yy = (int)Math.Truncate(b);
                    lx = ((x * 100) / percent) - xx;
                    ly = ((y * 100) / percent) - yy;
                    
                    try {
                        red = (byte)((this.BitmapArray[xx + 1, yy].R - this.BitmapArray[xx, yy].R) * lx + (this.BitmapArray[xx, yy + 1].R - this.BitmapArray[xx, yy].R) * ly + (this.BitmapArray[xx + 1, yy + 1].R - this.BitmapArray[xx + 1, yy].R - this.BitmapArray[xx, yy + 1].R - this.BitmapArray[xx, yy].R) * lx * ly + this.BitmapArray[xx, yy].R);
                        green = (byte)((this.BitmapArray[xx + 1, yy].G - this.BitmapArray[xx, yy].G) * lx + (this.BitmapArray[xx, yy + 1].G - this.BitmapArray[xx, yy].G) * ly + (this.BitmapArray[xx + 1, yy + 1].G - this.BitmapArray[xx + 1, yy].G - this.BitmapArray[xx, yy + 1].G - this.BitmapArray[xx, yy].G) * lx * ly + this.BitmapArray[xx, yy].G);
                        blue = (byte)((this.BitmapArray[xx + 1, yy].B - this.BitmapArray[xx, yy].B) * lx + (this.BitmapArray[xx, yy + 1].B - this.BitmapArray[xx, yy].B) * ly + (this.BitmapArray[xx + 1, yy + 1].B - this.BitmapArray[xx + 1, yy].B - this.BitmapArray[xx, yy + 1].B - this.BitmapArray[xx, yy].B) * lx * ly + this.BitmapArray[xx, yy].B);
                        bitmap.SetPixel(x, y, Color.FromArgb(red, green, blue));
                    }
                    catch {
                        
                    }
                    
                }
            }
            return bitmap;

        }

Závěrem

Pro ještě kvalitnější změnu velikosti se používá bikubická interpolace, kterou jsem ještě nedělal, ale pokud budu mít čas, tak bych ji rád naprogramoval. Když se to povede, výsledek přidám sem.

6.10.2007 21:04 | Programování | Komentáře (0) | Trvalý odkaz | 6480x | Linkuj.cz

Příklad ze softwarové zkoušky

 | 2.7.2007

Na softwarovou zkoušku jsem si vybral příklad, který byl asi nejlehčí, v zadání bylo vytvořit program pro formátování textu v souboru. Program načte soubor, kde mohou být před odstavcem nastaveny parametry odstavce, kterými jsou

Program jsem psal jako konzolovou aplikaci, kterou si můžete stáhnout včetně zdrojového kódu formattext.zip. K dispozici je i testovací soubor: text.txt. Kód asi nebude nejlepší, ale hlavní je, že to funguje správně a dostal jsem za to jedničku ;o)

2.7.2007 13:55 | Programování | Komentáře (0) | Trvalý odkaz | 5336x | Linkuj.cz

Druhý graf z bakalářské práce

 | 28.2.2007

Tak jsem zase trošku pokročil a máme tu další graf z mé bakalářské práce. Tentokráte již trošku barevnější a ještě vám k tomu ukážu i zdrojový kód, pomocí kterého se zavolá onen Serverový ovládací prvek, který graf generuje. U tohoto grafu jsou ještě zobrazeny inflexní body a je zde pouze jeden graf, ale určitě je vidět, že grafů lze do obrázku přidat více.

Druhý graf <cc1:WebGraphs ID="WebCustomControl1" Text="Text" runat="server" Height="300px" Width="500px" Padding="25" Theme="default">
     <Graphs>
         <cc1:Graph color="DarkGreen" from_x="-1" from_y="-1.2" function="cos(x)" to_x="6" to_y="1.2" size="1" inflex="true" />
     </Graphs>
</cc1:WebGraphs>

Ještě pořád je na čem pracovat, hlavně je potřeba optimalizovat zobrazování inflexních bodů a extrémů a snížit dobu generování grafu a zavést podporu pro skiny a datové vazby. Však vám zase příště něco ukážu ;o)

28.2.2007 18:02 | Programování | Komentáře (1) | Trvalý odkaz | 8240x | Linkuj.cz

První graf z bakalářské práce

 | 9.2.2007

Moje bakalářská práce už začíná docela dobře zobrazovat grafy a tak bych vám chtěl ukázat jeden z nich. Samozřejmě, že to ještě není konečná podoba, zatím jde jen o to, aby to ukázalo správný graf a ne o to jaké má barvičky a co je okolo.

9.2.2007 11:22 | Programování | Komentáře (3) | Trvalý odkaz | 6876x | Linkuj.cz

Microsoft Expression Web Designer Beta 1

 | 21.11.2006

Dnes jsem si stáhl a nainstaloval nový wysiwyg editor pro tvorbu webových stránek od Microsoftu Expression Web Designer ve verzi Beta 1.

Uživatelské prostředí je velmi příjemné, ostatně jako u všech posledních programů od Microsoftu, po prvním spuštění se nám nabízí pět základních panelů: Seznam souborů a adresářů (Folder list), vlastnosti css (CSS Properties), Okno designeru, Toolbox a Aplikace či správa stylů (Apply Styles a Manage styles). V okně designeru si můžete vybrat, jestli budete používat wysiwyg nebo budete kód psát ručně či obojí.

Microsoft Expression Web Designer Beta 1

Microsoft Expression Web Designer je vlastně takovým nástupcem nenáviděného i milovaného editoru Front Page, jde však o dost dál, dynamické stránky můžete psát rovnou v ASP.NET 2.0 a vybrat si můžete jestli budete psát v jazyku C#, Visual J# či Visual Basicu, máte k dispozici všechny ASP.NET ovládací prvky, dobře použitelný editor css a hlavně výsledný kód stránky vypadá docela pěkně.

Tohle všechno jsem napsal již po hodině hraní si s tímto programem, který si své uživatele určitě najde, ještě si jej pár dní nechám nainstalovaný a zkusím v něm udělat něco kloudného, ale Visual Studio 2005 mi nenahradí.

21.11.2006 12:12 | Programování | Komentáře (10) | Trvalý odkaz | 10524x | Linkuj.cz

Kreslení v ASP.NET pomocí knihovny GDI

 | 9.11.2006

Posledních pár dní jsem studoval, jak kreslit obrázek v ASP.NET a ono to není vůbec těžké. Nejdříve si musíte založit nový projekt ve Visual Studiu nebo WebDeveloperu, kde si vyberete položku ASP.NET Web Site. Ještě než cokoliv napíšete přidejte do projektu nový WebForm s kódem v odděleném souboru, který můžete nazvat například kruhy. Otevřete si soubor kruhy.aspx.cs připište do použitých jmenných prostorů následující:

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

Nyní se podívejte o kousek níže, kde je metoda Page_Load(), do které napíšeme náš obrázek. Začneme tím, že vytvoříme nový obrázek a také objekt pro kreslení, kterému nastavíme aby při kreslení používal AntiAliasing a rovnou si vykreslíme i nějaké pozadí:

Bitmap obrazek = new Bitmap(500, 400);
Graphics g = Graphics.FromImage(obrazek);
g.SmoothingMode = SmoothingMode.AntiAlias; g.FillRectangle(Brushes.DarkOrange, 0, 0, 500, 400);

Nyní si vytvoříme pero, kterým budeme kreslit:

Pen pero = new Pen(Color.White, 2);

Když už máme čím kreslit, nakreslíme si pár kruhů.

g.DrawEllipse(pero, 200, 150, 100, 100);
g.DrawEllipse(pero, 250, 100, 100, 100);
g.DrawEllipse(pero, 250, 200, 100, 100);
g.DrawEllipse(pero, 150, 200, 100, 100);
g.DrawEllipse(pero, 150, 100, 100, 100);
g.DrawEllipse(pero, 270, 150, 100, 100);
g.DrawEllipse(pero, 130, 150, 100, 100);
g.DrawEllipse(pero, 200, 80, 100, 100);
g.DrawEllipse(pero, 200, 220, 100, 100);

Samozřejmě můžete vykreslovat i jiné geometrické útvary, ty si můžete najít ve vytvořeném objektu g. No a aby jsme z toho něco měli můžeme si přidat i popisek obrázku:

g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
g.DrawString("Kreslení v ASP.NET 2.0 pomocí knihovny GDI", new Font("Trebuchet MS", 14), Brushes.White, new Point(10, 10));

Teď obrázek uložíme a použijeme:

obrazek.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
g.Dispose();
obrazek.Dispose()

Nakonec přejdeme k souboru Default.aspx, kam přidáme ovládací prvek image, kterému nastavíme vlastnost ImageUrl na kruhy.aspx. Měl by se vám zobrazit následující obrázek.

Kreslení v ASP.NET pomocí knihovny GDI

9.11.2006 14:09 | Programování | Komentáře (0) | Trvalý odkaz | 7308x | Linkuj.cz

ASP.NET AJAX

 | 7.11.2006

Microsoft uvolnil beta verzi frameworku ASP.NET AJAX pro snadné vytváření interaktivních webových stránek pod ASP.NET. Všechny potřebné informace se o frameworku dozvíte na webu http://ajax.asp.net/.

Jak nám ukazuje zejména Google, ale i například český Seznam, Ajaxové aplikace jsou opravdu úžasně interaktivní a nejeden uživatel to dokáže ocenit. Pokud ještě nevíte co to ajax je, doporučuji si přečíst článek na AJAX na české wikipedii.

Citace: AJAX (Asynchronous JavaScript and XML) je obecné označení pro technologie vývoje interaktivních webových aplikací, které mění obsah svých stránek bez nutnosti jejich znovunačítání. Na rozdíl od klasických webových aplikací poskytují uživatelsky příjemnější prostředí, ale vyžadují použití moderních webových prohlížečů.

7.11.2006 18:33 | Programování | Komentáře (0) | Trvalý odkaz | 6921x | Linkuj.cz

Náhledy obrázků v PHP

 | 2.11.2006

Určitě jste už někde na internetu potkali dynamické galerie, kde jste nahráli obrázek a hned jste mohli vidět jeho náhled. Díky PHP a knihovně GD jsou takovéto náhledy docela jednoduchou záležitostí.

Nejdříve vrátíme hlavičku obrázku, aby prohlížeč vrátil soubor jako obrázek, v našem případě vrátíme obrázek jako JPEG a stejně tak tento skript bere jen souboru ve formátu JPEG.

Je dobré ošetřit stav, kdy obrázek, ze kterého chceme udělat náhled neexistuje. Pokud neexistuje vypíšeme tuto skutečnost na náhled. Pokud obrázek existuje, vytvoříme z něj funkcí ImageCreateFromJPEG nový obrázek, který následně vložíme do náhledu a zmenšíme (ImageCopyResized) do námi chtěných rozměrů.

Zdrojový kód

<?php
Header
("Content-type: Image/jpeg");

$img="obrazek.jpg";

$width 130;
$height 96;

if (!
file_exists($img)){
    
$Im1 ImageCreate($width,$height);
    
$bgc imagecolorallocate ($Im1255255255);
    
$tc  imagecolorallocate ($Im1000);
    
imagefilledrectangle ($Im10015030$bgc);
    
imagestring ($Im1155"Obrázek není"$tc);
    
imagestring ($Im11515"k dispozici"$tc);
    
imageline ($Im10$height/2$width$height/2$tc);
}else{
    
$Im2 ImageCreateFromJPEG("data/images/$img");

    if(
ImageSX($Im2)>ImageSY($Im2))
    {
        
$pomer=ImageSY($Im2)/ImageSX($Im2);
        
$sirka=$width;
        
$vyska=$width*$pomer;
        
$posun_dolu=($height-$vyska)/2;
        
$posun_doprava 0;
    }else
    {
        
$pomer=ImageSX($Im2)/ImageSY($Im2);
        
$sirka=$height*$pomer;
        
$vyska=$height;
        
$posun_dolu0;
        
$posun_doprava = ($width-$sirka)/2;
    }
    
$Im1 ImageCreateTrueColor($sirka,$vyska);
    
    
imagefilledrectangle ($Im100$width$height$White);
    
ImageCopyResized($Im1,$Im2,0,0,0,0,$sirka$vyska,ImageSX($Im2),ImageSY($Im2));
}

ImageJpeg($Im1);

Destroy($Im1);
Destroy($Im2);
?>

2.11.2006 09:50 | Programování | Komentáře (4) | Trvalý odkaz | 8167x | Linkuj.cz

Balíček na fotoblogu

 | 20.10.2006

Včera jsem zprovoznil jednu novinku na fotoblogu a tou je možnost si nechat vybrané fotografie zabalit do zip archivu a následně stáhnout. Vše můžete vyzkoušet, ale má to jeden háček, jakmile velikost archivu překoná určitou velikost, tak PHP nahlásí chybu:

Fatal error: Allowed memory size of 6291456 bytes exhausted (tried to allocate 43361 bytes) in /DISK2/WWW/clovicek.net/fotoblog/zip.lib.php on line 130

Nevíte náhodou někdo, jak takovouto nepříjemnost obejít? Napadlo mě pouze ukládat soubor dočasně na server a pak jej mazat, ale to může mít nechtěné následky.

20.10.2006 15:27 | Programování | Komentáře (1) | Trvalý odkaz | 5818x | Linkuj.cz

Předchozí příspěvky | 1 | 2 | 3 | Další příspěvky

Tipy na přečtení

Kategorie

Vyhledávání

Odkazy

Fotoblog

Poslední fotgrafie z fotoblogu

Nejčtenější příspěvky za poslední týden

Poslední příspěvky

"A jedeme dál ..." Človíčkův Weblog aneb Michal Horák bloguje. (c) Michal Horák (Človíček webdesign) 2006