Jak stáhnout a uložit obrázek ze zadané URL v ASP.NET
Komunitní aplikace na webu umožňují uživatelům sdílet kdeco. V tomto článku si ukážeme, jak uživateli prostřednictvím ASP.NET umožnit stažení obrázku, který už sídlí na nějaké URL, podobně jako nejmenovaná služba "obličejkniha".
Upload obrázku, který uživatel vyhledá na svém lokálním disku a vloží do políčka formuláře, je známá technika a řada dnešních aplikací ji nabízí. V článku se naučíme stáhnout data obrázku ze zadané url – a získat tak stream, se kterým potom v aplikaci můžeme naložit stejně, jakoby byl obrázek uploadován z uživatelova prohlížeče. Mám na mysli úpravy obrázku – změna velikosti, oříznutí, formátu…
Uložení obrázku na disk zde jen naznačíme, je potřeba stejně jako při běžném uploadu vyřešit možné kolize názvů souborů a případně uložení údajů o obrázku do databáze. Uvědomíme si, že pro upload se používá HttpPostedFile, kde ve vlastnosti InputStream je stream obrázku z prohlížeče klienta. Pokud vyjdeme z dobře známých aplikací, kde uživatel přes formulář uploaduje soubor ze svého prohlížeče, určitě v ní bude nějaká metoda na opracování rozměrů obrázku a jeho následné uložení na disk. Nejspíše tato metoda bude napsána tak, že umí zpracovat stream souboru, aby bylo možné vyrobit objekt Image (obrázek) a upravit jeho vlastnosti.
Taková metoda se nám bude hodit i pro ukládání obrázku staženého ze vzdáleného serveru, níže si proto probereme možný příklad takové metody Image_SaveToDisc()
.
Pohodlnosti uživatelů jistě přijde vhod i fakt, že se nemusí starat o formát zdrojového obrázku – jelikož předpokládané užiti je pro spíše menší a ilustrační fotografie, jakýkoli obrázek se nakonec uloží ve formátu JPEG.
Stažení obrázku – získání streamu souboru
Nejprve musíme ze vzdáleného serveru (stroje) stáhnout data obrázku. Použijeme několik vestavěných metod .net frameworku – pokud vše dopadne dobře, získáme data v podobě objektu Stream.
private void FetchImageFromUrl(String url,String path) { // se zadanou URL si připravíme HttpWebRequest HttpWebRequest getImageRequest = (HttpWebRequest) WebRequest.Create(new Uri(url)); // kdyby byl z našeho serveru potřeba přístup přes proxy, stačí odkomentovat následující //getImageRequest.Proxy = new WebProxy(); //getImageRequest.Proxy.Credentials = new NetworkCredential(); //getImageRequest.PreAuthenticate = true; //getImageRequest.Credentials = new System.Net.NetworkCredential(UserName,UserPassword); try { // HttpWebResponse nám vrátí stream odpovědi serveru using (System.Net.HttpWebResponse getImageResponse = (HttpWebResponse) getImageRequest.GetResponse()) { if (getImageRequest.HaveResponse && getImageResponse.ContentLength != 0) { // pokud se vůbec něco stáhlo a nemá nulovou délku, můžeme to uložit na disk Image_SaveToDisc(getImageResponse.GetResponseStream(), 300, 400, path); } else { //nepřečetlo se nebo má nulovou délku } // pěkně po sobě uklidíme getImageResponse.Close(); } } catch (System.Net.WebException netEx) { // síťová chyba } catch(Exception Ex) { // jiná chyba } }
Uložení streamu obrázku na disk
V metodě ImageSaveToDisc()
zároveň aplikujeme trošku matematiky pro úpravu rozměrů obrázku – vpodstatě musíme rozhodnout, zda je obrázek "na výšku" nebo "na šířku". Delší stranu potom nastavíme na zadanou maximální hodnotu, zbylou stranu musíme dopočítat v poměru stran původního obrázku. Samozřejmě je možné dělat i složitější úpravy – třeba výřezy z příliš širokých obrázků a podobně, příklad jsem se však snažil ponechat co nejjednoduší.
private void Image_SaveToDisc(Stream image, int maxWidth, int maxHeight, string path) { bool isLandscape = false; // ze streamu vytvoříme nový objekt obrázku using (System.Drawing.Image sourcePicture = System.Drawing.Image.FromStream(image, false, true)) { // je obrázek "naležato"? isLandscape = (sourcePicture.Width > sourcePicture.Height); // velikost "delší" strany int longerSideLength = (isLandscape) ? sourcePicture.Width : sourcePicture.Height; // pokud má obrázek některou stranu větší než maximum, musíme zmenšit if (longerSideLength > maxWidth || longerSideLength > maxHeight) { // vypočteme poměr stran decimal originalAspectRatio = ((decimal)sourcePicture.Width / (decimal)sourcePicture.Height); // připravíme novou šířku int newPictureWidth = (int)(Decimal.Round(((decimal)maxHeight * originalAspectRatio), 0)); // připravíme novou výšku int newPictureHeight = maxHeight; // pokud dopočítaná šířka překročí maximální if (newPictureWidth >= maxWidth) { // nastavíme maximální šířku newPictureWidth = maxWidth; // a dopočítáme výšku newPictureHeight = (int)(Decimal.Round(((decimal)maxWidth / originalAspectRatio), 0)); } // připravíme "prázdný" obrázek o nových rozměrech using (Bitmap resizedPicture = new Bitmap(newPictureWidth, newPictureHeight)) { // připravíme objekt Graphic nad prázdným obrázkem using (Graphics oGraphic = Graphics.FromImage(resizedPicture)) { // nastavíme vlastnosti pro úpravy obrázku oGraphic.CompositingQuality = CompositingQuality.HighQuality; oGraphic.SmoothingMode = SmoothingMode.HighQuality; oGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic; // a nakonec původní obrázek rozkreslíme do nového "prázdného" oGraphic.DrawImage(sourcePicture, 0, 0, newPictureWidth, newPictureHeight); } try { // uložíme nově upravený obrázek resizedPicture.Save(path, System.Drawing.Imaging.ImageFormat.Jpeg); } catch (Exception Ex) { //chyba při ukládání souboru; } } } else { // obrázek je menší než maximum, uložíme bez úprav try { sourcePicture.Save(path, System.Drawing.Imaging.ImageFormat.Jpeg); } catch (Exception Ex) { //chyba při ukládání souboru; } } } }
Příklad formuláře pro stažení obrázku z URL
Máme-li již v naší aplikaci formulář, který umožňuje upload souboru z formuláře, pak stačí poupravit metodu ukládání obrázku na disk tak, aby bylo možné zpracovávat stream
získaný z vlastnosti InputStream. Pro názornost alespoň jednoduchá ukázka – povšimněte si důležitý import prostorů názvů a také napevno nastavené cesty pro ukládání obrázku:
<form id="form1" runat="server"> <div> <p><asp:TextBox ID="TextBox1" runat="server"></asp:TextBox></p> <p><asp:Button ID="Button1" runat="server" Text="Uložit" onclick="Button1_Click" /></p> </div> </form>
using System; using System.Net; using System.Web.UI; using System.IO; using System.Web.UI.WebControls; using System.Drawing; using System.Drawing.Drawing2D; public partial class FetchImage : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Button1_Click(object sender, EventArgs e) { FetchImageFromUrl(TextBox1.Text, "C:\\FetchImage\\FetchImage.jpg"); } }
Skutečný formulář by měl určitě obsahovat validátor a splňovat řadu dalších požadavků, zde uvedený kód je jen příkladem řešení. Důležité je samozřejmě ošetřit chyby a výjimky a nejspíše také použít nějaké konfigurační údaje. Podstatné je také určit cestu, kam se soubor bude ukládat a také pod jakým názvem – aby se soubory nemohly navzájem přepsat.
Uvědomme si, že uživatelům dáváme k dispozici nástroj, kterým mohou porušit autorská práva – a na toto je v aplikaci upozornit. Některý obsah je dovoleno stáhnout, ale není dovoleno jej publikovat bez uvedení původního zdroje.
Příklad jednoduché stránky pro stahování obrázků si můžete stáhnout zde.
Mohlo by vás také zajímat
-
4 tipy, jak na efektivní úsporu při rozjezdu podnikání
3. ledna 2023 -
Od iPhonu po Android: Ultra HDR přináší nový standard fotografií
1. listopadu 2024 -
Proč investovat do nejvýkonnějších VPS s AMD EPYC procesory
14. června 2024 -
Znovuuvedení domény .AD
5. září 2024
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024
Jakub Vrána
Lis 20, 2009 v 11:13A ještě řešení v PHP:
if (ereg(„^https?://“, $_POST[„TextBox1“]))
copy($_POST[„TextBox1“], „data/FetchImage.jpg“);
Michal Holub
Lis 20, 2009 v 14:17To mi připomělo jeden vtip na hello world :)
Miroslav Kučera
Lis 20, 2009 v 14:26Michal Holub: sem s ním ;-)
Chamurappi
Lis 21, 2009 v 2:05Samotné stažení a uložení souboru jde napsat hodně stručně i v ASP.NET (třeba metodou System.Net.WebClient.DownloadFile), ale o tom článek zjevně není.