Nie jest konieczne użycie, System.Drawing
aby znaleźć format obrazu w identyfikatorze URI. System.Drawing
nie jest dostępny, .NET Core
chyba ż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.WebClient
ponieważ Microsoft wyraźnie odradza używanieSystem.Net.WebClient
.
Nie zalecamy używania tej WebClient
klasy 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.WebClient
i System.Drawing
.
Ta metoda asynchronicznie pobierze obraz (lub dowolny plik, o ile identyfikator URI ma rozszerzenie pliku) przy użyciu rozszerzenia, System.Net.Http.HttpClient
a 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 Scheme
góry do Path
.
Innymi słowy, https://www.example.com/image.png?query&with.dots
staje 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.WriteAllBytes
jeś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
HttpClient
dla 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 HttpClient
i prawidłowo usuwa, którą można znaleźć tutaj .