Is is possible to programmaticaly save a graphic forma given URL?

S

Stacey Levine

Ok.. Maybe I am trying the wrong approach. If given a URL to a graphic, I
want to save that graphic to a local file. The approach below gets the
response, but I can't quite figure out how to save it to a file. In this
instance, a file gets created but it only contains the text
"System.Io.StreamReader" I have also tried writer.write(reader.ReadToEnd),
but the file still displays nothing.


Dim URL As String = GraphicURL

Dim request As WebRequest = WebRequest.Create(URL)

Dim response As WebResponse = request.GetResponse()

Dim reader As StreamReader = New

StreamReader(response.GetResponseStream())

Dim writer As StreamWriter = New StreamWriter("C:\temp\" & GraphicKey &
".jpg")

writer.Write(reader)

writer.Close()

reader.Close()

response.Close()


Stacey Levine
 
R

Robin Tucker

Yes, you are writing the reader, rather than writing what the reader is
reading :) Try writing reader.readtoend (or something).
 
S

Stacey Levine

I did try writer.write(reader.ReadToEnd), and the file has more data.. it
is all hex.. but it still won't open as a picture. I am not sure if I missed
writing something.
 
S

Stacey Levine

One other wierd bit.. when I save the file using the reader.ReadToEnd ..
the file has 1302 bytes.
If I right click the image and save it, it has 2257 bytes.

very very wierd
 
M

Michael C#

Try BinaryWriter/BinaryReader:

Try
Dim Request As HttpWebRequest =
HttpWebRequest.Create(http://i3.microsoft.com/h/en-us/i/SpeedPC_2_10.jpg)
Request.Timeout = 5000
Dim Response As HttpWebResponse = Request.GetResponse()
Dim myReader As BinaryReader
myReader = New BinaryReader(Response.GetResponseStream())
Dim Result() As Byte = myReader.ReadBytes(Response.ContentLength)
Dim myFileStream As New FileStream("c:\SpeedPC_2_10.jpg",
FileMode.CreateNew)
Dim myWriter As New BinaryWriter(myFileStream)
myWriter.Write(Result)
myWriter.Close()
Catch e As Exception
MessageBox.Show(e.Message, "Error Occurred")
End Try
 
M

Michael C#

You're using a regular StreamReader and StreamWriter, so it's using Default
Text encodings. You need to use BinaryReader/BinaryWriter for Binary
graphic data. See other post.
 
H

Herfried K. Wagner [MVP]

Stacey Levine said:
Ok.. Maybe I am trying the wrong approach. If given a URL to a graphic, I
want to save that graphic to a local file. The approach below gets the
response, but I can't quite figure out how to save it to a file.

Check out 'WebClient.DownloadFile'.
 
J

Jay B. Harlow [MVP - Outlook]

Stacey,
In addition to the other comments:

Don't use StreamReader & StreamWriter on binary files (such as graphic
files), as StreamReader & StreamWriter are used with Text Files.

If you simply want to copy the file, I would not even bother with
BinaryReader & BinaryWriter, as StreamReader & StreamWriter and BinaryReader
& BinaryWriter are used to parse "formatted" files, you simply want to copy
the bytes.

The "easiest" way is to use WebClient.DownloadFile as Herfried shows.
Alternatively you can use a loop, something like:

Dim URL As String = GraphicURL
Dim request As WebRequest = WebRequest.Create(URL)
Dim response As WebResponse = request.GetResponse()

Dim input As Stream = response.GetResponseStream()
Dim output As New FileStream("C:\temp\" & graphicKey & ".jpg",
FileMode.Create)

Dim count As Integer = 32 * 1024
Dim buffer(count - 1) As Byte

Do
count = input.Read(buffer, 0, count)
If count = 0 Then Exit Do
output.Write(buffer, 0, count)
Loop

input.Close()
output.Close()
response.Close()

Hope this helps
Jay

