воскресенье, 7 декабря 2008 г.

Get Image from HTTP URL - .NET, ASP.NET

Overview:
Create image object and save it into file by URL.

Depending on your needs it can be two solutions:


Solution 1 - when you need to make some manipulations with the image object (resize, crop, etc) before saving to disk:
1. get Stream from URL using WebRequest class
2. Create Image object from stream using System.Drawing.Image.FromStream method
3. Make manipulations with image object
3. Save image to file on disk using System.Drawing.Image.Save method


Solution 2 - when you need to get image from Url and just save it to disk as-is.
1. get Stream from URL using WebRequest class
2. Create new file and stream for it
3. Get data from Webrequest's stream in binary format and put this data into file stream.

Below is the full code for each of the solutions


Code for solution 1:

using System.Net;
using System.IO;

public bool getImageByUrl(string url, string filename)
{

WebResponse response = null;
Stream remoteStream = null;
StreamReader readStream = null;
try
{
WebRequest request = WebRequest.Create(url);
if (request != null)
{
response = request.GetResponse();
if (response != null)
{
remoteStream = response.GetResponseStream();

readStream = new StreamReader(remoteStream);

System.Drawing.Image img = System.Drawing.Image.FromStream(remoteStream);

if (img == null)
return false;

// YOUR CODE HERE: make manipulations with the image object


// save image to disk
img.Save( filename, System.Drawing.Imaging.ImageFormat.Jpeg );
img.Dispose();
}
}
}
finally
{
if (response != null) response.Close();
if (remoteStream != null) remoteStream.Close();
if (readStream != null) readStream.Close();
}

return true;
}


code for solution 2

public static bool saveImageByUrlToDisk(string url, string filename, out string imageType)
{
imageType = "";

WebResponse response = null;
Stream remoteStream = null;
StreamReader readStream = null;
try
{
WebRequest request = WebRequest.Create(url);
if (request != null)
{
response = request.GetResponse();
if (response != null)
{
remoteStream = response.GetResponseStream();


// analyze image type, image extension
string content_type = response.Headers["Content-type"];

imageType = content_type;

if (content_type == "image/jpeg" || content_type == "image/jpg")
{
imageType = "jpg";
}
else if (content_type == "image/png")
{
imageType = "png";
}
else if (content_type == "image/gif")
{
imageType = "gif";
}
else
{
imageType = "";

return false;
}


readStream = new StreamReader(remoteStream);

Stream fw = File.Open(filename, FileMode.Create);

//
byte[] buf = new byte[256];
int count = remoteStream.Read(buf, 0, 256);
while (count > 0)
{
fw.Write(buf, 0, count);

count = remoteStream.Read(buf, 0, 256);
}

fw.Close();
}
}
}
finally
{
if (response != null) response.Close();
if (remoteStream != null) remoteStream.Close();
}

return true;
}

9 комментариев:

Bruce комментирует...

Awesome, saved my day! Thanks!

Анонимный комментирует...

Can you provide this in a vb example?

Thanks~

Анонимный комментирует...

Can you show how your doing this using vb?

Thanks~

mxdev комментирует...

VB variant for solution #2.
(I hope this code works but I didn't try this code )

Public Function saveImageByUrlToDisk(ByVal url As String, ByVal filename As String, ByVal imageType As String) As Boolean

imageType = ""

Dim response As System.Net.WebResponse = Nothing
Dim remoteStream As System.IO.Stream = Nothing
Dim readStream As System.IO.StreamReader = Nothing

Dim request As System.Net.WebRequest = Nothing

request = System.Net.WebRequest.Create(url)


response = request.GetResponse()

remoteStream = response.GetResponseStream()


Dim content_type As String = response.Headers("Content-type")

imageType = content_type

If content_type = "image/jpeg" Or content_type = "image/jpg" Then
imageType = "jpg"
ElseIf content_type = "image/png" Then
imageType = "png"
ElseIf content_type = "image/gif" Then
imageType = "gif"
Else
imageType = ""
Return False

End If



readStream = New System.IO.StreamReader(remoteStream)

Dim fw As System.IO.Stream = System.IO.File.Open(filename, System.IO.FileMode.Create)

Dim buf() As Byte = New Byte() {}
ReDim buf(256)

Dim count As Integer = remoteStream.Read(buf, 0, 256)

While (count > 0)
fw.Write(buf, 0, count)
count = remoteStream.Read(buf, 0, 256)
End While

fw.Close()



response.Close()
remoteStream.Close()


Return True


End Function

Анонимный комментирует...

Many thanks. But, I was looking for a VB variant for solution #1.

Love your work!

Анонимный комментирует...

Is there a way to not save the file to the drive

Dim fw As System.IO.Stream = System.IO.File.Open(filename, System.IO.FileMode.Create)

but save it to a BLOB in a database?

mxdev комментирует...

I advice you not to store BLOB data in database. Microsoft suggests to store data in native format. It means - store path to file (string) in database and store the file on disk (jpg, doc, pdf, etc).
There is no good functions in SQL-language (as i know about SQL Server) to insert/update BLOB data - you have to update the data by small parts of 8Kb.

mxdev комментирует...

VB.Net version of solution #1 to save image file to disk:



Public Function getImageByUrl(ByVal url As String, ByVal filename As String) As Boolean

Dim response As System.Net.WebResponse = Nothing
Dim remoteStream As System.IO.Stream = Nothing
Dim readStream As System.IO.StreamReader = Nothing


Dim request As System.Net.WebRequest = Nothing

request = System.Net.WebRequest.Create(url)


response = request.GetResponse()

remoteStream = response.GetResponseStream()

readStream = New System.IO.StreamReader(remoteStream)

Dim img As System.Drawing.Image = System.Drawing.Image.FromStream(remoteStream)





img.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg)
img.Dispose()

response.Close()
remoteStream.Close()
readStream.Close()


Return True

End Function

Juan Manuel комментирует...

Great article! it works great! thanks and regards from argentina.
Juan Manuel