Download and show an image from a URL in background - c#

How to download & show an image from a URL using asp.net
e.g. I have a page ShowImage.aspx
When I call this page it should show image(from Response Stream) from external URL
https://appharbor.com/assets/images/stackoverflow-logo.png
with Response.ContentType = "Image/png"
SOLVED ON MY OWN
protected void Page_Load(object sender, EventArgs e)
{
WebRequest req = WebRequest.Create("https://appharbor.com/assets/images/stackoverflow-logo.png");
WebResponse response = req.GetResponse();
Stream stream = response.GetResponseStream();
Byte[] buffer = null;
Response.Clear();
Response.ContentType = "image/png";
Response.AddHeader("Content-Length", response.ContentLength.ToString());
int bytesRead = 0;
do
{
buffer = new Byte[4096];
bytesRead = stream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
{
Response.OutputStream.Write(buffer,0,bytesRead);
}
} while (bytesRead > 0);
Response.End();
}
REF: http://forums.asp.net/t/1401931.aspx/1

You can simply use the Image.ImageUrl property of Image control
<asp:Image id="img1" runat="server" ImageUrl="https://appharbor.com/assets/images/stackoverflow-logo.png" />
If you want to set Image url from server side (code behind)
img1.ImageUrl = "http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.image.imageurl.aspx";
If you use WebRequest to get the Image string from url.
WebRequest req = WebRequest.Create("https://appharbor.com/assets/images/stackoverflow-logo.png");
WebResponse response = req.GetResponse();
Stream stream = response.GetResponseStream();
System.Drawing.Image image = System.Drawing.Image.FromStream(stream);
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ms.WriteTo(Response.OutputStream);
}

public class Service1 : IService1
{
public Stream GetImage()
{
WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
using(WebClient Client = new WebClient())
{
using(StreamReader Reader = new StreamReader(Client.OpenRead("FILE URL")))
{
try
{
string Contents = Reader.ReadToEnd();
Reader.Close();
return Contents;
}
catch
{
return string.Empty;
}
}
}
}
}

Related

ASP.Net FTP Upload Not Working

I am trying to upload an image file via FTP in ASP.Net. The image file is uploaded to correct location but when I read or download it, it's corrupt. My code is given below
protected void FTPUpload()
{
//FTP Server URL.
string ftp = ConfigurationManager.AppSettings.Get("FTPServer");
//FTP Folder name.
string ftpFolder = "images/logos/";
//FTP Credentials
string ftpUsername = ConfigurationManager.AppSettings.Get("FTPUsername");
string ftpPassword = ConfigurationManager.AppSettings.Get("FTPPassword");
byte[] fileBytes = null;
//Read the FileName and convert it to Byte array.
string fileName = Path.GetFileName(fuLogo.FileName);
using (StreamReader fileStream = new StreamReader(fuLogo.PostedFile.InputStream))
{
fileBytes = Encoding.UTF8.GetBytes(fileStream.ReadToEnd());
fileStream.Close();
}
try
{
//Create FTP Request.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftp + ftpFolder + fileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
//Enter FTP Server credentials.
request.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
request.ContentLength = fileBytes.Length;
request.UsePassive = true;
request.UseBinary = true;
request.ServicePoint.ConnectionLimit = fileBytes.Length;
request.EnableSsl = false;
using (var requestStream = request.GetRequestStream())
{
CopyStream(fuLogo.PostedFile.InputStream, requestStream);
}
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
//lblMessage.Text += fileName + " uploaded.<br />";
response.Close();
}
catch (WebException ex)
{
throw new Exception((ex.Response as FtpWebResponse).StatusDescription);
}
}
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[1024000];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
}
Am I missing something? The file is uploaded perfectly but for some reason it gets corrupted.
This part smells:
using (StreamReader fileStream = new StreamReader(fuLogo.PostedFile.InputStream))
{
fileBytes = Encoding.UTF8.GetBytes(fileStream.ReadToEnd());
fileStream.Close();
}
There should be no reason to first copy image to array (and use default text encoding/UTF8 decoding in the meantime) - just do stream-to-stream copy(see How do I copy the contents of one stream to another?):
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[32768];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write (buffer, 0, read);
}
}
So the ftp upload should be just
using (var requestStream = request.GetRequestStream())
{
CopyStream(fuLogo.PostedFile.InputStream, requestStream);
// no need to requestStream.Close(); - using does that for you
}

