Não é necessário usar System.Drawing
para localizar o formato da imagem em um URI. System.Drawing
não está disponível para a .NET Core
menos que você baixe o pacote System.Drawing.Common NuGet e, portanto, não vejo nenhuma boa resposta entre plataformas para essa pergunta.
Além disso, meu exemplo não usa, System.Net.WebClient
pois a Microsoft desestimula explicitamente o uso deSystem.Net.WebClient
.
Não recomendamos que você use a WebClient
classe para novos desenvolvimentos. Em vez disso, use a classe System.Net.Http.HttpClient .
Baixe uma imagem e grave-a em um arquivo sem saber a extensão (plataforma cruzada) *
* Sem System.Net.WebClient
e velho System.Drawing
.
Este método irá baixar de forma assíncrona uma imagem (ou qualquer arquivo, desde que o URI tenha uma extensão de arquivo) usando o System.Net.Http.HttpClient
e, em seguida, gravá-lo em um arquivo, usando a mesma extensão de arquivo que a imagem tinha no URI.
Obtendo a extensão do arquivo
A primeira parte para obter a extensão do arquivo é remover todas as partes desnecessárias do URI.
Usamos Uri.GetLeftPart () com UriPartial.Path para obter tudo, desde o Scheme
até o Path
.
Em outras palavras, https://www.example.com/image.png?query&with.dots
torna-se https://www.example.com/image.png
.
Depois disso, usamos Path.GetExtension () para obter apenas a extensão (em meu exemplo anterior, .png
).
var uriWithoutQuery = uri.GetLeftPart(UriPartial.Path);
var fileExtension = Path.GetExtension(uriWithoutQuery);
Baixando a imagem
A partir daqui, deve ser direto. Baixe a imagem com HttpClient.GetByteArrayAsync , crie o caminho, verifique se o diretório existe e, em seguida, grave os bytes no caminho com File.WriteAllBytesAsync () (ou File.WriteAllBytes
se você estiver no .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);
}
Observe que você precisa do seguinte usando diretivas.
using System;
using System.IO;
using System.Threading.Tasks;
using System.Net.Http;
Exemplo de uso
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));
Notas
- É uma má prática criar um novo
HttpClient
para cada chamada de método. Deve ser reutilizado em todo o aplicativo. Escrevi um pequeno exemplo de um ImageDownloader
(50 linhas) com mais documentação que reutiliza corretamente HttpClient
e elimina corretamente o que você pode encontrar aqui .