Comment télécharger une image à partir de l'URL

105

Existe-t-il un moyen de télécharger une image directement à partir d'une URL en c # si l'url n'a pas de format d'image à la fin du lien? Exemple d'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

Je sais comment télécharger l'image lorsque l'URL se termine par un format d'image. Par exemple:

http://img1.wikia.nocookie.net/__cb20101219155130/uncyclopedia/images/7/70/Facebooklogin.png
Ifwat Ibrahim
la source

Réponses:

136

Simplement, vous pouvez utiliser les méthodes suivantes.

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

Ces méthodes sont presque identiques à celles de DownloadString (..) et DownloadStringAsync (...). Ils stockent le fichier dans le répertoire plutôt que dans la chaîne C # et n'ont pas besoin d'extension de format dans URi

Si vous ne connaissez pas le format (.png, .jpeg, etc.) de l'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();
}

En l'utilisant

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
}
Charlie
la source
4
@Arsman Ahmad c'est une question complètement différente qui devrait être recherchée ou posée ailleurs. Ce fil est pour le téléchargement d'une seule image.
AzNjoE
79

Selon que vous connaissez ou non le format de l'image, voici des moyens de le faire:

Télécharger l'image dans un fichier en connaissant le format de l'image

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

Télécharger l'image dans un fichier sans connaître le format de l'image

Vous pouvez utiliser Image.FromStreampour charger n'importe quel type de bitmaps habituels (jpg, png, bmp, gif, ...), il détectera automatiquement le type de fichier et vous n'aurez même pas besoin de vérifier l'extension d'url (ce qui n'est pas très bon entraine toi). Par exemple:

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) ; 
       }
   } 

}

Remarque: ArgumentException peut être levée Image.FromStreamsi le contenu téléchargé n'est pas un type d'image connu.

Consultez cette référence sur MSDN pour trouver tous les formats disponibles. Voici la référence à WebClientet Bitmap.

Parfait28
la source
2
Notez que vous avez besoin de "using System.Drawing;" pour Image.FromStream ()
dlchambers
3
Notez qu'au lieu de demander à la bibliothèque d'imagerie de détecter le format d'image, vous pouvez également consulter les en-têtes de réponse pour voir quel format la source pense que l'image utilisewebClient.ResponseHeaders["Content-Type"]
bikeman868
Ce serait également beaucoup plus efficace en
termes de
20

Pour toute personne souhaitant télécharger une image SANS l'enregistrer dans un fichier:

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

Il n'est pas nécessaire d'utiliser System.Drawingpour trouver le format d'image dans un URI. System.Drawingn'est pas disponible pour .NET Coresauf si vous téléchargez le package NuGet System.Drawing.Common et je ne vois donc pas de bonnes réponses multiplateformes à cette question.

De plus, mon exemple n'est pas utilisé System.Net.WebClientcar Microsoft décourage explicitement l'utilisation deSystem.Net.WebClient .

Nous ne vous recommandons pas d'utiliser la WebClientclasse pour un nouveau développement. Au lieu de cela, utilisez la classe System.Net.Http.HttpClient .

Téléchargez une image et écrivez-la dans un fichier sans connaître l'extension (multiplateforme) *

* Sans ancien System.Net.WebClientet System.Drawing.

Cette méthode téléchargera de manière asynchrone une image (ou n'importe quel fichier tant que l'URI a une extension de fichier) à l'aide de System.Net.Http.HttpClient, puis l'écrira dans un fichier, en utilisant la même extension de fichier que l'image contenue dans l'URI.

Obtenir l'extension de fichier

La première partie de l'obtention de l'extension de fichier consiste à supprimer toutes les parties inutiles de l'URI.
Nous utilisons Uri.GetLeftPart () avec UriPartial.Path pour tout obtenir, du Schemeplus au Path.
En d'autres termes, https://www.example.com/image.png?query&with.dotsdevient https://www.example.com/image.png.

Après cela, nous utilisons Path.GetExtension () pour obtenir uniquement l'extension (dans mon exemple précédent, .png).

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

Téléchargement de l'image

À partir de là, cela devrait être simple. Téléchargez l'image avec HttpClient.GetByteArrayAsync , créez le chemin, assurez-vous que le répertoire existe, puis écrivez les octets dans le chemin avec File.WriteAllBytesAsync () (ou File.WriteAllBytessi vous êtes sur .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);
}

Notez que vous avez besoin des directives using suivantes.

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

Exemple d'utilisation

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));

Remarques

  • C'est une mauvaise pratique de créer un nouveau HttpClientpour chaque appel de méthode. Il est censé être réutilisé tout au long de l'application. J'ai écrit un court exemple d'un ImageDownloader(50 lignes) avec plus de documentation qui réutilise correctement HttpClientet en élimine correctement que vous pouvez trouver ici .
MarcusOtter
la source
5

.net Framework permet à PictureBox Control de charger des images à partir de l'URL

et enregistrer l'image dans l'événement complet Laod

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

void pictureBox1_LoadCompleted(object sender, AsyncCompletedEventArgs e) {
   pictureBox1.Image.Save(destination); }
Ali Humayun
la source
4

Essayez ceci, cela a fonctionné pour moi

Écrivez ceci dans votre contrôleur

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));
        }

Voici mon avis

<div><a href="/DemoController/GetLogoImage?Type=Logo" target="_blank">Download Logo</a></div>
Chandan Kumar
la source
1

La plupart des messages que j'ai trouvés expireront après une deuxième itération. Surtout si vous faites une boucle sur un tas d'images comme je l'ai été. Donc, pour améliorer les suggestions ci-dessus, voici la méthode entière:

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;
    }
Be05x5
la source