Il n'est pas nécessaire d'utiliser System.Drawing
pour trouver le format d'image dans un URI. System.Drawing
n'est pas disponible pour .NET Core
sauf 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.WebClient
car Microsoft décourage explicitement l'utilisation deSystem.Net.WebClient
.
Nous ne vous recommandons pas d'utiliser la WebClient
classe 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.WebClient
et 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 Scheme
plus au Path
.
En d'autres termes, https://www.example.com/image.png?query&with.dots
devient 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.WriteAllBytes
si 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
HttpClient
pour 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 HttpClient
et en élimine correctement que vous pouvez trouver ici .