WP8 C# // Save image from web, in isolate storage - c#

I know how to save an image in isolate storage using the following :
private void addButton_Click(object sender, RoutedEventArgs e)
{
MemoryStream stream = new MemoryStream();
WriteableBitmap wb = new WriteableBitmap(myImage, null);
BitmapImage bi = new BitmapImage();
wb.SaveJpeg(stream, wb.PixelWidth, wb.PixelHeight, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
string data = Convert.ToBase64String(stream.GetBuffer());
appSettings.Add("image", data);
}
I know how to load it using the following :
private void loadImage_Click(object sender, RoutedEventArgs e)
{
byte[] imageBytes = Convert.FromBase64String(appSettings["image"].ToString());
MemoryStream ms = new MemoryStream(imageBytes);
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(ms);
myImage.Source = bitmapImage;
}
But I don't know how to load and read it from a URL, how can this be accomplished?
Thx for your help.

From this Image from URL to stream:
WebClient client = new WebClient();
client.OpenReadCompleted += (s, e) =>
{
byte[] imageBytes = new byte[e.Result.Length];
e.Result.Read(imageBytes, 0, imageBytes.Length);
// Now you can use the returned stream to set the image source too
var image = new BitmapImage();
image.SetSource(e.Result);
NLBI.Thumbnail.Source = image;
};
client.OpenReadAsync(new Uri(article.ImageURL));
Edit: here is some more info on OpenReadComplete(MSDN) and how to use it

Related

Cannot save Bitmapsource to Bitmapimage

I am trying to save an image from a users Clipboard. I am able to get all the correct data from the clipboard image into the Bitmapsource. I am trying to save to a Bitmapimage so I can upload a file to a website. When converting the Bitmapsource to a Bitmapimage, all of the Bitmapimages data stays null and will throw an exception.
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if ((Keyboard.Modifiers == ModifierKeys.Control) && (e.Key == Key.V))
{
if (Clipboard.ContainsImage())
{
BitmapSource bitmapSource = Clipboard.GetImage();
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
MemoryStream memoryStream = new MemoryStream();
BitmapImage bImg = new BitmapImage();
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
encoder.Save(memoryStream);
bImg.BeginInit();
bImg.StreamSource = new MemoryStream(memoryStream.ToArray());
bImg.EndInit();
var client = new WebClient();
var uri = bImg.UriSource;
var path = uri.AbsolutePath;
//client.UploadFile(link, path);
}
}
}
Both
var uri = bImg.UriSource;
var path = uri.AbsolutePath;
Will throw an unhandled exception of type 'System.NullReferenceException' occurred in WpfApplication1.exe
Additional information: Object reference not set to an instance of an object
Creating a BitmapImage from its StreamSource property will not magically set its UriSource property. You do not need that BitmapImage at all.
Write the original BitmapSource to a FileStream instead of a MemoryStream, and upload that file:
string path = ...
using (var fileStream = new FileStream(path, FileMode.Create))
{
encoder.Save(fileStream);
}
client.UploadFile(link, path);
It may even be unnecessary to create an intermediate file. Just upload the buffer of the MemoryStream:
using (var memoryStream = new MemoryStream())
{
encoder.Save(memoryStream);
client.UploadData(link, memoryStream.ToArray());
}

How to set and save background image in windows phone?

