So laden Sie ein Bild von der URL herunter

103

Gibt es eine Möglichkeit, ein Bild direkt von einer URL in c # herunterzuladen, wenn die URL am Ende des Links kein Bildformat hat? Beispiel für 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

Ich kann das Bild herunterladen, wenn die URL mit einem Bildformat endet. Z.B:

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

Antworten:

134

Einfach Sie können folgende Methoden verwenden.

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

Diese Methoden sind fast identisch mit DownloadString (..) und DownloadStringAsync (...). Sie speichern die Datei im Verzeichnis und nicht in der C # -String und benötigen keine Formaterweiterung in URi

Wenn Sie das Format (.png, .jpeg usw.) von Image nicht kennen

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

Es benutzen

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
quelle
4
@Arsman Ahmad, das ist eine ganz andere Frage, die anderswo gesucht oder gestellt werden sollte. Dieser Thread dient zum Herunterladen eines einzelnen Bildes.
AzNjoE
79

Je nachdem, ob Sie das Bildformat kennen oder nicht, können Sie dies folgendermaßen tun:

Laden Sie das Bild in eine Datei herunter und kennen Sie das Bildformat

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

Laden Sie das Bild in eine Datei herunter, ohne das Bildformat zu kennen

Sie können Image.FromStreamjede Art von üblichen Bitmaps (jpg, png, bmp, gif, ...) laden, es erkennt automatisch den Dateityp und Sie müssen nicht einmal die URL-Erweiterung überprüfen (was nicht sehr gut ist trainieren). Z.B:

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

}

Hinweis: ArgumentException kann ausgelöst werden, Image.FromStreamwenn der heruntergeladene Inhalt kein bekannter Bildtyp ist.

Überprüfen Sie diese Referenz auf MSDN , um alle verfügbaren Formate zu finden. Hier verweisen auf WebClientund Bitmap.

Perfect28
quelle
2
Beachten Sie, dass Sie "using System.Drawing;" benötigen. für Image.FromStream ()
dlchambers
3
Beachten Sie, dass Sie, anstatt die Imaging-Bibliothek zu bitten, das Bildformat zu ermitteln, auch in den webClient.ResponseHeaders["Content-Type"]
Antwortheadern nachsehen können,
Dies wäre auch viel speichereffizienter als das Erweitern des komprimierten Bildes in ein unkomprimiertes Bitmap-Objekt und würde es Ihnen ermöglichen, das Bild in seinem ursprünglichen Format mit seiner ursprünglichen Komprimierung usw. zu
speichern
19

Für alle, die ein Bild herunterladen möchten, ohne es in einer Datei zu speichern:

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
quelle
9

Es ist nicht erforderlich, System.Drawingdas Bildformat in einer URI zu suchen. System.Drawingist nur verfügbar, .NET Corewenn Sie das System.Drawing.Common NuGet-Paket herunterladen. Daher sehe ich keine guten plattformübergreifenden Antworten auf diese Frage.

Außerdem wird mein Beispiel nicht verwendet, System.Net.WebClientda Microsoft ausdrücklich von der Verwendung von abrätSystem.Net.WebClient .

Wir empfehlen nicht, die WebClientKlasse für Neuentwicklungen zu verwenden. Verwenden Sie stattdessen die Klasse System.Net.Http.HttpClient .

Laden Sie ein Bild herunter und schreiben Sie es in eine Datei, ohne die Erweiterung zu kennen (plattformübergreifend) *

* Ohne alt System.Net.WebClientund System.Drawing.

Diese Methode lädt asynchron ein Bild (oder eine beliebige Datei, solange der URI eine Dateierweiterung hat) mit dem herunter System.Net.Http.HttpClientund schreibt es dann in eine Datei mit derselben Dateierweiterung wie das Bild im URI.

Abrufen der Dateierweiterung

Der erste Teil des Abrufs der Dateierweiterung besteht darin, alle unnötigen Teile aus dem URI zu entfernen.
Wir verwenden Uri.GetLeftPart () mit UriPartial.Path, um alles von Schemeoben bis unten zu erhalten Path.
Mit anderen Worten, https://www.example.com/image.png?query&with.dotswird https://www.example.com/image.png.

Danach verwenden wir Path.GetExtension () , um nur die Erweiterung abzurufen ( in meinem vorherigen Beispiel .png).

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

Bild herunterladen

Von hier sollte es einfach sein. Laden Sie das Image mit HttpClient.GetByteArrayAsync herunter , erstellen Sie den Pfad, stellen Sie sicher, dass das Verzeichnis vorhanden ist, und schreiben Sie die Bytes mit File.WriteAllBytesAsync () in den Pfad (oder File.WriteAllByteswenn Sie sich in .NET Framework befinden).

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

Beachten Sie, dass Sie mithilfe von Anweisungen Folgendes benötigen.

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

Anwendungsbeispiel

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

Anmerkungen

  • Es ist eine schlechte Praxis, HttpClientfür jeden Methodenaufruf eine neue zu erstellen . Es soll während der gesamten Anwendung wiederverwendet werden. Ich habe ein kurzes Beispiel eines ImageDownloader(50 Zeilen) mit mehr Dokumentation geschrieben, das das hier wiederverwendet HttpClientund ordnungsgemäß entsorgt, das Sie hier finden .
MarcusOtter
quelle
5

Mit .net Framework kann PictureBox Control Bilder von der URL laden

und Bild in Laod Complete Event speichern

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

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

Versuchen Sie das, es hat bei mir funktioniert

Schreiben Sie dies in Ihren 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));
        }

Hier ist meine Ansicht

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

Die meisten Beiträge, die ich gefunden habe, werden nach einer zweiten Iteration eine Zeitüberschreitung aufweisen. Besonders, wenn Sie eine Menge Bilder durchlaufen, wie ich es war. Um die obigen Vorschläge zu verbessern, ist hier die gesamte Methode:

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
quelle