Nie jest konieczne użycie, System.Drawingaby znaleźć format obrazu w identyfikatorze URI. System.Drawingnie jest dostępny, .NET Corechyba że pobierzesz pakiet System.Drawing.Common NuGet i dlatego nie widzę żadnych dobrych odpowiedzi na to pytanie dla wielu platform.
Ponadto mój przykład nie używa, System.Net.WebClientponieważ Microsoft wyraźnie odradza używanieSystem.Net.WebClient .
Nie zalecamy używania tej WebClientklasy do nowego rozwoju. Zamiast tego użyj klasy System.Net.Http.HttpClient .
Pobierz obraz i zapisz go do pliku bez znajomości rozszerzenia (wiele platform) *
* Bez starych System.Net.WebClienti System.Drawing.
Ta metoda asynchronicznie pobierze obraz (lub dowolny plik, o ile identyfikator URI ma rozszerzenie pliku) przy użyciu rozszerzenia, System.Net.Http.HttpClienta następnie zapisze go w pliku, używając tego samego rozszerzenia pliku, co obraz w identyfikatorze URI.
Pobieranie rozszerzenia pliku
Pierwszą częścią uzyskiwania rozszerzenia pliku jest usunięcie wszystkich niepotrzebnych części z identyfikatora URI.
Używamy Uri.GetLeftPart () z UriPartial.Path dostać wszystko od Schemegóry do Path.
Innymi słowy, https://www.example.com/image.png?query&with.dotsstaje się https://www.example.com/image.png.
Następnie używamy Path.GetExtension (), aby uzyskać tylko rozszerzenie (w moim poprzednim przykładzie .png).
var uriWithoutQuery = uri.GetLeftPart(UriPartial.Path);
var fileExtension = Path.GetExtension(uriWithoutQuery);
Pobieranie obrazu
Stąd powinno być prosto. Pobierz obraz za pomocą HttpClient.GetByteArrayAsync , utwórz ścieżkę, upewnij się, że katalog istnieje, a następnie zapisz bajty w ścieżce za pomocą File.WriteAllBytesAsync () (lub File.WriteAllBytesjeśli korzystasz z .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);
}
Zauważ, że potrzebujesz następujących dyrektyw using.
using System;
using System.IO;
using System.Threading.Tasks;
using System.Net.Http;
Przykładowe użycie
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));
Uwagi
- Tworzenie nowego
HttpClientdla każdego wywołania metody jest złą praktyką . Powinien być ponownie używany w całej aplikacji. Napisałem krótki przykład ImageDownloader(50 wierszy) z większą dokumentacją, która poprawnie ponownie wykorzystuje HttpClienti prawidłowo usuwa, którą można znaleźć tutaj .