Get an Image from a URL but it is not loaded completely

心不动则不痛 提交于 2019-12-13 01:35:27

问题


I'm trying to get an image from an URL but when I save it to a file it is half of the actual image! I have searched many sites and solutions like HttpWebRequest.BeginGetResponse because I thought it is because I must buffer the data but it did not work. I don't know which part of my code is wrong and making this problem!:(

This is the code which retrieve image from URL:

 public static Bitmap GetImageFromUrl(string url)
    {
        string RefererUrl = string.Empty;
        int TimeoutMs = 22 * 1000;
        string requestAccept = "*/*";
        string UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7";

        Bitmap img = null;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

        request.UserAgent = UserAgent;
        request.Timeout = TimeoutMs;
        request.ReadWriteTimeout = TimeoutMs * 6;
        request.Accept = requestAccept;

        if (!string.IsNullOrEmpty(RefererUrl))
        {
            request.Referer = RefererUrl;
        }

        try
        {
            WebResponse wResponse = request.GetResponse();
            using (HttpWebResponse response = wResponse as HttpWebResponse)
            {
                Stream responseStream = response.GetResponseStream();
                img = new Bitmap(responseStream);
                response.Close();
            }
        }
        catch (Exception)
        {
        }
        return img;
    }

This the code which saves the image in File:

        byte[] imgBytes = tile.Image;
        using (MemoryStream ms = new MemoryStream(imgBytes))
        {
            using (Image img = Image.FromStream(ms))
            {
                ms.Dispose();
                Bitmap tempBmp = new Bitmap(img);
                img.Dispose();

                string activeDir = Environment.CurrentDirectory;
                string newPath = System.IO.Path.Combine(activeDir, "Images");
                System.IO.Directory.CreateDirectory(newPath);

                newPath = System.IO.Path.Combine(newPath, tile.TileType.ToString());
                System.IO.Directory.CreateDirectory(newPath);

                newPath = System.IO.Path.Combine(newPath, tile.Zoom.ToString());
                System.IO.Directory.CreateDirectory(newPath);

                newPath = System.IO.Path.Combine(newPath, tile.X.ToString());
                System.IO.Directory.CreateDirectory(newPath);

                newPath = System.IO.Path.Combine(newPath, tile.Y.ToString());
                System.IO.Directory.CreateDirectory(newPath);

                string newFileName = "tile.png";
                newPath = System.IO.Path.Combine(newPath, newFileName);

                tempBmp.Save(newPath, ImageFormat.Png);
                tempBmp.Dispose();

回答1:


Your code seems overcomplicated, do you really need read image and then resave it? Why can't you just save downloaded image directly, like this:

        public static void GetImageFromUrl(string url)
    {
        string RefererUrl = string.Empty;
        int TimeoutMs = 22 * 1000;
        string requestAccept = "*/*";
        string UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7";

      //  Bitmap img = null;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

        request.UserAgent = UserAgent;
        request.Timeout = TimeoutMs;
        request.ReadWriteTimeout = TimeoutMs * 6;
        request.Accept = requestAccept;

        if (!string.IsNullOrEmpty(RefererUrl))
        {
            request.Referer = RefererUrl;
        }

        try
        {
            WebResponse wResponse = request.GetResponse();
            using (HttpWebResponse response = wResponse as HttpWebResponse)
            {
                Stream responseStream = response.GetResponseStream();
                BinaryReader br = new BinaryReader(responseStream);

                FileStream fs = new FileStream(@"c:\pst\1.jpg", FileMode.Create, FileAccess.Write);

                const int buffsize = 1024;
                byte[] bytes = new byte[buffsize];
                int totalread = 0;

                int numread = buffsize;
                while (numread != 0)
                {
                    // read from source
                    numread = br.Read(bytes, 0, buffsize);
                    totalread += numread;

                    // write to disk
                    fs.Write(bytes, 0, numread);
                }

                br.Close();
                fs.Close();


                response.Close();
            }
        }
        catch (Exception)
        {
        }
    } 

You should of course split it into methods and set proper return values




回答2:


You should not call Dispose() on ms and img objects until you have saved it to the file at the end.

They are even declared in their own using sections, so you don't need to call Dispose() on them at all, because it is automatically disposed at the exit of each used block (this is really the main reason of using using in the first place!).



来源:https://stackoverflow.com/questions/9462256/get-an-image-from-a-url-but-it-is-not-loaded-completely

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!