Come scaricare un'immagine dall'URL


105

C'è un modo per scaricare un'immagine direttamente da un URL in c # se l'URL non ha un formato immagine alla fine del collegamento? Esempio di URL:

https://fbcdn-sphotos-h-a.akamaihd.net/hphotos-ak-xpf1/v/t34.0-12/10555140_10201501435212873_1318258071_n.jpg?oh=97ebc03895b7acee9aebbde7d6b002bf&oe=53C9ABB0&__gda__=1405685729_110e04e71d969d392b63b27ec4f4b24a

So come scaricare l'immagine quando l'URL termina con un formato immagine. Per esempio:

http://img1.wikia.nocookie.net/__cb20101219155130/uncyclopedia/images/7/70/Facebooklogin.png

Risposte:


136

Semplicemente puoi usare i seguenti metodi.

using (WebClient client = new WebClient()) 
{
    client.DownloadFile(new Uri(url), @"c:\temp\image35.png");
    // OR 
    client.DownloadFileAsync(new Uri(url), @"c:\temp\image35.png");
}

Questi metodi sono quasi gli stessi di DownloadString (..) e DownloadStringAsync (...). Memorizzano il file nella directory anziché nella stringa C # e non è necessaria l'estensione Format in URi

Se non conosci il formato (.png, .jpeg ecc.) Di Image

public void SaveImage(string filename, ImageFormat format)
{    
    WebClient client = new WebClient();
    Stream stream = client.OpenRead(imageUrl);
    Bitmap bitmap;  bitmap = new Bitmap(stream);

    if (bitmap != null)
    {
        bitmap.Save(filename, format);
    }

    stream.Flush();
    stream.Close();
    client.Dispose();
}

Usandolo

try
{
    SaveImage("--- Any Image Path ---", ImageFormat.Png)
}
catch(ExternalException)
{
    // Something is wrong with Format -- Maybe required Format is not 
    // applicable here
}
catch(ArgumentNullException)
{   
    // Something wrong with Stream
}

4
@Arsman Ahmad questa è una domanda completamente diversa che dovrebbe essere cercata o posta altrove. Questo thread serve per il download di una singola immagine.
AzNjoE

79

A seconda che tu conosca o meno il formato dell'immagine, ecco i modi per farlo:

Scarica l'immagine in un file, conoscendo il formato dell'immagine

using (WebClient webClient = new WebClient()) 
{
   webClient.DownloadFile("http://yoururl.com/image.png", "image.png") ; 
}

Scarica l'immagine in un file senza conoscere il formato dell'immagine

Puoi usare Image.FromStreamper caricare qualsiasi tipo di bitmap usuale (jpg, png, bmp, gif, ...), rileverà automaticamente il tipo di file e non avrai nemmeno bisogno di controllare l'estensione dell'URL (che non è un ottimo pratica). Per esempio:

using (WebClient webClient = new WebClient()) 
{
    byte [] data = webClient.DownloadData("https://fbcdn-sphotos-h-a.akamaihd.net/hphotos-ak-xpf1/v/t34.0-12/10555140_10201501435212873_1318258071_n.jpg?oh=97ebc03895b7acee9aebbde7d6b002bf&oe=53C9ABB0&__gda__=1405685729_110e04e71d9");

   using (MemoryStream mem = new MemoryStream(data)) 
   {
       using (var yourImage = Image.FromStream(mem)) 
       { 
          // If you want it as Png
           yourImage.Save("path_to_your_file.png", ImageFormat.Png) ; 

          // If you want it as Jpeg
           yourImage.Save("path_to_your_file.jpg", ImageFormat.Jpeg) ; 
       }
   } 

}

Nota: ArgumentException può essere generata da Image.FromStreamse il contenuto scaricato non è un tipo di immagine noto.

Controlla questo riferimento su MSDN per trovare tutti i formati disponibili. Qui ci sono riferimenti a WebCliente Bitmap.


2
Notare che è necessario "using System.Drawing;" per Image.FromStream ()
dlchambers

3
Nota che invece di chiedere alla libreria di immagini di rilevare il formato dell'immagine puoi anche guardare le intestazioni delle risposte per vedere quale formato la fonte pensa che l'immagine stia usandowebClient.ResponseHeaders["Content-Type"]
bikeman868

Ciò sarebbe anche molto più efficiente in termini di memoria rispetto all'espansione dell'immagine compressa in un oggetto Bitmap non compresso e ti consentirebbe di salvare l'immagine nel suo formato originale con la sua compressione originale, ecc.
bikeman868

20

Per chiunque desideri scaricare un'immagine SENZA salvarla in un file:

Image DownloadImage(string fromUrl)
{
    using (System.Net.WebClient webClient = new System.Net.WebClient())
    {
        using (Stream stream = webClient.OpenRead(fromUrl))
        {
            return Image.FromStream(stream);
        }
    }
}

11

Non è necessario utilizzare System.Drawingper trovare il formato dell'immagine in un URI. System.Drawingnon è disponibile a .NET Coremeno che non si scarichi il pacchetto NuGet System.Drawing.Common e quindi non vedo nessuna buona risposta multipiattaforma a questa domanda.

Inoltre, il mio esempio non viene utilizzato System.Net.WebClientpoiché Microsoft sconsiglia esplicitamente l'uso diSystem.Net.WebClient .

