【问题标题】:Download image from the site in .NET/C#从 .NET/C# 中的站点下载图像
【发布时间】:2011-04-06 15:49:48
【问题描述】:

我正在尝试从该站点下载图像。当图像可用时,我使用的代码工作正常。如果图像不可用,则会产生问题。如何验证图像的可用性?

代码:

方法一:

WebRequest requestPic = WebRequest.Create(imageUrl);

WebResponse responsePic = requestPic.GetResponse();

Image webImage = Image.FromStream(responsePic.GetResponseStream()); // Error

webImage.Save("D:\\Images\\Book\\" + fileName + ".jpg");

方法二:

WebClient client = new WebClient();
Stream stream = client.OpenRead(imageUrl);

bitmap = new Bitmap(stream); // Error : Parameter is not valid.
stream.Flush();
stream.Close();
client.dispose();

if (bitmap != null)
{
    bitmap.Save("D:\\Images\\" + fileName + ".jpg");
}

编辑:

Stream 有以下语句:

      Length  '((System.Net.ConnectStream)(str)).Length' threw an exception of type  'System.NotSupportedException'    long {System.NotSupportedException}
    Position  '((System.Net.ConnectStream)(str)).Position' threw an exception of type 'System.NotSupportedException'    long {System.NotSupportedException}
 ReadTimeout  300000    int
WriteTimeout  300000    int

【问题讨论】:

  • try - catch 包装违规语句,并向我们提供异常详细信息。
  • 行 bitmap = new Bitmap(stream);显示错误:参数无效。

标签: c# .net image streaming


【解决方案1】:

无需涉及任何图片类,直接调用WebClient.DownloadFile即可:

string localFilename = @"c:\localpath\tofile.jpg";
using(WebClient client = new WebClient())
{
    client.DownloadFile("http://www.example.com/image.jpg", localFilename);
}

更新
由于您需要检查文件是否存在并下载文件,因此最好在同一个请求中执行此操作。所以这里有一个方法可以做到这一点:

private static void DownloadRemoteImageFile(string uri, string fileName)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

    // Check that the remote file was found. The ContentType
    // check is performed since a request for a non-existent
    // image file might be redirected to a 404-page, which would
    // yield the StatusCode "OK", even though the image was not
    // found.
    if ((response.StatusCode == HttpStatusCode.OK || 
        response.StatusCode == HttpStatusCode.Moved || 
        response.StatusCode == HttpStatusCode.Redirect) &&
        response.ContentType.StartsWith("image",StringComparison.OrdinalIgnoreCase))
    {

        // if the remote file was found, download oit
        using (Stream inputStream = response.GetResponseStream())
        using (Stream outputStream = File.OpenWrite(fileName))
        {
            byte[] buffer = new byte[4096];
            int bytesRead;
            do
            {
                bytesRead = inputStream.Read(buffer, 0, buffer.Length);
                outputStream.Write(buffer, 0, bytesRead);
            } while (bytesRead != 0);
        }
    }
}

简而言之,它发出文件请求,验证响应代码是OKMovedRedirect 之一并且ContentType 是图像.如果这些条件为真,则下载文件。

【讨论】:

  • 别忘了处理WebClient
  • @Geetha:如果您尝试在网络浏览器中导航到给定的 URL,您会得到图像吗?
  • @Geetha:听起来好像您首先要检查图像是否存在,然后下载它。对于第一步,请在此处查看:stackoverflow.com/questions/1379371/…
  • 它花费了太多时间并且还下载了空白图像。行位图 = 新位图(流);显示错误:参数无效
  • “不需要涉及任何图像类”。实际上,如果您打算下载图像,对其进行操作并简单地显示它,则需要。如果不需要存储文件,则无需存储文件甚至用图像填充磁盘。
【解决方案2】:

我在一个项目中使用了 Fredrik 的上述代码,稍作修改,我想分享一下:

