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 .