Unable to get full image from server

I have a C# windows form application which downloads file from a url(asp.net application) but it is not returning full image lets say image is of 780kb the file that windows form creates is 381 bytes exactly.
I am not able to figure out the issue. Please help.
The code i am using for download is:
public bool getFileFromURL(string url, string filename)
{
long contentLength = 0;
Stream stream = null;
try
{
WebRequest req = WebRequest.Create(url);
WebResponse response = req.GetResponse();
stream = response.GetResponseStream();
contentLength = response.ContentLength;
// Transfer the file
byte[] buffer = new byte[10 * 1024]; // 50KB at a time
int numBytesRead = 0;
long totalBytesRead = 0;
using (FileStream fileStream = new FileStream(filename, FileMode.Create))
{
using (BinaryWriter fileWriter = new BinaryWriter(fileStream))
{
while (stream.CanRead)
{
numBytesRead = stream.Read(buffer, 0, buffer.Length);
if (numBytesRead == 0) break;
totalBytesRead += numBytesRead;
fileWriter.Write(buffer, 0, numBytesRead);
}
fileWriter.Close();
}
fileStream.Close();
}
stream.Close();
response.Close();
req.Abort();
return true;
}
catch (Exception)
{
return false;
}
}
This is my asp.net app code:
using (PortalEntities db = new PortalEntities())
{
PortalModel.Command command = db.Commands.SingleOrDefault(c => c.id == id);
var filePath = Server.MapPath("~/Uploads/"+command.arguments);
if (!File.Exists(filePath))
return;
var fileInfo = new System.IO.FileInfo(filePath);
Response.ContentType = "image/jpg";
Response.AddHeader("Content-Disposition", String.Format("attachment;filename=\"{0}\"", filePath));
Response.AddHeader("Content-Length", fileInfo.Length.ToString());
Response.WriteFile(filePath);
Response.End();
}
That's an awful lot of code to write some bytes out to a file from a web response. How about something like this (.NET 4+):
public static bool GetFileFromURL(string url, string filename)
{
try
{
var req = WebRequest.Create(url);
using (Stream output = File.OpenWrite(filename))
using (WebResponse res = req.GetResponse())
using (Stream s = res.GetResponseStream())
s.CopyTo(output);
return true;
}
catch
{
return false;
}
}
You can download image in more elegant way, it was discussed before here Unable to locate FromStream in Image class
And use File.WriteAllBytes Method to save the byte array as a file, more info at
http://msdn.microsoft.com/en-us/library/system.io.file.writeallbytes(v=vs.110).aspx
So all your client code can be replaced with
public void getFileFromURL(string url, string filename)
{
using (var webClient = new WebClient())
{
File.WriteAllBytes(filename,webClient.DownloadData(url));
}
}
Dude, why are you not using WebClient.DownloadFileAsync?
private void DownloadFile(string url, string path)
{
using (var client = new System.Net.WebClient())
{
client.DownloadFileAsync(new Uri(url), path);
}
}
That's pretty much it, but this method can't download over 2GB. But i don't think the image is that big xD.
Hope it helps!

Post image from Windows Phone Application to PHP

