如何从网址下载图片

时间:2014-07-17 07:34:35

标签: c# url download

如果网址在链接末尾没有图片格式,是否可以直接从c#中的网址下载图片?网址示例:

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

7 个答案:

答案 0 :(得分:94)

<强>简单地 您可以使用以下方法。

  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(...)几乎相同。它们将文件存储在Directory而不是C#字符串中,并且不需要URi中的Format扩展

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

 public void SaveImage(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 Path ---", ImageFormat.Png)

 }catch(ExternalException)
 {
   //Something is wrong with Format -- Maybe required Format is not 
   // applicable here
 }
 catch(ArgumentNullException)
 {  
    //Something wrong with Stream
 }

答案 1 :(得分:65)

根据您是否了解图像格式,可以采用以下方法:

将图像下载到文件中,知道图像格式

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。

检查this reference on MSDN以查找所有可用格式。 以下是WebClientBitmap的参考。

答案 2 :(得分:6)

对于任何想要下载图像而不将其保存到文件的人:

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

答案 3 :(得分:4)

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

并在Laod Complete Event中保存图像

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

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

答案 4 :(得分:0)

尝试此操作绝对可以100%工作

将此内容写入您的控制器文件中

public class TenantCustomizationController : RecruitControllerBase

    //enter code here

[AllowAnonymous]
        [HttpGet]
        public async Task<FileStreamResult> GetLogoImage(string logoimage)
        {
            string str = "" ;
            var filePath = Server.MapPath("~/App_Data/" + AbpSession.TenantId.Value);
            // 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));
        }
        //09/07/2018

Here Is my View


<div><a href="/TenantCustomization/GetLogoImage?Type=Logo" target="_blank">@L("DownloadBrowseLogo")</a></div>

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

不必使用System.Drawing在URI中查找图像格式。除非您下载System.Drawing.Common NuGet package,否则System.Drawing不适用于.NET Core,因此我看不到该问题的任何跨平台的好答案。

此外,我的示例从Microsoft explicitly discourage the use of System.Net.WebClient开始不使用System.Net.WebClient

  

我们不建议您将WebClient类用于新开发。而是使用System.Net.Http.HttpClient类。

下载图像并将其写入文件而无需扩展名(跨平台)*

*没有旧的System.Net.WebClientSystem.Drawing

此方法将使用System.Net.Http.HttpClient异步下载图片(或只要URI具有文件扩展名的任何文件),然后使用与图片中相同的文件扩展名将其写入文件。 URI。

获取文件扩展名

获取文件扩展名的第一步是从URI中删除所有不必要的部分。
我们将Uri.GetLeftPart()与UriPartial.Path结合使用,以获取从SchemePath的所有内容。
换句话说,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()(如果使用.NET Framework,则使用File.WriteAllBytes)将字节写入路径

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 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并妥善处理以供您here使用。