代码之家  ›  专栏  ›  技术社区  ›  Geeth

从.NET/C中的站点下载图像#

  •  62
  • Geeth  · 技术社区  · 14 年前

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

    代码:

    方法1:

    WebRequest requestPic = WebRequest.Create(imageUrl);
    
    WebResponse responsePic = requestPic.GetResponse();
    
    Image webImage = Image.FromStream(responsePic.GetResponseStream()); // Error
    
    webImage.Save("D:\\Images\\Book\\" + fileName + ".jpg");
    

    方法2:

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

    编辑:

    流具有以下语句:

          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
    
    5 回复  |  直到 5 年前
        1
  •  159
  •   Fredrik Mörk    14 年前

    不需要涉及任何图像类,只需调用 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);
            }
        }
    }
    

    简言之,它请求文件,验证响应代码是否是 OK , Moved Redirect 而且 ContentType 是一个图像。如果这些条件为真,则下载文件。

        2
  •  26
  •   germankiwi    12 年前

    我在一个项目中使用了上面的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时遇到异常
    • 返回布尔值
        3
  •  2
  •   Alexander Nikolaev    7 年前

    也可以使用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;
            }
        }
    
        4
  •  0
  •   CodeNinja    8 年前
            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);
                    }
                }
            }
    
        5
  •  0
  •   Mohamad-Al-Ibrahim    5 年前

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

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