I am trying to develop an application for Windows Phone 7 which uploads a selected picture (from the picture chooser task) to a server with the use of PHP.
I am trying to use HttpWebRequest in order to do this. And the data is posted successfully too.
The Problem that I am facing is that the image is required to be encoded to base64 before posting.
And, I am not able to encode it properly.
This is my C# code so far:
public partial class SamplePage : PhoneApplicationPage
{
public SamplePage()
{
InitializeComponent();
}
PhotoChooserTask selectphoto = null;
private void SampleBtn_Click(object sender, RoutedEventArgs e)
{
selectphoto = new PhotoChooserTask();
selectphoto.Completed += new EventHandler<PhotoResult>(selectphoto_Completed);
selectphoto.Show();
}
void selectphoto_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
BinaryReader reader = new BinaryReader(e.ChosenPhoto);
image1.Source = new BitmapImage(new Uri(e.OriginalFileName));
txtBX.Text = e.OriginalFileName;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://"+QR_Reader.MainPage.txtBlck+"/beamer/saveimage.php");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string str = BitmapToByte(image1);
MessageBox.Show(str);
string postData = String.Format("image={0}", str);
// Getting the request stream.
request.BeginGetRequestStream
(result =>
{
// Sending the request.
using (var requestStream = request.EndGetRequestStream(result))
{
using (StreamWriter writer = new StreamWriter(requestStream))
{
writer.Write(postData);
writer.Flush();
}
}
// Getting the response.
request.BeginGetResponse(responseResult =>
{
var webResponse = request.EndGetResponse(responseResult);
using (var responseStream = webResponse.GetResponseStream())
{
using (var streamReader = new StreamReader(responseStream))
{
string srresult = streamReader.ReadToEnd();
}
}
}, null);
}, null);
} // end of taskresult == OK
} // end of select photo completed
private Stream ImageToStream(Image image1)
{
WriteableBitmap wb = new WriteableBitmap(400, 400);
wb.Render(image1, new TranslateTransform { X = 400, Y = 400 });
wb.Invalidate();
Stream myStream = new MemoryStream();
wb.SaveJpeg(myStream, 400, 400, 0, 70);
return myStream;
}
private string BitmapToByte(Image image) //I suspect there is something wrong here
{
Stream photoStream = ImageToStream(image);
BitmapImage bimg = new BitmapImage();
bimg.SetSource(photoStream); //photoStream is a stream containing data for a photo
byte[] bytearray = null;
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap wbitmp = new WriteableBitmap(bimg);
wbitmp.SaveJpeg(ms, wbitmp.PixelWidth, wbitmp.PixelHeight, 0, 100);
bytearray = ms.ToArray();
}
string str = Convert.ToBase64String(bytearray);
return str;
}
}
The BitmapToByte function is used to convert the image to base64 string.
And, the ImageToStream function is used to convert it to stream.
Now, I seriously suspect that there is something wrong in these two functions.
Further, I'm getting exactly the same base64 string for every image. Yes, I'm getting exactly same base64 string irrespective of what image I'm selecting. This is very weird.
I don't know what is wrong with this.
I've uploaded a text file here: http://textuploader.com/?p=6&id=vWZy
It contains that base64 string.
On, the server side, the PHP is accepting the postdata successfully and the decoding is working perfectly too (I decoded some base64 strings manually to ensure this).
Only problem I'm facing is base64 encoding.
Please help me.
EDIT
I've made the following changes in the ImageToStream and BitmapToByte functions:
private MemoryStream ImageToStream(Image image1)
{
WriteableBitmap wb = new WriteableBitmap(400, 400);
wb.Render(image1, new TranslateTransform { X = 400, Y = 400 });
wb.Invalidate();
MemoryStream myStream = new MemoryStream();
wb.SaveJpeg(myStream, 400, 400, 0, 70);
return myStream;
}
private string BitmapToByte(Image image)
{
MemoryStream photoStream = ImageToStream(image);
byte[] bytearray = photoStream.ToArray();
string str = Convert.ToBase64String(bytearray);
return str;
}
You BitmapToByte method is tremendously overcomplicated. Change ImageToStream to return a MemoryStream and:
private string BitmapToByte(Image image)
{
MemoryStream photoStream = ImageToStream(image);
byte[] bytearray = photoStream.ToArray();
string str = Convert.ToBase64String(bytearray);
return str;
}

How to get a photo from Server and display it in Image Control for Wp7

I am using the below code. I just dont know why it is not working. The error msg is : Unspecified error on this : bmp.SetSource(ms).
I am not familiar with HttpWebRequest for Wp7. Would appreciate your help to solve this problem. Thanks.
enter code here
private void LoadPic()
{
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(#"http://xxxxxx/MyImage.jpg");
NetworkCredential creds = new NetworkCredential("Username", "Pwd");
req.Credentials = creds;
req.Method = "GET";
req.BeginGetResponse(new AsyncCallback(GetStatusesCallBack), req);
}
public void GetStatusesCallBack(IAsyncResult result)
{
try
{
HttpWebRequest httpReq = (HttpWebRequest)result.AsyncState;
HttpWebResponse response = (HttpWebResponse)httpReq.EndGetResponse(result);
Stream myStream = response.GetResponseStream();
int len = (int)myStream.Length;
byte[] byt = new Byte[len];
myStream.Read(byt, 0, len);
myStream.Close();
MemoryStream ms = new MemoryStream(byt);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(ms);
image1.Source = bmp;
});
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Is it necessary to copy the response stream to a byte array and then to a MemoryStream? If not, you can just do the following:
Stream myStream = response.GetResponseStream();
Deployment.Current.Dispatcher.BeginInvoke(() => {
BitmapImage bmp = new BitmapImage();
bmp.SetSource(myStream);
image1.Source = bmp;
});
If you have to do the copy for some reason, you will need to fill the buffer in a loop:
Stream myStream = response.GetResponseStream();
int contentLength = (int)myStream.Length;
byte[] byt = new Byte[contentLength];
for (int pos = 0; pos < contentLength; )
{
int len = myStream.Read(byt, pos, contentLength - pos);
if (len == 0)
{
throw new Exception("Upload aborted.");
}
pos += len;
}
MemoryStream ms = new MemoryStream(byt);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
// same as above
});
Second part adapted (slightly) from C# bitmap images, byte arrays and streams!.