| Ok.. Maybe I am trying the wrong approach. If given a URL to a graphic, I
| want to save that graphic to a local file. The approach below gets the
| response, but I can't quite figure out how to save it to a file. In this
| instance, a file gets created but it only contains the text
| "System.Io.StreamReader" I have also tried writer.write(reader.ReadToEnd),
| but the file still displays nothing.
|
|
| Dim URL As String = GraphicURL
|
| Dim request As WebRequest = WebRequest.Create(URL)
|
| Dim response As WebResponse = request.GetResponse()
|
| Dim reader As StreamReader = New
|
| StreamReader(response.GetResponseStream())
|
| Dim writer As StreamWriter = New StreamWriter("C:\temp\" & GraphicKey &
| ".jpg")
|
| writer.Write(reader)
|
| writer.Close()
|
| reader.Close()
|
| response.Close()
|
|
| Stacey Levine
|
|
 
M

Michael C#

Alternatively, you can eliminate the "loop" and all the extra logic and code
(Dim count, Dim buffer(count - 1), If...Then..Exit Do, etc.) by using the
BinaryReader's .ReadBytes() method in conjunction with the BinaryWriter's
ability to write an entire Byte array to a file at once. I.e.,

'...
Dim Result() As Byte = myReader.ReadBytes(Response.ContentLength)
'...
myWriter.Write(Result)
'...
 
I

Inge Henriksen

The data returned is probably gzip'ed(documented in RFC1950 to RFC 1952),
you dont want to read the HTTP data as GZIP if you dont intend to unzip it
programatically.
 
J

Jay B. Harlow [MVP - Outlook]

Michael,
| Alternatively, you can eliminate the "loop" and all the extra logic and
code
| (Dim count, Dim buffer(count - 1), If...Then..Exit Do, etc.) by using the
You can do that, but I would question if you should do that! ;-)

What happens when you download a 1600 x 1200 32bit color TIFF?

Allocating such a large single block of memory may cause undue stress on the
GC & the memory requirements of your app.

A 1600 x 1200 32bit color TIFF is 5M, while the corresponding JPG is .9M
both of which seems to be an excessive size to allocate a single block.
Especially if the OP is going to be processing multiple files at a time...
Ergo my loop example. Granted the size of the buffer in the loop makes a
difference, I picked 32K, which may be too small. One should really pick a
size that exceeds most of the files involved, yet does not cause undue
stress on memory & the GC. In other words 64K or 128K might be a better
buffer, although I understand a 128K buffer would be placed in the large
memory heap which might not be a good idea...

Just a thought
Jay


| Alternatively, you can eliminate the "loop" and all the extra logic and
code
| (Dim count, Dim buffer(count - 1), If...Then..Exit Do, etc.) by using the
| BinaryReader's .ReadBytes() method in conjunction with the BinaryWriter's
| ability to write an entire Byte array to a file at once. I.e.,
|
| '...
| Dim Result() As Byte = myReader.ReadBytes(Response.ContentLength)
| '...
| myWriter.Write(Result)
| '...
|
| | > Alternatively you can use a loop, something like:
| >
| > Dim URL As String = GraphicURL
| > Dim request As WebRequest = WebRequest.Create(URL)
| > Dim response As WebResponse = request.GetResponse()
| >
| > Dim input As Stream = response.GetResponseStream()
| > Dim output As New FileStream("C:\temp\" & graphicKey & ".jpg",
| > FileMode.Create)
| >
| > Dim count As Integer = 32 * 1024
| > Dim buffer(count - 1) As Byte
| >
| > Do
| > count = input.Read(buffer, 0, count)
| > If count = 0 Then Exit Do
| > output.Write(buffer, 0, count)
| > Loop
| >
| > input.Close()
| > output.Close()
| > response.Close()
| >
|
|
 
C

Cor Ligthert [MVP]

The "easiest" way is to use WebClient.DownloadFile as Herfried shows.

And extremely fast way,

And if needed a progressbar, because of slow connections. Than Jay's method
because that is the negative point from "DownloadFile" that you can AFAIK
not use that with it.

:)

Cor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top