I'm using this code, so user can sets custom background image for the application:
private void Button_Click(object sender, RoutedEventArgs e)
{
PhotoChooserTask photoChooserTask = new PhotoChooserTask();
photoChooserTask.Completed += new EventHandler<PhotoResult>(photoChooserTask_Completed);
photoChooserTask.Show();
}
void photoChooserTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.SetSource(e.ChosenPhoto);
var imageBrush = new ImageBrush
{
ImageSource = bmp,
Opacity = 0.5d
};
App.RootFrame.Background = imageBrush;
}
}
but this won't save background image for next application lunch.
now how can I save chosen photo to isolated storage to remains as app background even after restarting the application?
Save image asynchronously, applies to WP8 only.
public static async Task SaveImageAsync(string imageFileName, BitmapImage image)
{
// Get Students LocalFolder
IStorageFolder folder = await ApplicationData.Current.LocalFolder
.CreateFolderAsync("Images", CreationCollisionOption.OpenIfExists);
IStorageFile file = await folder.CreateFileAsync(
imageFileName, CreationCollisionOption.ReplaceExisting);
using (Stream stream = await file.OpenStreamForWriteAsync())
{
var wrBitmap = new WriteableBitmap(image);
wrBitmap.SaveJpeg(stream, image.PixelWidth, image.PixelHeight, 100, 100);
}
}
Read image synchronously both WP7.x WP8:
public static BitmapImage LoadImage(string imageFileName)
{
BitmapImage bitmapImage = null;
using (var isoFile = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var isoStream = isoFile.OpenFile(
imageFileName, FileMode.Open, FileAccess.Read))
{
bitmapImage = new BitmapImage();
bitmapImage.SetSource(isoStream);
}
}
return bitmapImage;
}
You can find a bunch of resources online, just google it.
http://msdn.microsoft.com/en-us/library/xf96a1wz(v=vs.110).aspx
When Choosing
IsolatedStorageSettings.ApplicationSettings["backgroundImage"]=e.OriginalFileName;
On app loading
image.Source = new BitmapImage(new Uri(IsolatedStorageSettings.ApplicationSettings["backgroundImage"], UriKind.Absolute));
You can use the free EZ_Iso.dll to do this.
Just send your Bitmap off to the serializer with a name and let it handle the rest
//Saving
EZ_Iso.IsolatedStorageAccess.SaveImage(“MyImage”, YourImage);
//Retrieving
ImageControl.Source = EZ_Iso.IsolatedStroageAccess.GetImage(“MyImage”,Width,Height);
EZ_Iso.dll Download and Documentation

Displaying, downloading, and saving a jpeg image from server to Windows Phone 8 camera roll

I am trying to retrieve an image from a specific URL, display it in my image box, and then finally save it to my camera roll. This is what I have tried but I am getting a target invocation exception. What does that suggest?
private void downloadImg()
{
String uri = "http://timenewsfeed.files.wordpress.com/2013/12/doge.jpg";
Uri imgUri = new Uri(uri, UriKind.Absolute);
ImageSource imgSource = new BitmapImage(imgUri);
Dispatcher.BeginInvoke(() =>
{
imageBox.Source = imgSource;
}
);
using (var mediaLibrary = new MediaLibrary())
{
using (var stream = new MemoryStream())
{
Debug.WriteLine("trying to save photo...");
var fileName = "HELLOWORLD.jpg";
BitmapImage img = new BitmapImage(imgUri);
img.CreateOptions = BitmapCreateOptions.None;
img.ImageOpened += (s, e) =>
{
WriteableBitmap bmp = new WriteableBitmap((BitmapImage)s);
bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
};
stream.Seek(0, SeekOrigin.Begin);
Dispatcher.BeginInvoke(() =>
{
var picture = mediaLibrary.SavePicture(fileName, stream);
});
// or to cameraroll
Debug.WriteLine("photo saved");
}
}
}
I see at least one potential issue with your code. The main issue I see is in the order things execute in your method which could cause the stream to be empty when you try to save it. You do a handling for ImageOpened which fills the stream, but that callback is executed asynchronously. In other words, this
stream.Seek(0, SeekOrigin.Begin);
Dispatcher.BeginInvoke(() =>
{
var picture = mediaLibrary.SavePicture(fileName, stream);
});
may execute before this
WriteableBitmap bmp = new WriteableBitmap((BitmapImage)s);
bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
If you moved the logic for saving up to ImageOpened handler, it may fix the issue. So you'd have something like this...
img.ImageOpened += (s, e) =>
{
WriteableBitmap bmp = new WriteableBitmap((BitmapImage)s);
bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
Dispatcher.BeginInvoke(() =>
{
var picture = mediaLibrary.SavePicture(fileName, stream);
});
};

Save a remote image in to Isolated Storage