Stream a PDF to a web page failing

I have a URL to a PDF and I want to serve up the PDF to my page viewer.
I can successfully (I think) retrieve the PDF file. Then when I do the Response.BinaryWrite() I get a "The file is damaged and could not be repaired" error from the adobe reader.
Here's the code I have:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
byte[] output = DoWork("Http://localhost/test.pdf");
Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "inline; filename=MyPDF.PDF");
Response.AddHeader("content-length", output.Length.ToString());
Response.BinaryWrite(output);
Response.End();
}
}
public byte[] DoWork(string requestUrl)
{
byte[] responseData;
HttpWebRequest req = null;
HttpWebResponse resp = null;
StreamReader strmReader = null;
try
{
req = (HttpWebRequest)WebRequest.Create(requestUrl);
using (resp = (HttpWebResponse)req.GetResponse())
{
byte[] buffer = new byte[resp.ContentLength];
BinaryReader reader = new BinaryReader(resp.GetResponseStream());
reader.Read(buffer, 0, buffer.Length);
responseData = buffer;
}
}
finally
{
if (req != null)
{
req = null;
}
if (resp != null)
{
resp.Close();
resp = null;
}
}
return responseData;
}
Apparently, I need to use ReadBytes() For some reason, when reading a PDF from a URL, You don't get all of the bytes that you requested.
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
byte[] output = DoWork("Http://localhost/test.pdf");
Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment");
Response.AddHeader("content-length", output.Length.ToString());
Response.BinaryWrite(output);
Response.End();
}
}
public byte[] DoWork(string requestUrl)
{
byte[] responseData;
HttpWebRequest req = null;
HttpWebResponse resp = null;
StreamReader strmReader = null;
try
{
req = (HttpWebRequest)WebRequest.Create(requestUrl);
using (resp = (HttpWebResponse)req.GetResponse())
{
byte[] buffer = new byte[resp.ContentLength];
using (BinaryReader reader = new BinaryReader(resp.GetResponseStream()))
{
buffer = reader.ReadBytes(buffer.Length);
reader.Close();
}
responseData = buffer;
}
}
finally
{
if (req != null)
{
req = null;
}
if (resp != null)
{
resp.Close();
resp = null;
}
}
return responseData;
}
Try saving the resulting file to your disk. Then open the file with a text editor. Maybe there are some errors in your script/source file.
You can also try to use FileStream the read the file
string strPath = Request.PhysicalApplicationPath
+ "\\document\\Test.pdf";
FileStream fStream = new FileStream
(strPath, FileMode.Open, FileAccess.Read);
StreamReader sReader = new StreamReader(fStream);
Try to flush the response after the binary write...
Response.BinaryWrite(output);
Response.Flush();
Response.End();
Alternatively, instead of inline, try to output the PDF as an attachment:
Response.AddHeader("Content-Disposition", "attachment;filename=MyPDF.PDF");
When I did this in Perl the other day (as a quick hack for our intranet), the crux of the script was:
binmode(STDOUT);
print "Content-type: application/pdf\n\n";
binmode(FILE);
print <FILE>;
close(FILE);
The key points being to make sure that the input and output streams are in binary mode, i.e. as you've found, the PDF needs to be interpreted as binary data throughout the chain.
You might be able to simplify your code quite a bit by using the WebClient class
Here's the MSDN documentation. Its not as cumbersome as the lower level HttpWebRequest class.

Categories