[英]How to download image from 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
我知道如何在 url 以圖像格式結尾時下載圖像。 例如:
http://img1.wikia.nocookie.net/__cb20101219155130/uncyclopedia/images/7/70/Facebooklogin.png
只需您可以使用以下方法。
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 中使用格式擴展名
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
}
根據您是否知道圖像格式,您可以使用以下方法:
using (WebClient webClient = new WebClient())
{
webClient.DownloadFile("http://yoururl.com/image.png", "image.png") ;
}
您可以使用Image.FromStream
加載任何類型的常用位圖(jpg、png、bmp、gif、...),它會自動檢測文件類型,您甚至不需要檢查 url 擴展名(這不是一個很好的做法)。 例如:
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。
對於想要下載圖像而不將其保存到文件的任何人:
Image DownloadImage(string fromUrl)
{
using (System.Net.WebClient webClient = new System.Net.WebClient())
{
using (Stream stream = webClient.OpenRead(fromUrl))
{
return Image.FromStream(stream);
}
}
}
.NET 多年來發生了一些變化,使得這篇文章中的其他答案相當過時:
System.Drawing
Image
(不適用於 .NET Core)來查找圖像格式System.Net.WebClient
我們不建議您使用
WebClient
類進行新的開發。 而是使用System.Net.Http.HttpClient類。
獲取文件擴展名的第一部分是從 URL 中刪除所有不必要的部分。 我們可以使用Uri.GetLeftPart()和 UriPartial.Path 來獲取從Scheme
到Path
。
換句話說, https://www.example.com/image.png?query&with.dots
變成https://www.example.com/image.png
。
之后,我們可以使用Path.GetExtension()僅獲取擴展名(在我之前的示例中, .png
)。
var uriWithoutQuery = uri.GetLeftPart(UriPartial.Path);
var fileExtension = Path.GetExtension(uriWithoutQuery);
從這里開始應該是直截了當的。 使用HttpClient.GetByteArrayAsync下載圖像,創建路徑,確保目錄存在,然后使用File.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
並正確處理它的文檔,您可以在此處找到。.net 框架允許 PictureBox 控件從 url 加載圖像
並在Laod Complete Event中保存圖像
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>
我發現的大多數帖子在第二次迭代后都會超時。 特別是如果你像我一樣遍歷一堆圖像。 因此,改進上面的建議是整個方法:
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;
}
這個方法對我來說,
我從這里得到了主要代碼
然后使用此修復程序
我能夠制作一種可以繞過可怕的禁止 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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.