Image not getting replaced in IsolatedStorage in Windows Phone 8 - windows-phone-8

I have stored few images in isolatedstorage and I am trying to replace them by using
using (IsolatedStorageFile isStore = IsolatedStorageFile.GetUserStoreForApplication()){
if (isStore.FileExists(fileName)){
isStore.DeleteFile(fileName);
}
using (IsolatedStorageFileStream targetStream = isStore.OpenFile(fileName, FileMode.Create, FileAccess.Write)){
// Initialize the buffer for 4KB disk pages.
byte[] readBuffer = new byte[4096];
int bytesRead = -1;
// Copy the thumbnail to the local folder.
while ((bytesRead = e.ImageStream.Read(readBuffer, 0, readBuffer.Length)) > 0){
targetStream.Write(readBuffer, 0, bytesRead);
targetStream.Close();
}
}
Now When I am trying to access the new file I end up seeing the old photo. the new photo is not replaced immediately.
But when I close the app and again fetch it I get the new photo. What is wrong?

I was using an ImageBrush to paint the background grid and was binding only the ImageSource of the ImageBrush. I guess this ImageBrush was not getting updated so instead of changing the source of the ImageBrush I created a new object of it and assigned it to Grid.Background. so now it works :)

Related

WriteableBitmapRenderer.RenderAsync() ArgumentException "Value does not fall within the expected range"

I'm developing a WP8 app using Nokia Imaging SDK.
I'm trying to add filter effect to an image and render it into a WriteableBitmap.
Here is my code:
private async void PhotoChosen(object sender, PhotoResult photoResult)
{
if (photoResult != null)
{
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(photoResult.ChosenPhoto);
WriteableBitmap wb = new WriteableBitmap(bitmap.PixelWidth, bitmap.PixelHeight);
StreamImageSource source = new StreamImageSource(photoResult.ChosenPhoto);
var effects = new FilterEffect(source);
effects.Filters = new IFilter[] { new SketchFilter() };
var renderer = new WriteableBitmapRenderer(effects, wb);
await renderer.RenderAsync();
}
}
All is going fine, but when this line is processing:
await renderer.RenderAsync();
This ArgumentException is thrown:
Value does not fall within the expected range
I think I've made a mistake creating the IImageProvider effects or the WriteableBitmap wb
Does anyone got this problem and found an issue ?
Thanks :)
You need to set the stream position before setting it as source for StreamImageSource.
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(photoResult.ChosenPhoto);
WriteableBitmap wb = new WriteableBitmap(bitmap.PixelWidth, bitmap.PixelHeight);
photoResult.ChosenPhoto.Position = 0;
StreamImageSource source = new StreamImageSource(photoResult.ChosenPhoto);
You need to do this because you have called bitmap.SetSource(photoResult.ChosenPhoto). That means that the stream has already been read once, therefore it's position is at the very end of the stream. When StreamImageSource tries to read it, it is already at the end, thus "Value does not fall within the expected range."

Load a PNG from isolated storage on Windows Phone

I can load JPEGs fine using the specialised JPEG load jpeg method, I can also save PNGs fine using the many methods detailed on SO.
However whenever I create a stream for loading a PNG from isolated storage it results in a BitmapImage of zero size.
Here is what I have ...
public static async Task<BitmapImage> ReadBitmapImageFromIsolatedStorage(string fn)
{
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
if (local != null)
{
Stream file = await local.OpenStreamForReadAsync(fn);
BitmapImage bi = new BitmapImage();
bi.SetSource(file);
return bi;
}
return null;
}
I've tried many variations as well. It seems there is some kind of delay to reading the stream when creating BitmapImages which means often the stream is disposed of before the BitmapImage reads it. In WPF there is an option that can be set but WIndows Phone BitmapImage does not have this option.
Try this:
BitmapImage image = new BitmapImage();
image.DecodePixelWidth = 500; //desired width, optional
image.DecodePixelHeight = 500; //desired height, optional
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (myIsolatedStorage.FileExists("imagepath"))
{
using (IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile("imagepath", FileMode.Open, FileAccess.Read))
{
image.SetSource(fileStream);
}
}
}
This is what I found works in the end using the new Windows.Storage APIs
I'm not 100% clear what the problem was originally but this works. This has some extra functionality in that if it fails to read, it retries a second or so later ...
public static async Task<BitmapImage> ReadBitmapImageFromIsolatedStorage(string fn)
{
Uri uri = new Uri(String.Format("ms-appdata:///local/{0}", fn));
// FileAccessAttempts is just an int that determines how many time
// to try reading before giving up
for (int i = 0; i < AppConfig.FileAccessAttempts; i++)
{
try
{
StorageFile file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(uri);
Stream stream = await file.OpenStreamForReadAsync();
BitmapImage bi = new BitmapImage();
bi.SetSource(stream);
return bi;
}
catch
{
// Similar functions also have a ~1 second retry interval so introduce
// a random element to prevent blocking from accidentally synched retries
Random r = new Random();
System.Threading.Thread.Sleep(950 + (int)Math.Floor(r.Next() * 50.0));
}
}
return new BitmapImage();
}