Si sconsiglia di utilizzare la WebClientclasse per nuovi sviluppi. Utilizzare invece la classe System.Net.Http.HttpClient .

Scarica un'immagine e scrivila su un file senza conoscerne l'estensione (multipiattaforma) *

* Senza vecchi System.Net.WebCliente System.Drawing.

Questo metodo scaricherà in modo asincrono un'immagine (o qualsiasi file purché l'URI abbia un'estensione di file) utilizzando System.Net.Http.HttpCliente quindi la scriverà in un file, utilizzando la stessa estensione di file dell'immagine nell'URI.

Ottenere l'estensione del file

La prima parte per ottenere l'estensione del file è rimuovere tutte le parti non necessarie dall'URI.
Usiamo Uri.GetLeftPart () con UriPartial.Path per ottenere tutto, dal Schemefino al Path.
In altre parole, https://www.example.com/image.png?query&with.dotsdiventa https://www.example.com/image.png.

Dopodiché, utilizziamo Path.GetExtension () per ottenere solo l'estensione (nel mio esempio precedente .png).

var uriWithoutQuery = uri.GetLeftPart(UriPartial.Path);
var fileExtension = Path.GetExtension(uriWithoutQuery);

Download dell'immagine

Da qui dovrebbe essere semplice. Scarica l'immagine con HttpClient.GetByteArrayAsync , crea il percorso, assicurati che la directory esista e quindi scrivi i byte nel percorso con File.WriteAllBytesAsync () (o File.WriteAllBytesse sei su .NET Framework)

private async Task DownloadImageAsync(string directoryPath, string fileName, Uri uri)
{
    using var httpClient = new HttpClient();

    // Get the file extension
    var uriWithoutQuery = uri.GetLeftPart(UriPartial.Path);
    var fileExtension = Path.GetExtension(uriWithoutQuery);

    // Create file path and ensure directory exists
    var path = Path.Combine(directoryPath, $"{fileName}{fileExtension}");
    Directory.CreateDirectory(directoryPath);

    // Download the image and write to the file
    var imageBytes = await _httpClient.GetByteArrayAsync(uri);
    await File.WriteAllBytesAsync(path, imageBytes);
}

Nota che hai bisogno delle seguenti direttive using.

using System;
using System.IO;
using System.Threading.Tasks;
using System.Net.Http;

Utilizzo di esempio

var folder = "images";
var fileName = "test";
var url = "https://cdn.discordapp.com/attachments/458291463663386646/592779619212460054/Screenshot_20190624-201411.jpg?query&with.dots";

await DownloadImageAsync(folder, fileName, new Uri(url));

Appunti

  • È una cattiva pratica creare un nuovo HttpClientper ogni chiamata al metodo. Dovrebbe essere riutilizzato in tutta l'applicazione. Ho scritto un breve esempio di un ImageDownloader(50 righe) con più documentazione che riutilizza correttamente HttpCliente lo smaltisce correttamente che puoi trovare qui .

5

.net Framework consente al controllo PictureBox di caricare immagini dall'URL

e Salva immagine in Laod Complete Event

protected void LoadImage() {
 pictureBox1.ImageLocation = "PROXY_URL;}

void pictureBox1_LoadCompleted(object sender, AsyncCompletedEventArgs e) {
   pictureBox1.Image.Save(destination); }

4

Prova questo ha funzionato per me

Scrivilo nel tuo controller

public class DemoController: Controller

        public async Task<FileStreamResult> GetLogoImage(string logoimage)
        {
            string str = "" ;
            var filePath = Server.MapPath("~/App_Data/" + SubfolderName);//If subfolder exist otherwise leave.
            // DirectoryInfo dir = new DirectoryInfo(filePath);
            string[] filePaths = Directory.GetFiles(@filePath, "*.*");
            foreach (var fileTemp in filePaths)
            {
                  str= fileTemp.ToString();
            }
                return File(new MemoryStream(System.IO.File.ReadAllBytes(str)), System.Web.MimeMapping.GetMimeMapping(str), Path.GetFileName(str));
        }

Ecco il mio punto di vista

<div><a href="/DemoController/GetLogoImage?Type=Logo" target="_blank">Download Logo</a></div>

1

La maggior parte dei post che ho trovato scadrà dopo una seconda iterazione. Soprattutto se stai scorrendo un mucchio di immagini come sono stato io. Quindi, per migliorare i suggerimenti sopra, ecco l'intero metodo:

public System.Drawing.Image DownloadImage(string imageUrl)
    {
        System.Drawing.Image image = null;

        try
        {
            System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(imageUrl);
            webRequest.AllowWriteStreamBuffering = true;
            webRequest.Timeout = 30000;
            webRequest.ServicePoint.ConnectionLeaseTimeout = 5000;
            webRequest.ServicePoint.MaxIdleTime = 5000;

            using (System.Net.WebResponse webResponse = webRequest.GetResponse())
            {

                using (System.IO.Stream stream = webResponse.GetResponseStream())
                {
                    image = System.Drawing.Image.FromStream(stream);
                }
            }

            webRequest.ServicePoint.CloseConnectionGroup(webRequest.ConnectionGroupName);
            webRequest = null; 
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message, ex);

        }


        return image;
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.