I tried using this code for download image:
void downloadImage(){
WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
client.DownloadStringAsync(new Uri("http://mysite/image.png"));
}
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
//how get stream of image??
PicToIsoStore(stream)
}
private void PicToIsoStore(Stream pic)
{
using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
var bi = new BitmapImage();
bi.SetSource(pic);
var wb = new WriteableBitmap(bi);
using (var isoFileStream = isoStore.CreateFile("somepic.jpg"))
{
var width = wb.PixelWidth;
var height = wb.PixelHeight;
Extensions.SaveJpeg(wb, isoFileStream, width, height, 0, 100);
}
}
}
The problem is: how get the stream of image?
Thank!
It's easy to get a stream to a file in Isolated Storage. IsolatedStorageFile has an OpenFile method that gets one.
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = store.OpenFile("somepic.jpg", FileMode.Open))
{
// do something with the stream
}
}
You need to put e.Result as a parameter when calling PicToIsoStore inside your client_DownloadStringCompleted method
void client_DownloadStringCompleted(object sender,
DownloadStringCompletedEventArgs e)
{
PicToIsoStore(e.Result);
}
The WebClient class gets response and stores it in the e.Result variable. If you look carefully, the type of e.Result is already Stream so it is ready to be passed to your method PicToIsoStore
There is an easy way
WebClient client = new WebClient();
client.OpenReadCompleted += (s, e) =>
{
PicToIsoStore(e.Result);
};
client.OpenReadAsync(new Uri("http://mysite/image.png", UriKind.Absolute));
Try the following
public static Stream ToStream(this Image image, ImageFormat formaw) {
var stream = new System.IO.MemoryStream();
image.Save(stream);
stream.Position = 0;
return stream;
}
Then you can use the following
var stream = myImage.ToStream(ImageFormat.Gif);

Converting Byte[] to Image type in C# for Windows Phone 7

I am having a problem converting a Byte array into an Image type for displaying in an application on Windows Phone 7.
The data is retrieved from a server, and when I upload and download the data it works fine, but I am struggling when converting it back into an Image format.
Can anyone shed some light on this issue for me?
This is my method for turning the Byte array into a BitmapImage,
public BitmapImage decodeImage(byte[] array)
{
MemoryStream ms = new MemoryStream(array, 0, array.Length);
// Convert byte[] to Image
ms.Write(array, 0, array.Length);
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(ms);
return bitmapImage;
}
Then this is the code where I try to set the returned BitmapImage to the source for the Image box I am using in the XAML UI.
BitmapImage usrIMG = new BitmapImage();
usrIMG = getJson.decodeImage(userProfile.Photos[0].Image);
profileImage.Source = usrIMG;
I know the code looks mishmashed, and I am declaring things that I dont need to, i have been fiddling with it for ages and I am completely at a loss.
Many Thanks
the following code works fine for me in a quick test for your scenario of using the PhotoChooserTask, and store the selected image in a byte array. You also might want to review your code where you store and retrieve the byte array on your side, to make sure nothing gets lost there.
private byte[] imageBytes;
private void GetPhoto_Click(object sender, RoutedEventArgs e)
{
PhotoChooserTask photoTask = new PhotoChooserTask();
photoTask.Completed += new EventHandler<PhotoResult>(photoTask_Completed);
photoTask.Show();
}
void photoTask_Completed(object sender, PhotoResult e)
{
imageBytes = new byte[e.ChosenPhoto.Length];
e.ChosenPhoto.Read(imageBytes, 0, imageBytes.Length);
// save 'imageBytes' byte array to data base ...
}
private void ShowPhoto_Click(object sender, RoutedEventArgs e)
{
// load 'imageBytes' byte array to data base ...
BitmapImage bitmapImage = new BitmapImage();
MemoryStream ms = new MemoryStream(imageBytes);
bitmapImage.SetSource(ms);
myImageElement.Source = bitmapImage;
}
You'll need a WritableBitmap and to know the height and width of the image to be able to do this.
Then you can do something like this:
var result = new WriteableBitmap(width, height);
var ms = new MemoryStream();
ms.Write(myByteArray, myByteArray, myByteArray.Length);
result.SetSource(ms);
var bitmapImage = new BitmapImage();
bitmapImage.SetSource(new MemoryStream(..Binary array Data..));
img1.Source = bitmapImage;
public BitmapImage ByteArraytoBitmap(Byte[] byteArray)
{
MemoryStream stream = new MemoryStream(byteArray);
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(stream);
return bitmapImage;
}
i used this code before and it's work 100% successfuly.

Categories