System.OutOfMemory BitmapImage WP8

I got a OutOfmemory error when i create a list of bitmapimage...
What am i supposed to do...?
Thanks for your help ;)
Here is my code :
foreach (var bytearray in imageDataBlocksPresta)
{
if (bytearray != null)
{
MemoryStream ms;
using (ms = new MemoryStream(bytearray, 0, bytearray.Length))
{
BitmapImage photo = new BitmapImage();
photo.DecodePixelHeight = 800;
photo.DecodePixelWidth = 624;
photo.SetSource(ms);//ERROR
listphotoPresta.Add(photo);
}
}
else//si photo null
{
BitmapImage photo = new BitmapImage();
photo.DecodePixelHeight = 800;
photo.DecodePixelWidth = 624;
photo.UriSource = new Uri("/Images/NoImageIcon.jpg", UriKind.RelativeOrAbsolute);
listphotoPresta.Add(photo);
}
Try setting photo to null and calling GC.Collect() once you've added it. Like this:
listphotoPresta.Add(photo);
photo = null;
GC.Collect();
Don't create NoImageIcon all the time. Use only one reference
Don't try to store all images in memory. It's a mobile.
Limit your app for devices with at least 512MB RAM
Store lower resuolution pictures. 800*600 is full screen on many devices
Load images on demand
Call GC right after you release an image

MemoryStream used to save image data in CameraCaptureSequence is 0 even though image data is present in the CameraCaptureSequence

I'm using the PhotoCaptureDevice class and I can capture the camera frame, but when I am getting an error while copying the image data in the CameraCaptureFrame.CaptureSequence of the CameraCaptureSequence into a MemoryStream and then save it in the Camera Roll. This is the code snippet of what I'm trying to do.
PhotoCaptureDevice cam;
cam = await PhotoCaptureDevice.OpenAsync(<front/rear depending on user input>,<resolution depends on user input>);
CameraCaptureSequence seq;
seq = cam.CreateCaptureSequence(1);
cam.SetProperty(KnownCameraGeneralProperties.PlayShutterSoundOnCapture, true);
MemoryStream captureStream1 = new MemoryStream();
seq.Frames[0].CaptureStream = captureStream1.AsOutputStream();//This stream is for saving the image data to camera roll
await cam.PrepareCaptureSequenceAsync(seq);
await seq.StartCaptureAsync();
bool a = seq.Frames[0].CaptureStream.Equals(0);//This value is false during debugging
if(capturestream1.Length>0)//This condition evaluates to false
{
MediaLibrary library = new MediaLibrary();
Picture picture1 = library.SavePictureToCameraRoll("image1", captureStream1);
}
else
{
//Logic to handle condition
}
As I've added in the comments, the variable bool a evaluates to false which I checked by debugging the code. But for some reason the capturestream1.Length property is 0.
Here's a code snippet on how to capture a sequence with a single image and saving that image to the MediaLibrary. Obviously this is a bit of a trivial example for this API since sequence are really good for capturing multiple images and meshing them up together with post-processing.
private async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
using (MemoryStream stream = new MemoryStream())
using (var camera = await PhotoCaptureDevice.OpenAsync(CameraSensorLocation.Back,
PhotoCaptureDevice.GetAvailableCaptureResolutions(CameraSensorLocation.Back).First()))
{
var sequence = camera.CreateCaptureSequence(1);
sequence.Frames[0].CaptureStream = stream.AsOutputStream();
camera.PrepareCaptureSequenceAsync(sequence);
await sequence.StartCaptureAsync();
stream.Seek(0, SeekOrigin.Begin);
using (var library = new MediaLibrary())
{
library.SavePictureToCameraRoll("currentImage.jpg", stream);
}
}
}
When you run this code snippet you can see the image stored on the device:
You can find a full working sample as part of Nokia's Camera Explorer app that demos end-to-end usecases for the WP8 camera APIs: http://projects.developer.nokia.com/cameraexplorer

Save image to isolated storage from BG task

I'm trying to save an image from the web to the isolated storage from a background task but it throws
An unhandled exception of type 'System.UnauthorizedAccessException' occurred in System.Windows.ni.dll
i'm using this piece of code
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (myIsolatedStorage.FileExists(tempJPEG))
{
myIsolatedStorage.DeleteFile(tempJPEG);
}
IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(tempJPEG);
StreamResourceInfo sri = null;
Uri uri = new Uri(tempJPEG, UriKind.Relative);
sri = Application.GetResourceStream(uri);
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(e.Result);
WriteableBitmap wb = new WriteableBitmap(bitmap);
// Encode WriteableBitmap object to a JPEG stream.
Extensions.SaveJpeg(wb, fileStream, wb.PixelWidth, wb.PixelHeight, 0, 100);
//wb.SaveJpeg(fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
fileStream.Close();
}
This works 100% when it's runing from the app , but not from the background task.
Any tips on how to save the image ?
You need to invoke this code Dispatcher.BeginInvoke() since WriteableBitmap needs to execute on the UI thread and not a background thread. See # http://codeblog.vurdalakov.net/2012/02/solution-wp7-unauthorizedaccessexceptio.html