private static bool DownloadRemoteImageFile(string uri, string fileName)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    HttpWebResponse response;
    try
    {
        response = (HttpWebResponse)request.GetResponse();
    }
    catch (Exception)
    {
        return false;
    }

    // Check that the remote file was found. The ContentType
    // check is performed since a request for a non-existent
    // image file might be redirected to a 404-page, which would
    // yield the StatusCode "OK", even though the image was not
    // found.
    if ((response.StatusCode == HttpStatusCode.OK ||
        response.StatusCode == HttpStatusCode.Moved ||
        response.StatusCode == HttpStatusCode.Redirect) &&
        response.ContentType.StartsWith("image", StringComparison.OrdinalIgnoreCase))
    {

        // if the remote file was found, download it
        using (Stream inputStream = response.GetResponseStream())
        using (Stream outputStream = File.OpenWrite(fileName))
        {
            byte[] buffer = new byte[4096];
            int bytesRead;
            do
            {
                bytesRead = inputStream.Read(buffer, 0, buffer.Length);
                outputStream.Write(buffer, 0, bytesRead);
            } while (bytesRead != 0);
        }
        return true;
    }
    else
        return false;
}

主要变化是:

  • 对 GetResponse() 使用 try/catch,因为当远程文件返回 404 时我遇到了异常
  • 返回一个布尔值

【讨论】:

  • 谢谢 - 看起来代码写得很好,在我的应用程序中运行良好
  • 当你可以抛出异常时,为什么要返回一个布尔标志?在您遇到性能问题之前总是更好。 SRP 不允许有这些方法。
【解决方案3】:
        private static void DownloadRemoteImageFile(string uri, string fileName)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            if ((response.StatusCode == HttpStatusCode.OK ||
                response.StatusCode == HttpStatusCode.Moved ||
                response.StatusCode == HttpStatusCode.Redirect) &&
                response.ContentType.StartsWith("image", StringComparison.OrdinalIgnoreCase)) 
            {
                using (Stream inputStream = response.GetResponseStream())
                using (Stream outputStream = File.OpenWrite(fileName))
                {
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    do
                    {
                        bytesRead = inputStream.Read(buffer, 0, buffer.Length);
                        outputStream.Write(buffer, 0, bytesRead);
                    } while (bytesRead != 0);
                }
            }
        }

【讨论】:

  • 也许你可以解释一下这段代码,以及为什么它有效?
【解决方案4】:

也可以使用 DownloadData 方法

    private byte[] GetImage(string iconPath)
    {
        using (WebClient client = new WebClient())
        {
            byte[] pic = client.DownloadData(iconPath);
            //string checkPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +@"\1.png";
            //File.WriteAllBytes(checkPath, pic);
            return pic;
        }
    }

【讨论】:

    【解决方案5】:

    从服务器或网站下载图像并将其存储在本地的最佳做法。

    WebClient client=new Webclient();
    client.DownloadFile("WebSite URL","C:\\....image.jpg");
    client.Dispose();
    

    【讨论】:

      【解决方案6】:

      您可以使用此代码

      using (WebClient client = new WebClient()) {
                          Stream stream = client.OpenRead(imgUrl);
                          if (stream != null) {
                              Bitmap bitmap = new Bitmap(stream);
                              ImageFormat imageFormat = ImageFormat.Jpeg;
                              if (bitmap.RawFormat.Equals(ImageFormat.Png)) {
                                  imageFormat = ImageFormat.Png;
                              }
                              else if (bitmap.RawFormat.Equals(ImageFormat.Bmp)) {
                                  imageFormat = ImageFormat.Bmp;
                              }
                              else if (bitmap.RawFormat.Equals(ImageFormat.Gif)) {
                                  imageFormat = ImageFormat.Gif;
                              }
                              else if (bitmap.RawFormat.Equals(ImageFormat.Tiff)) {
                                  imageFormat = ImageFormat.Tiff;
                              }
      
                              bitmap.Save(fileName, imageFormat);
                              stream.Flush();
                              stream.Close();
                              client.Dispose();
                          }
                      }
      

      项目地址:github

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-08
        • 1970-01-01
        • 1970-01-01
        • 2015-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多