Non è necessario utilizzare System.Drawing
per trovare il formato dell'immagine in un URI. System.Drawing
non è disponibile a .NET Core
meno 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.WebClient
poiché Microsoft sconsiglia esplicitamente l'uso diSystem.Net.WebClient
.
Si sconsiglia di utilizzare la WebClient
classe 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.WebClient
e 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.HttpClient
e 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 Scheme
fino al Path
.
In altre parole, https://www.example.com/image.png?query&with.dots
diventa 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.WriteAllBytes
se 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
HttpClient
per 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 HttpClient
e lo smaltisce correttamente che puoi trovare qui .