Save image to disk from an url

rfazendeiro

Centurion
Joined
Mar 8, 2004
Messages
110
I'm having a little problem saving a image to disk. I get the image from a url, and want to save that to disk.

So i just do a HttpWebRequest to the image url, get the stream and convert it to an image and save to disk. This code here is working for jpg's but its does not work with GIF. also there are somethings that would like to change. the code is this:

PHP:
public  static String HttpRequest(String serverImgURL, String physicalPath, String extention)
        {
            String siteImgURL;
            HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(serverImgURL);

            HttpWebResponse loWebResponse = (HttpWebResponse)loHttp.GetResponse();

            Encoding enc = Encoding.GetEncoding("ISO-8859-1");            

            StreamReader loResponseStream = new StreamReader(loWebResponse.GetResponseStream(), enc);

            String lcHtml = loResponseStream.ReadToEnd();

            loWebResponse.Close();
            loResponseStream.Close();

            String imageName = serverImgURL.Substring(serverImgURL.LastIndexOf("/") + 1, serverImgURL.Length - serverImgURL.LastIndexOf("/") - 1);
            siteImgURL = ConvertToImage(lcHtml, physicalPath, imageName, extention);

            return siteImgURL;
        }

private static String ConvertToImage(String stringImage, String physicalPath, String imageName, String extention)
        {
            string imageurl = string.Empty;

            if (stringImage.Length > 0)
            {
                Byte[] bitmapData;
                bitmapData = ToByteArray(stringImage);
                MemoryStream streamBitmap = new MemoryStream(bitmapData);
                Bitmap bitImage = new Bitmap(Image.FromStream(streamBitmap));

                String fotoPath;
                fotoPath = physicalPath + "\\" + imageName;

                if (extention.ToLower() == "jpg")
                    bitImage.Save(fotoPath, ImageFormat.Jpeg);
                else
                    bitImage.Save(fotoPath, ImageFormat.Gif);
            }

            return imageurl;
        }

public static Byte[] ToByteArray(String StringToConvert)
        {
            Encoding encoding = Encoding.GetEncoding("ISO-8859-1");
            Byte[] ByteArray = encoding.GetBytes(StringToConvert);

            return ByteArray;
        }


my problem is that this code does actually work for JPG. But when i try to get a GIF i get an exception when tring to save to disk. Any ideia why?

Code:
bitImage.Save(fotoPath, ImageFormat.Gif);
{"A generic error occurred in GDI+."}

Exception:
Code:
System.Runtime.InteropServices.ExternalException was unhandled by user code
  Message="A generic error occurred in GDI+."
  Source="System.Drawing"
  ErrorCode=-2147467259
 
Not sure why the error is being thrown, however if you are just wanting to save a copy you could just save the raw bytes to disk - you don't need to create an image instance and then save that.
 
i need to use the imagem and show it on a webpage after. Thats why i dont just store the bytes. I cant understand this error and debugging it seems almost impossible.

any help is welcome.

thank you
 
I haven't checked but there is a chance that creating an image and then saving it could result in the image being compressed again - which in the case of a jpeg will reduce the quality, saving the raw bytes locally and then either creating an image from that or the original byte stream would prevent this.

It could also be down to restrictions of the gif format - depending on the original image you could be attempting something that just isn't supported.
 
well i've been searching the web and came up with this

PHP:
public  static String Cache(String serverImgURL, String physicalPath, String extention)
        {
            String siteImgURL;

            HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(serverImgURL);
            HttpWebResponse loWebResponse = (HttpWebResponse)loHttp.GetResponse();

            MemoryStream memStream = new MemoryStream();

            using (Stream responseStream = loWebResponse.GetResponseStream())
            {
                byte[] buffer = new byte[0x1000];
                int bytes;
                while ((bytes = responseStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    memStream.Write(buffer, 0, bytes);
                }
            }

            loWebResponse.Close();

            String imageName = serverImgURL.Substring(serverImgURL.LastIndexOf("/") + 1, serverImgURL.Length - serverImgURL.LastIndexOf("/") - 1);
            siteImgURL = ToImage(memStream, physicalPath, imageName, extention);

            return siteImgURL;
        }


private static String ToImage(MemoryStream streamBitmap, String physicalPath, String imageName, String extention)
        {
            string imageurl = string.Empty;

            Bitmap bitImage = (Bitmap) Bitmap.FromStream(streamBitmap);

            String fotoPath;
            fotoPath = physicalPath + "\\" + imageName;

            if (extention.ToLower() == "jpg")
                bitImage.Save(fotoPath, ImageFormat.Jpeg);
            else
                bitImage.Save(fotoPath, ImageFormat.Gif);


            return imageurl;
        }

I had some mesure of success with this aproach. I tried Gif's and jpg's from diferente websites and was able to save them to disk. From the look of it i was able to keep the quality of the image.

But (there's always a but ;)) when i try the same from the server i'm using to store the images (i dont have any control on how they are stored) the error on the gif's still exist.

I'm not very sure about this code. Is there anyway to optimize it?

PHP:
MemoryStream memStream = new MemoryStream(); 

            using (Stream responseStream = loWebResponse.GetResponseStream()) 
            { 
                byte[] buffer = new byte[0x1000]; 
                int bytes; 
                while ((bytes = responseStream.Read(buffer, 0, buffer.Length)) > 0) 
                { 
                    memStream.Write(buffer, 0, bytes); 
                } 
            }
 
Back
Top