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 .