如何从 URL 下载图片

如果链接末尾的 url 没有图像格式,有没有办法直接从 c # 中的 url 下载图像?网址示例:

https://fbcdn-sphotos-h-a.akamaihd.net/hphotos-ak-xpf1/v/t34.0-12/10555140_10201501435212873_1318258071_n.jpg?oh=97ebc03895b7acee9aebbde7d6b002bf&oe=53C9ABB0&__gda__=1405685729_110e04e71d969d392b63b27ec4f4b24a

我知道如何下载的图像时,网址结束的图像格式。例如:

http://img1.wikia.nocookie.net/__cb20101219155130/uncyclopedia/images/7/70/Facebooklogin.png
286260 次浏览

这取决于你是否知道图像格式,以下是你可以做到的方法:

了解图像格式后,将图像下载到文件中

using (WebClient webClient = new WebClient())
{
webClient.DownloadFile("http://yoururl.com/image.png", "image.png") ;
}

在不知道图像格式的情况下将图像下载到文件中

你可以使用 Image.FromStream加载任何类型的位图(jpg,png,bmp,gif,...) ,它会自动检测文件类型,你甚至不需要检查网址扩展名(这不是一个很好的做法)。例如:

using (WebClient webClient = new WebClient())
{
byte [] data = webClient.DownloadData("https://fbcdn-sphotos-h-a.akamaihd.net/hphotos-ak-xpf1/v/t34.0-12/10555140_10201501435212873_1318258071_n.jpg?oh=97ebc03895b7acee9aebbde7d6b002bf&oe=53C9ABB0&__gda__=1405685729_110e04e71d9");


using (MemoryStream mem = new MemoryStream(data))
{
using (var yourImage = Image.FromStream(mem))
{
// If you want it as Png
yourImage.Save("path_to_your_file.png", ImageFormat.Png) ;


// If you want it as Jpeg
yourImage.Save("path_to_your_file.jpg", ImageFormat.Jpeg) ;
}
}


}

注意: 如果下载的内容不是已知的图像类型,Image.FromStream可能会抛出 ArgumentException。

检查 MSDN 上的参考资料以查找所有可用的格式。 这里是参考 WebClientBitmap

很简单 您可以使用以下方法。

using (WebClient client = new WebClient())
{
client.DownloadFile(new Uri(url), @"c:\temp\image35.png");
// OR
client.DownloadFileAsync(new Uri(url), @"c:\temp\image35.png");
}

这些方法与 DownloadString (。.)和 DownloadStringAsync (...)。它们将文件存储在目录中而不是 C # 字符串中,并且不需要在 URi 中设置格式扩展名

如果你不知道图片的格式(. png,. jpeg 等)

public void SaveImage(string imageUrl, string filename, ImageFormat format)
{
WebClient client = new WebClient();
Stream stream = client.OpenRead(imageUrl);
Bitmap bitmap;  bitmap = new Bitmap(stream);


if (bitmap != null)
{
bitmap.Save(filename, format);
}
        

stream.Flush();
stream.Close();
client.Dispose();
}

用它

try
{
SaveImage("--- Any Image URL---", "--- Any Image Path ---", ImageFormat.Png)
}
catch(ExternalException)
{
// Something is wrong with Format -- Maybe required Format is not
// applicable here
}
catch(ArgumentNullException)
{
// Something wrong with Stream
}

. net Framework 允许 PictureBox 控件从 URL 加载图像

在完成事件中保存图像

