Converting Stream to byte array after asynchronously downloading in Windows Phone - c#

I am asynchronously downloading images from one web site.And I want to save list of images into IsolatedStorage. And stream is not serializable, so I have to convert it to byte array. But it is not reading Stream in while loop in ReadFully() method.
Here is how I am trying to download images:
HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
request.Headers["Referer"] = "http://www.website.com";
request.BeginGetResponse((result) =>
{
Stream imageStream = request.EndGetResponse(result).GetResponseStream();
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
// Set stream as the source of image
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.CreateOptions = BitmapCreateOptions.BackgroundCreation;
bitmapImage.SetSource(imageStream);
image.Source = bitmapImage;
// Convert stream to byte array and save in the custom list with the uri of the image
ls.Add(new DownloadedImages() { Image = ReadFully(imageStream), URI = uri });
ds.SaveMyData(ls, "BSCImages");
});
}, null);
And here is the method for converting stream to byte array:
public static byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[input.Length];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
Update:
It is not getting inside the while loop. So the byte array is always empty.

Because you are consuming the stream imageStream in creating bitmapImage before passing to ReadFully.
First get the byte[], then use it to form the image and to pass to new DownloadedImages()

Related

Convert bitmapimage into byte array

I am trying to convert bitmap Image to Byte array. I have select all the image by using MediaLibrary class and added it into a list of bitmap images. Here is my code
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!store.DirectoryExists("ImagesZipFolder"))
{
store.CreateDirectory("ImagesZipFolder");
for (int i = 0; i < imgname.Count(); i++)
{
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(#"ImagesZipFolder\" + imgname[i], System.IO.FileMode.CreateNew, store))
{
byte[] bytes = null;
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap wBitmap = new WriteableBitmap(ImgCollection[i]);
wBitmap.SaveJpeg(ms, wBitmap.PixelWidth, wBitmap.PixelHeight, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
bytes = ms.GetBuffer();
stream.Write(bytes, 0, bytes.Length);
}
// byte[] bytes = Encoding.UTF8.GetBytes(imgname[i]);//new byte[ImgCollection[i].PixelWidth * ImgCollection[i].PixelHeight * 4];
// stream.Write(bytes, 0, bytes.Length);
}
}
}
else {
directory = true;
}
}
Basically what I am trying to do is, selecting all images or photo from device and create a zip file of that images. I was successful in creating a zip file of images. When I extract that file there is some images, but the problem is when I double click on image, I can't see that image. I think the problem is in reading the bytes of image. I am not getting what's wrong? Is my code is correct ?
Perhaps you can try the below. I know this code maintains the image, so if you have no luck using this, you may have a different issue.
// Convert the new image to a byte[]
ImageConverter converter = new ImageConverter();
byte[] newBA = (byte[])converter.ConvertTo(newImage, typeof(byte[]));
The ImageConverter is of the System.Drawing namespace.
Update:
http://msdn.microsoft.com/en-GB/library/system.windows.media.imagesourceconverter.convertto.aspx
You should be able to use this in place of the System.Drawing type I suggested.
There is no need to save the WriteableBitmap to a MemoryStream and then copy it to an IsolatedStorageFileStream. Just save the bitmap directly to the IsolatedStorageFileStream.
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(#"ImagesZipFolder\" + imgname[i], System.IO.FileMode.CreateNew, store))
{
WriteableBitmap wBitmap = new WriteableBitmap(ImgCollection[i]);
wBitmap.SaveJpeg(stream, wBitmap.PixelWidth, wBitmap.PixelHeight, 0, 100);
}
This will allow you to save on memory as well. If you really want to save memory, you could reuse the WriteableBitmap.

Converting image to base64

I have the following code to convert image to base64:
private void btnSave_Click(object sender, RoutedEventArgs e)
{
StreamResourceInfo sri = null;
Uri uri = new Uri("Checked.png", UriKind.Relative);
sri = Application.GetResourceStream(uri);
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(sri.Stream);
WriteableBitmap wb = new WriteableBitmap(bitmap);
MemoryStream ms = new MemoryStream();
wb.SaveJpeg(ms, bitmap.PixelWidth, bitmap.PixelHeight, 0, 100);
byte[] imageBytes = ms.ToArray();
base64 = System.Convert.ToBase64String(imageBytes);
}
And the following code to get Bitmap image form base 64:
public static BitmapImage base64image(string base64string)
{
byte[] fileBytes = Convert.FromBase64String(base64string);
using (MemoryStream ms = new MemoryStream(fileBytes, 0, fileBytes.Length))
{
ms.Write(fileBytes, 0, fileBytes.Length);
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(ms);
return bitmapImage;
}
}
So when i convert and deconvert it is blank.
I know that deconverter works, because, when i give him exact string:
string base64="iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAQAAABLCVATAAACH0lEQVR42q3WoZKrMBQGYGRkIpHEoY9DMrh1nUGtzxPcGV7gCsTaK3iBCqa2ipmrVqLrWrmytjL3nBwoEGD30ja/6JaSj/wp3SEIXjpUoB+Oeg0zpoR+NsyoDVOgi39cbYHAy4MQTc0wOYZepxRBUkn9UxxEiNnXxyYwd6w/438hSddHJilv1tqv664Shle1DeJaJihPV9uNQ+NWBRK2QVSr+GjtaFzOIpdjKFShnoY+Gv0N0u0OVLexY48NQ+68JchdpQu/o1piVMu6faJdwjNWIAYyl55bqGUtbndO53TzCIpUpCkdlEm+V3J3Ir8r3uops2+FkTmvx832IGJwN97xS/5Ti0LQ/WLwtbxMal2ueAwvc2c8CAgSJip5U4+tKHECMlUzq2UcA9EyROuJi6/71dtzWAfVcq0Jw1CsYh13kDDteVoirE+zWtLVinQ8ZAS5YlVlvRHWfi3pakUQL0OOwmp/W/vN6Gt5zBIkzEezxnCtMJsxDIECTYmhp3bej4HHzaalNMyAnzE0UBKp6Z1Do2pwd3JkAH6CxlTs/bZOZ661yMwhohDLQqREMWz8UAvWoUQleggehG5dSPUbv28GJlnKHGJsqPi7vuG/MGTyCGslOtkCOayrGOa/indajdudb6FUpXoepgiLHIIMriddyzrkMBhGAqlOH4U2hKCT2j0NdU8jFbzpZ3LQlh9srPqEQ1Y9lEP2CVa99KHvH8mnrGGdl9V9AAAAAElFTkSuQmCC";
Which is my Checked.png converted in online converter. It decompreses perfectly.
And this is my base64, which i get by converting:
"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"
My problem is that string which i get as base64 from my code - is incorrect *What i did wrong?*
What about trying:
public static BitmapImage base64image(string base64string)
{
byte[] fileBytes = Convert.FromBase64String(base64string);
using (MemoryStream ms = new MemoryStream(fileBytes))
{
Image streamImage = Image.FromStream(ms);
context.Response.ContentType = "image/jpeg";
streamImage.Save(context.Response.OutputStream, ImageFormat.Jpeg);
return streamImage;
}
}
I agree with Alexei that your code for reading the image in does look a little strange. I've recently written some code for a similar task that I was doing which might point you in the right direction:
string fileContent = null;
/* Check the file actually has some content to display to the user */
if (uploadFile != null && uploadFile.ContentLength > 0)
{
byte[] fileBytes = new byte[uploadFile.ContentLength];
int byteCount = uploadFile.InputStream.Read(fileBytes, 0, (int)uploadFile.ContentLength);
if (byteCount > 0)
{
fileContent = CreateBase64Image(fileBytes);
}
}
private string CreateBase64Image(byte[] fileBytes)
{
Image streamImage;
/* Ensure we've streamed the document out correctly before we commit to the conversion */
using (MemoryStream ms = new MemoryStream(fileBytes))
{
/* Create a new image, saved as a scaled version of the original */
streamImage = ScaleImage(Image.FromStream(ms));
}
using (MemoryStream ms = new MemoryStream())
{
/* Convert this image back to a base64 string */
streamImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return Convert.ToBase64String(ms.ToArray());
}
}
not an answer: more of a long comment ... OP states that decoding code works perfectly fine, also it looks suspicios. Also code assumed to be verified to work on PNG images, but saving code explicitly produces valid JPG with SaveJpeg call...
Your code that creates stream for reading looks strange - you create stream over existing byte array, than write the same bytes into that stream, and that pass that stream without seeking back to 0 to some method.
Potential fix (assuming BitampImage can accept JPG stream):
don't call Write at all as stream already have the bytes you want
set ms.Position = 0 after writing to the stream.
Note: I'm not sure if it is OK to dispose stream that is a source for BitmapImage, you may need to remove using too.

Convert GIF to PDF byte[]

I am calling a third-party webservice which returns a GIF. I want to convert that image to a PDF, which I then want to convert into byte[].
Here's my code:
HttpWebRequest NxtserviceRequest = (HttpWebRequest)WebRequest.Create(ImgPath);
NxtserviceRequest.Method = "GET";
HttpWebResponse NxtServiceResponse = (HttpWebResponse)NxtserviceRequest.GetResponse();
Stream NxtresponseStream;
NxtresponseStream = NxtServiceResponse.GetResponseStream();
using (MemoryStream ms = new MemoryStream())
{
int count = 0;
do
{
byte[] buf = new byte[1024];
count = NxtresponseStream.Read(buf, 0, 1024);
ms.Write(buf, 0, count);
} while (NxtresponseStream.CanRead && count > 0);
binaryData = ms.ToArray();
...
}
When I am trying to pass this binaryData on file browser, it's showing error on PDF generate.

Save Image source to database

I have a WPF Image with a source assign from picture dialog;
this.imgProduct.Source = new BitmapImage(new Uri(op.FileName));
How can I retieve the source, convert it to byte array and save it into database?
Thank you
You have to convert BitmapImage into the byte[] then save it to the database.
var imageSource = this.imgProduct.Source as BitmapImage;
var stream = imageSource.StreamSource;
Byte[] buffer = null;
if (stream != null && stream.Length > 0)
{
using (BinaryReader br = new BinaryReader(stream))
{
buffer = br.ReadBytes((Int32)stream.Length);
}
}
// write buffer to the database
P.S. I haven't tested the code but I think it works!
As long as you have access to the image file in op.FileName it would be very easy to get the file content by e.g.
byte[] imageBuffer = File.ReadAllBytes(op.FileName);
If the image is loaded from a file Uri (as in your example) you could also do this:
byte[] imageBuffer = File.ReadAllBytes(image.UriSource.AbsolutePath);
If you only have the BitmapImage without information about the file that it was loaded from (e.g. when it was loaded from a temporary file or a web resource), you would have to encode it by one of WPFs BitmapEncoders:
byte[] imageBuffer;
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
using (MemoryStream stream = new MemoryStream())
{
encoder.Save(stream);
imageBuffer = stream.GetBuffer();
}

WPF download image bytes from Blob Storage

I want to preload a lot of images when my app starts up, sort of a once off thing.
I have an Image class that contains the Url of its image stored in the cloud as blob storage (this address is a https address BTW)
I want to download the image bytes from the cloud, store them on the object, then when it comes time to show the image, load the image from its bytes.
I have all the code for this, but I keep getting the exception:
No imaging component suitable to complete this operation was found.
Here is my code: EDIT UPDATED WITH A FIX
//Loaded on start-up
private static void LoadImageBytes(Image img)
{
var urlUri = new Uri(img.Url);
var request = (HttpWebRequest)WebRequest.CreateDefault(urlUri);
MemoryStream memStream = new MemoryStream();
using (var response = request.GetResponse())
{
var buffer = new byte[4096];
using (var stream = response.GetResponseStream())
{
int bytesRead = stream.Read(buffer, 0, buffer.Length);
while (bytesRead > 0)
{
memStream.Write(buffer, 0, bytesRead);
bytesRead = stream.Read(buffer, 0, buffer.Length);
}
img.ImageBytes = memStream.ToArray();
}
}
}
Then when I want to get the image on the screen I call this:
public BitmapImage ImageFromBuffer(Byte[] bytes)
{
MemoryStream stream = new MemoryStream(bytes);
stream.Seek(0, SeekOrigin.Begin);
BitmapImage image = new BitmapImage();
image.BeginInit();
image.StreamSource = stream;
image.EndInit();
return image;
}
But in the EndInit() call I get the exception.
I have done some testing and if I load the file from my local filesystem, I get a different set of bytes to that of the image in the cloud. I assume its something to do with blob storage or https?
And yes I can browse to that image and its not corrupted.
EDIT, fixed now all good
Are you sure this line is correct?
while (stream.Read(buffer, 0, buffer.Length) > 0)
img.ImageBytes = buffer;
img.ImageBytes will hold the last read buffer.

Categories

Resources