I have a xml with data, in this case images stored in the internet..i want to read the xml in windows phone and save it to the memory.. how can i do that? any tutorial?
Lets divide your task into two parts
1. Downloading XML file containing image path
2. Reading that XML file and binding image control to that dynamic path
Lets Proceeds with first case:
1. Downloading XML file containing image path
here Path=http://server_adrs/XML_FILE
iso_path=Path inside Isolated Storage where u want to save XML file.
public void GetXMLFile(string path)
{
WebClient wcXML = new WebClient();
wcXML.OpenReadAsync(new Uri(path));
wcXML.OpenReadCompleted += new OpenReadCompletedEventHandler(wc);
}
void wc(object sender, OpenReadCompletedEventArgs e)
{
var isolatedfile = IsolatedStorageFile.GetUserStoreForApplication();
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(iso_path, System.IO.FileMode.Create, isolatedfile))
{
byte[] buffer = new byte[e.Result.Length];
while (e.Result.Read(buffer, 0, buffer.Length) > 0)
{
stream.Write(buffer, 0, buffer.Length);
}
stream.Flush();
System.Threading.Thread.Sleep(0);
}
}
2. Reading XML file and binding image control to the dynamic path
here i am having an List which is showing an images, so i will a function to bind images to this list as per below.
public IList<Dictionary> GetListPerCategory_Icon(string category, string xmlFileName)
{
using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (storage.FileExists(xmlFileName))
{
using (Stream stream = storage.OpenFile(xmlFileName, FileMode.Open, FileAccess.Read))
{
try
{
loadedData = XDocument.Load(stream);
var data = from query in loadedData.Descendants("category")
where query.Element("name").Value == category
select new Glossy_Test.Dictionary
{
Image=GetImage((string)query.Element("iconpress")),//This is a function which will return Bitmap image
};
categoryList = data.ToList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString(), (((PhoneApplicationFrame)Application.Current.RootVisual).Content).ToString(), MessageBoxButton.OK);
return categoryList = null;
}
}
}
}
return categoryList;
}
and here the definition for above function
public BitmapImage GetImage(string imagePath)
{
var image = new BitmapImage();
imagePath = "/Glossy" + imagePath;
using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (storage.FileExists(imagePath))
{
using (Stream stream = storage.OpenFile(imagePath, FileMode.Open, FileAccess.Read))
{
image.SetSource(stream);
}
}
}
return image;
}
you could use WebClient to pull the xml from the server and then save it as an XDocument in your callback.
Related
am trying to show image directly from zip file without extracting file.
ZipArchiveEntry tumbnail = archive.Entries.Where(s => s.FullName.Equals("coverthumb.png")).FirstOrDefault();
if (tumbnail != null)
{
Stream picdata = tumbnail.Open();
await picdata.CopyToAsync (picdata);
BitmapImage bt = new BitmapImage();
bt.SetSource (picdata.AsRandomAccessStream());
image.Source = bt;
}
but getting an
cannot seek exception
please help.
the following code works for images but when tries to read many images at once some times it gives invalid data exception at bitmap creation
async public static Task<BitmapImage> GetImageFromZipEntry(ZipArchiveEntry zipentry)
{
//for extracting image inside a zip as bitmapimage
BitmapImage tm = new BitmapImage();
try {
if (zipentry != null)
{
using (Stream imstream = zipentry.Open())
{
using (MemoryStream immemorystream = new MemoryStream((int)zipentry.Length))
{
await imstream.CopyToAsync(immemorystream);
using (var sourceStream = new MemoryStream(immemorystream.ToArray()))
{
await tm.SetSourceAsync(sourceStream.AsRandomAccessStream());
}
}
}
}
}
catch(Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
tm = null;
}
return tm;
}
I'm using Magick.NET to convert a PDF to a PNG and stream it back to the page via ajax.
Everything works until a PDF is uploaded twice. When trying to overwrite or delete the existing file, the debugger tells me that the file is in use by another process.
Here's my function that returns an Image to the controller:
//path is a fully qualified path to a file ending in .PDF
private Image ConvertPDFTOneImage(string path)
{
MagickReadSettings settings = new MagickReadSettings();
settings.Density = new PointD(300, 300);
using (MagickImageCollection images = new MagickImageCollection())
{
FileInfo file = new FileInfo(path);
images.Read(file);
file = null;
using (MagickImage horizontal = images.AppendHorizontally())
{
string PNGName = Path.ChangeExtension(path, ".png");
horizontal.Write(PNGName);
}
return Image.FromFile(path.Replace("pdf", "png"));
}
}
And my controller that streams the response back to the browser:
public async Task<HttpResponseMessage> PostFormData([FromUri] int sellerID, [FromUri] int eventID, [FromUri] string section, [FromUri] string row, [FromUri] string seat)
{
if (HttpContext.Current.Request.Files.AllKeys.Any())
{
try
{
string base64 = string.Empty;
SellerObjects.Externeal.SellerTicket TicketToSave = new SellerObjects.Externeal.SellerTicket();
TicketToSave.UploadedFile = HttpContext.Current.Request.Files["UploadedImage"];
SellerTicketRepo TheLocalSellerRepo = new SellerTicketRepo(TicketToSave);
using (MemoryStream ms = new MemoryStream())
{
TheLocalSellerRepo.GetConvertedPDFImage().Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
base64 = System.Convert.ToBase64String(ms.ToArray());
}
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StringContent(base64);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
return result;
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, "Error saving file.");
}
}
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "An error has occurred");
}
I am assuming that the Image class that you are returning is a System.Drawing.Image. You need to Dispose this object to release the file lock.
// Instead of this:
using (MemoryStream ms = new MemoryStream())
{
TheLocalSellerRepo.GetConvertedPDFImage().Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
base64 = System.Convert.ToBase64String(ms.ToArray());
}
// Should you be doing this:
using (MemoryStream ms = new MemoryStream())
{
using (Image img = TheLocalSellerRepo.GetConvertedPDFImage())
{
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
base64 = System.Convert.ToBase64String(ms.ToArray());
}
}
// Or you could even do this (if GetConvertedPDFImage() returns a MagickImage):
using (MagickImage img = TheLocalSellerRepo.GetConvertedPDFImage())
{
img.Format = MagickFormat.Jpeg;
base64 = img.ToBase64();
}
I'm trying do to a program which stores many (5-15) .txt files in phone's isolated storage memory. I noticed how easy it is to read those files with programs like Windows Phone Power Tools so I decided to to encrypt them. I'm using this link as a tutorial:
http://msdn.microsoft.com/en-us/library/windows/apps/hh487164(v=vs.105).aspx
Encryption works fine, as I'm obviously saving one file at a time. However, I'm having problems while trying to decrypt them. How should i edit my code so I can decrypt many .txt files? Below are my codes that I'm using at the moment:
private void IsoRead()
{
System.IO.IsolatedStorage.IsolatedStorageFile local =
System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication();
string[] filenames = local.GetFileNames("./DataFolder/*.txt*");
foreach (var fname in filenames)
{
//retrieve byte
byte[] ProtectedByte = this.DecryptByte();
//decrypt with Unprotect method
byte[] FromByte = ProtectedData.Unprotect(ProtectedByte, null);
//convert from byte to string
fText = Encoding.UTF8.GetString(FromByte, 0, FromByte.Length);
this.Items.Add(new itemView() { LineOne = fname, LineTwo = fText });
}
}
And the other one:
private byte[] DecryptByte()
{
// Access the file in the application's isolated storage.
IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication();
IsolatedStorageFileStream readstream = new IsolatedStorageFileStream
("DataFolder\\"/*Here's where I'm having problems with*/, System.IO.FileMode.Open, FileAccess.Read, file);
// Read the written data from the file.
Stream reader = new StreamReader(readstream).BaseStream;
byte[] dataArray = new byte[reader.Length];
reader.Read(dataArray, 0, dataArray.Length);
return dataArray;
}
So basically the program has a listview page that get's the files from isolated storage. If one is touched, it goes to a new page that shows what's written in it.
Bonus question: Can I encrypt folders in WP7/WP8?
Edit: added one code line into IsoRead.
Xaml:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<Button Content="Write Random File" Click="WriteFile" VerticalAlignment="Top" />
<Button Content="Read files File" Click="ReadFiles" VerticalAlignment="Top" />
</StackPanel>
</Grid>
Code:
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
}
private const string FilePath = "{0}.txt";
private readonly List<ItemView> items = new List<ItemView>();
private void WriteFile(object sender, RoutedEventArgs e)
{
var fileName = DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture);
// Convert text to bytes.
byte[] data = Encoding.UTF8.GetBytes(fileName);
// Encrypt byutes.
byte[] protectedBytes = ProtectedData.Protect(data, null);
// Store the encrypted bytes in iso storage.
this.WriteToFile(protectedBytes, fileName);
}
private void ReadFiles(object sender, RoutedEventArgs e)
{
items.Clear();
using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
var files = isoStore.GetFileNames("*.txt");
foreach (var file in files)
{
// Retrieve the protected bytes from isolated storage.
byte[] protectedBytes = this.ReadBytesFromFile(file);
// Decrypt the protected bytes by using the Unprotect method.
byte[] bytes = ProtectedData.Unprotect(protectedBytes, null);
// Convert the data from byte to string and display it in the text box.
items.Add(new ItemView { LineOne = file, LineTwo = Encoding.UTF8.GetString(bytes, 0, bytes.Length) });
}
}
//Show all the data...
MessageBox.Show(string.Join(",", items.Select(i => i.LineTwo)));
}
private void WriteToFile(byte[] bytes, string fileName)
{
// Create a file in the application's isolated storage.
using (var file = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var writestream = new IsolatedStorageFileStream(string.Format(FilePath, fileName), System.IO.FileMode.Create, System.IO.FileAccess.Write, file))
{
// Write data to the file.
using (var writer = new StreamWriter(writestream).BaseStream)
{
writer.Write(bytes, 0, bytes.Length);
}
}
}
}
private byte[] ReadBytesFromFile(string filePath)
{
// Access the file in the application's isolated storage.
using (var file = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var readstream = new IsolatedStorageFileStream(filePath, System.IO.FileMode.Open, FileAccess.Read, file))
{
// Read the data in the file.
using (var reader = new StreamReader(readstream).BaseStream)
{
var ProtectedPinByte = new byte[reader.Length];
reader.Read(ProtectedPinByte, 0, ProtectedPinByte.Length);
return ProtectedPinByte;
}
}
}
}
}
public class ItemView
{
public string LineOne { get; set; }
public string LineTwo { get; set; }
}
I have found a class from the link ImageCaching
but when i load from isolated storage i got an exeption "System.InvalidOperationException"
here is my code
public static object DownloadFromWeb(Uri imageFileUri)
{
WebClient m_webClient = new WebClient(); //Load from internet
BitmapImage bm = new BitmapImage();
m_webClient.OpenReadCompleted += (o, e) =>
{
if (e.Error != null || e.Cancelled) return;
WriteToIsolatedStorage(IsolatedStorageFile.GetUserStoreForApplication(), e.Result, GetFileNameInIsolatedStorage(imageFileUri));
bm.SetSource(e.Result);
e.Result.Close();
};
m_webClient.OpenReadAsync(imageFileUri);
return bm;
}
public static object ExtractFromLocalStorage(Uri imageFileUri)
{
byte[] data;
string isolatedStoragePath = GetFileNameInIsolatedStorage(imageFileUri); //Load from local storage
if (null == _storage)
{
_storage = IsolatedStorageFile.GetUserStoreForApplication();
}
using (IsolatedStorageFileStream sourceFile = _storage.OpenFile(isolatedStoragePath, FileMode.Open, FileAccess.Read))
{
// Read the entire file and then close it
sourceFile.Read(data, 0, data.Length);
sourceFile.Close();
BitmapImage bm = new BitmapImage();
bm.SetSource(sourceFile);///here got the exeption
return bm;
}
}
so that i can't set the image.
I'm using the converter you mentioned and it works but you modified the method.
Your ExtractFromLocalStorage method isn't the same. You close your stream before to use it with the SetSource method.
Here is the original method code:
private static object ExtractFromLocalStorage(Uri imageFileUri)
{
string isolatedStoragePath = GetFileNameInIsolatedStorage(imageFileUri); //Load from local storage
using (var sourceFile = _storage.OpenFile(isolatedStoragePath, FileMode.Open, FileAccess.Read))
{
BitmapImage bm = new BitmapImage();
bm.SetSource(sourceFile);
return bm;
}
}
I made a project to Cache Images. I want to wait in main thread for complete DownloadImage function and then return that saved bitmap. Is that possible?
Am I doing it even properly?
public static ImageSource GetImage(int id)
{
BitmapImage bitmap = new BitmapImage();
String fileName=string.Format("ImageCache/{0}.jpg", id);
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!myIsolatedStorage.DirectoryExists("ImageCache"))
{
myIsolatedStorage.CreateDirectory("ImageCache");
}
if (myIsolatedStorage.FileExists(fileName))
{
using (IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile(fileName, FileMode.Open, FileAccess.Read))
{
bitmap.SetSource(fileStream);
}
}
else
{
DownloadImage(id);
//HERE - how to wait for end of DownloadImage and then do that below??
using (IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile(fileName, FileMode.Open, FileAccess.Read))
{
bitmap.SetSource(fileStream);
}
}
}
return bitmap;
}
Here is DownloadImage function:
private static void DownloadImage(Object id)
{
WebClient client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
client.OpenReadAsync(new Uri(string.Format("http://example.com/{0}.jpg", id)), id);
}
private static void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (e.Error == null && !e.Cancelled)
{
try
{
string fileName = string.Format("ImageCache/{0}.jpg", e.UserState);
IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(fileName);
BitmapImage image = new BitmapImage();
image.SetSource(e.Result);
WriteableBitmap wb = new WriteableBitmap(image);
// Encode WriteableBitmap object to a JPEG stream.
Extensions.SaveJpeg(wb, fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
fileStream.Close();
}
catch (Exception ex)
{
//Exception handle appropriately for your app
}
}
}
}
You have many way to achieve what you want. It is possible to wait with async await command which is part of Visual Studio Async.
You can download the latest CTP from here. More how to use it.
Personally I would use events.
This one contains some details and code example: http://www.ben.geek.nz/2010/07/one-time-cached-images-in-windows-phone-7/