protected void LoadImage() {
pictureBox1.ImageLocation = "PROXY_URL;}


void pictureBox1_LoadCompleted(object sender, AsyncCompletedEventArgs e) {
pictureBox1.Image.Save(destination); }

试试这个,对我有用

把这个写在控制器中

public class DemoController: Controller


public async Task<FileStreamResult> GetLogoImage(string logoimage)
{
string str = "" ;
var filePath = Server.MapPath("~/App_Data/" + SubfolderName);//If subfolder exist otherwise leave.
// DirectoryInfo dir = new DirectoryInfo(filePath);
string[] filePaths = Directory.GetFiles(@filePath, "*.*");
foreach (var fileTemp in filePaths)
{
str= fileTemp.ToString();
}
return File(new MemoryStream(System.IO.File.ReadAllBytes(str)), System.Web.MimeMapping.GetMimeMapping(str), Path.GetFileName(str));
}

这是我的观点

<div><a href="/DemoController/GetLogoImage?Type=Logo" target="_blank">Download Logo</a></div>

对于那些想下载图片而不想将其保存到文件中的人:

Image DownloadImage(string fromUrl)
{
using (System.Net.WebClient webClient = new System.Net.WebClient())
{
using (Stream stream = webClient.OpenRead(fromUrl))
{
return Image.FromStream(stream);
}
}
}

我发现的大多数帖子都会在第二次迭代后超时。特别是如果你是循环通过一堆,如果图像我已经。因此,为了改进上面的建议,这里是整个方法:

public System.Drawing.Image DownloadImage(string imageUrl)
{
System.Drawing.Image image = null;


try
{
System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(imageUrl);
webRequest.AllowWriteStreamBuffering = true;
webRequest.Timeout = 30000;
webRequest.ServicePoint.ConnectionLeaseTimeout = 5000;
webRequest.ServicePoint.MaxIdleTime = 5000;


using (System.Net.WebResponse webResponse = webRequest.GetResponse())
{


using (System.IO.Stream stream = webResponse.GetResponseStream())
{
image = System.Drawing.Image.FromStream(stream);
}
}


webRequest.ServicePoint.CloseConnectionGroup(webRequest.ConnectionGroupName);
webRequest = null;
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);


}




return image;
}

.NET 在过去的几年里发生了一些变化,使得这篇文章中的其他回答显得相当过时:

  • 它们使用来自 System.DrawingImage(这对.NET Core 是不可用的)来查找图像格式
  • 他们用的是 System.Net.WebClient也就是 不赞成

我们不建议您使用 WebClient类进行新的开发,而是使用 客户端类。

.NET 核心异步解决方案

获取文件扩展名

获取文件扩展名的第一部分是从 URL 中删除所有不必要的部分。 我们可以使用 Uri. GetLeftPart ()和 UriPartit.Path 来获取从 SchemePath的所有内容。
换句话说,https://www.example.com/image.png?query&with.dots变成了 https://www.example.com/image.png

之后,我们可以使用 路径来获取扩展名(在我之前的示例中是 .png)。

var uriWithoutQuery = uri.GetLeftPart(UriPartial.Path);
var fileExtension = Path.GetExtension(uriWithoutQuery);

正在下载图像

从这里开始应该直走。用 HttpClient. GetByteArrayAsync下载映像,创建路径,确保目录存在,然后用 文件: WriteAllBytesAsync ()将字节写入路径

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);
}

请注意,您需要以下 using 指令。

using System;
using System.IO;
using System.Threading.Tasks;
using System.Net.Http;

示例用法

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));

笔记

  • 为每个方法调用创建一个新的 HttpClient是不好的做法。它应该在整个应用程序中被重用。我编写了一个简短的 ImageDownloader示例(50行) ,其中有更多的文档,可以正确地重用 HttpClient并正确地处理它,您可以找到 给你

这个方法帮了我,

我从 给你拿到了主代码

然后用这个 修好

我能够制定一个方法,可以绕过可怕的禁止403错误

方法如下

    private static void DownloadImage(string url, string saveFilename)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
// we need the user agent and default credentials if not,
//  we get a forbidden request 303 error, which pretty much means the server thinks we are a bot -- which we are.... hehehehehehe
httpWebRequest.UserAgent = "Case Banana"; // note -- this string can be anything you like, I recommend making it atleast 10 characters
httpWebRequest.UseDefaultCredentials = true;


var httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
if ((httpWebResponse.StatusCode != HttpStatusCode.OK &&
httpWebResponse.StatusCode != HttpStatusCode.Moved &&
httpWebResponse.StatusCode != HttpStatusCode.Redirect)
|| !httpWebResponse.ContentType.StartsWith("image", StringComparison.OrdinalIgnoreCase))
{
return;
}


using (var stream = httpWebResponse.GetResponseStream())
{
using (var fileStream = File.OpenWrite(saveFilename))
{
var bytes = new byte[4096];
var read = 0;
do
{
if (stream == null)
{
continue;
}
read = stream.Read(bytes, 0, bytes.Length);
fileStream.Write(bytes, 0, read);
} while (read != 0);
}
}
}

对于这个问题,每个人都给出了一个很好的解决方案,但是在每个人给出的所有解决方案背后都存在一个主要问题,即如果图像托管在 https 上,它将不会创建 SSL/TLS 安全通道。那么,我们应该怎么做呢?答案很简单,只需在创建 WebClient 请求之前添加这两行

ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;