Jak změnit (přepsat) existující obrázek v .NET?

Pokud někteří z vás někdy potřebovali změnit nějaký původní obrázek (např. přidat vodoznak), pravděpodobně jste se setkali s problémem, jak tento původní obrázek v souborovém systému přepsat. Na jednoduchém příkladu si ukážeme jak toho za pomocí jazyka C# dosáhnout. Určeno začátečníkům.


Petr Stříbný

Autorem článku je Petr Stříbný. Programátor. Věnuje se internetovým stránkám, technologiím, jazykům C# a PHP. Při přípravě na maturitu sepsal některé maturitní otázky na web. Kromě toho si píše osobní blog.

Naše projekty

Angličtina AGJ.cz
Dějepis


Proč to nejde jednoduše?

Nejlehčí cesta opětovného uložení obrázků z paměti do souboru (tedy např. objektů typu Image) vede přes metodu Save(). Tato metoda však nemá žádný parametr, který by určil zda se obrázek přepsat má nebo ne. Proč tomu tak je? .NET totiž vyžaduje, aby při manipulaci s obrázkem byl zdrojový stream (tedy např. zdrojový obrázek ze souboru) neustále přístupný. Pro přeuložení obrázku však je potřeba soubor nejdříve smazat, čímž tento zdroj ztratíme a nemůžeme pak dále s obrázkem nijak pracovat, ani ho uložit. V .NETu je tato vlastnost označena jako by design.

Řešení

Řešení si ukážeme na ukázkovém příkladu přidání vodoznaku, kde budeme mít jednu metodu Image AddWaterMark(Image img), která má vstupní parametr i návratovou hodnotu typu Image. Předpokládejme, že budeme chtít s touto metodou pracovat tímto způsobem:

Image im;
im = Image.FromFile(@"obrazek.jpg");
im = AddWaterMark(im);
File.Delete(@"obrazek.jpg");
im.Save(@"obrazek.jpg");

Základní myšlenkou naší metody AddWaterMark je nevytváření objektu Graphics pomocí tohoto obrázku. Naproti tomu vytvoříme prázdný obrázek o stejných rozměrech (pomocí objektu Bitmap), do kterého ten původní vykreslíme metodou DrawImage.

Image AddWaterMark(Image img)
{
    Bitmap newimg = new Bitmap(img.Width, img.Height);
    Graphics gr = Graphics.FromImage(newimg);
    gr.DrawImage(img, 0, 0);

    // Ted si muzeme obrazek libovolne upravit, napr. pridat vodoznak:
    gr.DrawImage(Watermark, x, y);

    gr.Dispose();
    return (Image)newimg;
}

Princip je jednoduchý - tím, že nevytváříme objekt typu Graphics přímo ze zdrojového obrázku tato metoda nevytvoří žádnou další referenci na náš obrázek. V předchozím kódu jsme pak našemu objektu im přiřadili ten nově vzniklý, tudíž i tato původní reference končí. Na původní soubor se tak nic neodkazuje a můžeme ho proto smazat. Druhou možností by bylo zavolání metody im.Dispose(), přiřazením jiného obrázku jsme se nutnosti volání této metody vyhli.

Ještě doplním, že pokud se snažíte přepsat obrázek, který je nějak používán, dostanete velice obecnou chybu "generic error occurred in GDI+"...

Článek publikován 2007-12-01 07:40:29.


Linkovat Přidat odkaz na del.icio.us

Komentáře

Více o watermarcích v C#/ASP.NET – především návod jak vložit poloprůhledný watermark, relativně/absolutně ho umísťovat.

http://trupik­.aspweb.cz/…-aspnet.aspx

Trupik

Napsat komentář

Upozornění: komentáře jsou schvalovány!




Napište prosím, kolik je 10 bez pěti:


Náhled

Nepřehlédněte

© 2005—2007 Zápisník programátorů. Veškerá práva vyhrazena.
O zápisníku — Autoři — Archív