Converting byte[] to pdf, rotating 180 degrees, back to byte[] and to response.outputstream - arrays

I am trying to rotate a pdf document 180 degrees. Stored as a byte[] initially, it should be returned to the same, so that I can write it to the outputstream to our customers. This is my working code without rotation:
if (pdfurl == null)
return View(errorview);
var response = Response;
var getbyteresult = WebService.GetPDFAsByteArray(pdfurl);
MemoryStream ms = new MemoryStream(getbyteresult);
response.Clear();
response.ContentType = "application/pdf";
response.AddHeader("content-disposition",
"attachment;filename=label.pdf");
response.Buffer = true;
ms.WriteTo(response.OutputStream);
response.End();
return View("~/Views/Order/pdf.cshtml");
I've tried several libraries (itext, freesharp, spire), none of correctly manipulates and outputs.
Thanks in advance,
Rasmus Edvardsen
EDIT: The language is C#, and it's an MVC web application.
EDIT2: John's answer solved my problem - I also had an outdated verison of itextsharp, so that answers why most other solutions I tried failed the same way.
Never meant to come off as arrogant or anything, but I realise that's how it came out. Sorry and thanks.

Looking at your sample code it seems to me that you are using C# so here's a spoon feed for you.
Using iTextSharp:
private byte[] RotatePDF(byte[] pdfBytes, int rotation)
{
byte[] renderedBytes = null;
using (MemoryStream ms = new MemoryStream())
{
Document document = new Document();
PdfCopy pdf = new PdfCopy(document, ms);
PdfReader pdfReader = null;
PdfStamper stamper = null;
try
{
document.Open();
pdfReader = new PdfReader(pdfBytes);
stamper = new PdfStamper(pdfReader, ms);
for (int i = 1; i <= pdfReader.NumberOfPages; i++)
{
PdfDictionary pageDict = pdfReader.GetPageN(i);
PdfNumber pdfRotation = pageDict.GetAsNumber(PdfName.ROTATE);
if (pdfRotation != null)
{
rotation += pdfRotation.IntValue;
rotation %= 360;
}
pageDict.Put(PdfName.ROTATE, new PdfNumber(rotation));
}
pdf.AddDocument(pdfReader);
pdfReader.Close();
}
catch (Exception)
{
renderedBytes = null;
}
finally
{
if (pdfReader != null)
{
pdfReader.Close();
}
if (document != null)
{
document.Close();
}
}
renderedBytes = ms.ToArray();
return renderedBytes;
}
}
Usage:
var getbyteresult = WebService.GetPDFAsByteArray(pdfurl);
getbyteresult = RotatePDF(getbyteresult, 180); // 90 180 270 360

Related

Implementing safe areas with Infinite Container pull to refresh

How can I set the safe area for pull to refresh? I have a form with with an infinite container. I set the IC with safe area ic.setSafeArea(true). When I rotate the screen the safe area is respected(see image 1). If i pull to refresh the safe area is not respected (see image 2). With the below code taken from the InfiniteContainerSample, how can I ensure the safe area is respected after pull to refresh?
image 1
public void showForm() {
Form hi = new Form("InfiniteContainer", new BorderLayout());
Style s = UIManager.getInstance().getComponentStyle("MultiLine1");
FontImage p = FontImage.createMaterial(FontImage.MATERIAL_PORTRAIT, s);
EncodedImage placeholder = EncodedImage.createFromImage(p.scaled(p.getWidth() * 3, p.getHeight() * 3), false);
InfiniteContainer ic = new InfiniteContainer() {
#Override
public Component[] fetchComponents(int index, int amount) {
java.util.List<Map<String, Object>> data = fetchPropertyData("Leeds");
MultiButton[] cmps = new MultiButton[data.size()];
for(int iter = 0 ; iter < cmps.length ; iter++) {
Map<String, Object> currentListing = data.get(iter);
if(currentListing == null) {
return null;
}
String thumb_url = (String)currentListing.get("thumb_url");
String guid = (String)currentListing.get("guid");
String summary = (String)currentListing.get("summary");
cmps[iter] = new MultiButton(summary);
cmps[iter].setIcon(URLImage.createToStorage(placeholder, guid, thumb_url));
}
return cmps;
}
};
ic.setUIID("Blue");
ic.setSafeArea(true);
ic.addComponent(new Label("This is a test"));
hi.add(BorderLayout.CENTER, ic);
hi.show();
}
int pageNumber = 1;
java.util.List<Map<String, Object>> fetchPropertyData(String text) {
try {
ConnectionRequest r = new ConnectionRequest();
r.setPost(false);
r.setUrl("http://api.nestoria.co.uk/api");
r.addArgument("pretty", "0");
r.addArgument("action", "search_listings");
r.addArgument("encoding", "json");
r.addArgument("listing_type", "buy");
r.addArgument("page", "" + pageNumber);
pageNumber++;
r.addArgument("country", "uk");
r.addArgument("place_name", text);
NetworkManager.getInstance().addToQueueAndWait(r);
Map<String,Object> result = new JSONParser().parseJSON(new InputStreamReader(new ByteArrayInputStream(r.getResponseData()), "UTF-8"));
Map<String, Object> response = (Map<String, Object>)result.get("response");
return (java.util.List<Map<String, Object>>)response.get("listings");
} catch(Exception err) {
Log.e(err);
return null;
}
}
Thanks for reporting this. This has been fixed on github. It will be included in the next release on Friday.

WPF print document in background

I've a realtime wpf application and sometimes I need to printout a document on a LAN printer. This is a part of my code:
using (PrintDocument prnDocument = new PrintDocument())
{
prnDocument.PrintPage += new PrintPageEventHandler(prnDocument_PrintPage);
if (!string.IsNullOrEmpty(printFile))
{
ImageFormat format = ImageFormat.Png;
float scale = 1; // Convert.ToSingle(_Scale.Value) / 100f;
long quality = 75; // Convert.ToInt64(_Quality.Value);
//string output = ""; // _TextBoxOutput.Text;
PaperSize ps = new PaperSize("label", panel.Width, panel.Height);
panel.BorderStyle = panelBorder ? BorderStyle.FixedSingle : BorderStyle.None;
prnDocument.DefaultPageSettings.PaperSize = ps;
prnDocument.DefaultPageSettings.Margins.Left = 0;
prnDocument.DefaultPageSettings.Margins.Top = 0;
PrintController controller = new PrintControllerFile(format, scale, quality, printFile);
prnDocument.PrintController = new PrintControllerWithStatusDialog(controller, "Exporting");
}
else
{
PaperSize ps = new PaperSize("label", panel.Width, panel.Height);
panel.BorderStyle = panelBorder ? BorderStyle.FixedSingle : BorderStyle.None;
prnDocument.DefaultPageSettings.PaperSize = ps;
prnDocument.DefaultPageSettings.Margins.Left = 0;
prnDocument.DefaultPageSettings.Margins.Top = 0;
if (!string.IsNullOrEmpty(printerName))
prnDocument.PrinterSettings.PrinterName = printerName;
prnDocument.PrintController = new StandardPrintController();
}
prnDocument.Print();
}
Basically each time the Print() is invoked, my application freeze up till 2-3 seconds, then it resume. I think that during that time I send data to the print spooler.
I've also tryied to use a thread:
System.Threading.Tasks.Task.Run(() => { prnDocument.Print(); });
But nothing seems to change. Any advice?

Displaying image from database in iTextSharp document [duplicate]

I try to create a PDF report from a datatable. One of the columns contents image. How can I extract the image from datatable and insert into PDF table? I'm using iTextShap version 5.4.2.0. Here is the code:
public void Report(DataTable dt, string output)
{
Document doc = new Document(PageSize.LETTER, 50, 50, 80, 50);
PdfWriter PDFWriter = PdfWriter.GetInstance(doc, new FileStream(output, FileMode.Create));
PDFWriter.ViewerPreferences = PdfWriter.PageModeUseOutlines;
iTextSharp.text.Font hel8 = FontFactory.GetFont(BaseFont.HELVETICA, 8);
doc.Open();
PdfPTable table = new PdfPTable(dt.Columns.Count);
float[] widths = new float[] { 1.2f, 1.2f, 1.2f, 1.2f, 1f, 4f, 1f, 4f };
table.SetWidths(widths);
table.WidthPercentage = 100;
PdfPCell cell = new PdfPCell(new Phrase("NewCells"));
cell.Colspan = dt.Columns.Count;
foreach (DataColumn c in dt.Columns)
{
table.AddCell(new Phrase(c.ColumnName, hel8));
}
foreach (DataRow r in dt.Rows)
{
if (dt.Rows.Count > 0)
{
table.AddCell(new Phrase(r[0].ToString(), hel8));
table.AddCell(new Phrase(r[1].ToString(), hel8));
table.AddCell(new Phrase(r[2].ToString(), hel8));
table.AddCell(new Phrase(r[3].ToString(), hel8));
table.AddCell(new Phrase(r[4].ToString(), hel8));
table.AddCell(new Phrase(r[5].ToString(), hel8));
byte[] byt = (byte[])r[6];
MemoryStream ms = new MemoryStream(byt);
System.Drwaing.Image sdi = System.Drawing.Image.FromStream(ms);
Image img = Image.GetInstance(sdi); <-- this is the problem code
table.AddCell(img);
table.AddCell(new Phrase(r[7].ToString(), hel8));
}
}
doc.Add(table);
}
doc.Close();
}
Update: #nekno, all of your suggestions are worked.
But I still need to correct the casting at line:
byte[] byt = (byte[])r[6];
It gave me a casting exception from VS2008. So I added the conversion function (pulled it from stackoverflow):
byte[] ImageToByte(System.Drawing.Image img)
{
byte[] byteArray = new byte[0];
using (MemoryStream stream = new MemoryStream())
{
img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Close();
byteArray = stream.ToArray();
}
return byteArray;
}
And revised the code:
byte[] byt = ImageToByte((System.Drawing.Image)dt.Rows[e][6]);
Thanks.
What exactly is the problem? What happens when you use your problem code?
Try one of the other Image.GetInstance() overloads:
You can pass the byte array directly:
byte[] byt = (byte[])r[6];
Image img = Image.GetInstance(byt);
Or you can pass the Stream:
byte[] byt = (byte[])r[6];
MemoryStream ms = new MemoryStream(byt);
Image img = Image.GetInstance(ms);
Or you can give iTextSharp more info about the image format:
byte[] byt = (byte[])r[6];
MemoryStream ms = new MemoryStream(byt);
System.Drawing.Image sdi = System.Drawing.Image.FromStream(ms);
Image img = Image.GetInstance(sdi, ImageFormat.Png);
If your column can be cast to a System.Drawing.Image, then you can use it directly:
Image img = Image.GetInstance((System.Drawing.Image)r[6], System.Drawing.Imaging.ImageFormat.Png);
I have suggested steps how shows how to add image into PDF, given below code snippet show how to add logo into your PDF using iTextsharp, follow provided below steps:
I have provided link to download "itextsharp" component from given link http://sourceforge.net/projects/itextsharp/
You have to add reference into your application.
Next you have to add required namespaces "iTextsharp.text.html", "iTextsharp.text" to consume its best properties.
Now you have to add code snippet into your application given at the end, add code snippet under "button click" in code behind.
Hope it will work for you !!!
protected void btnPDF_Click(object sender, ImageClickEventArgs e)
{
DataTable dtn = new DataTable();
dtn = GetDataTable();
dtPDF = dtn.Copy();
for (int i = 0; i <= dtn.Rows.Count - 1; i++)
{
ExportToPdf(dtPDF);
}
}
public void ExportToPdf(DataTable myDataTable)
{
Document pdfDoc = new Document(PageSize.A4, 10, 10, 10, 10);
try
{
PdfWriter.GetInstance(pdfDoc, System.Web.HttpContext.Current.Response.OutputStream);
pdfDoc.Open();
Chunk c = new Chunk("" + System.Web.HttpContext.Current.Session["CompanyName"] + "", FontFactory.GetFont("Verdana", 11));
Paragraph p = new Paragraph();
p.Alignment = Element.ALIGN_CENTER;
p.Add(c);
pdfDoc.Add(p);
string clientLogo = Server.MapPath(".") + "/logo/tpglogo.jpg";
string imageFilePath = Server.MapPath(".") + "/logo/tpglogo.jpg";
iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(imageFilePath);
//Resize image depend upon your need
jpg.ScaleToFit(80f, 60f);
//Give space before image
jpg.SpacingBefore = 0f;
//Give some space after the image
jpg.SpacingAfter = 1f;
jpg.Alignment = Element.HEADER;
pdfDoc.Add(jpg);
Font font8 = FontFactory.GetFont("ARIAL", 7);
DataTable dt = myDataTable;
if (dt != null)
{
//Craete instance of the pdf table and set the number of column in that table
PdfPTable PdfTable = new PdfPTable(dt.Columns.Count);
PdfPCell PdfPCell = null;
for (int rows = 0; rows < dt.Rows.Count; rows++)
{
for (int column = 0; column < dt.Columns.Count; column++)
{
PdfPCell = new PdfPCell(new Phrase(new Chunk(dt.Rows[rows][column].ToString(), font8)));
PdfTable.AddCell(PdfPCell);
}
}
//PdfTable.SpacingBefore = 15f; // Give some space after the text or it may overlap the table
pdfDoc.Add(PdfTable); // add pdf table to the document
}
pdfDoc.Close();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment; filename= SampleExport.pdf");
System.Web.HttpContext.Current.Response.Write(pdfDoc);
Response.Flush();
Response.End();
//HttpContext.Current.ApplicationInstance.CompleteRequest();
}
catch (DocumentException de)
{
System.Web.HttpContext.Current.Response.Write(de.Message);
}
catch (IOException ioEx)
{
System.Web.HttpContext.Current.Response.Write(ioEx.Message);
}
catch (Exception ex)
{
System.Web.HttpContext.Current.Response.Write(ex.Message);
}
}

How to insert a youtube video as an attachment to specified timeline item?

Currently attachment takes stream for the content, is it possible to set a youtube video url for the attachment?
Thanks
This is not yet possible with the current version of the API and Glass client. Feel free to file a feature request on our issues tracker.
It is possible to stream a youtube video in the timeline card, here is the C#.Net code. use this name space "YoutubeExtractor".This works fine for me. When getting the youtube video url get the link that comes after you select share.
private static String InsertItem5(MainController controller)
{
string link = "http://youtu.be/9uYKISlL7Vg";
IEnumerable<VideoInfo> videoInfos = DownloadUrlResolver.GetDownloadUrls(link);
VideoInfo video = videoInfos.First(info => info.VideoType == VideoType.Mp4 && info.Resolution == 360);
String vLink = video.DownloadUrl;
TimelineItem critical = new TimelineItem()
{
Text = "Menu Card",
BundleId = "666",
Notification = new NotificationConfig() { Level = "DEFAULT" },
MenuItems = new List<MenuItem>()
{
new MenuItem() {Action = "DELETE"},
}
};
String mediaLink = vLink;
if (!String.IsNullOrEmpty(mediaLink))
{
Stream stream = null;
if (mediaLink.StartsWith("/"))
{
stream = new StreamReader(controller.Server.MapPath(mediaLink)).BaseStream;
}
else
{
HttpWebRequest request = WebRequest.Create(mediaLink) as HttpWebRequest;
request.UseDefaultCredentials = false;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
byte[] b = null;
using (Stream streamFromWeb = response.GetResponseStream())
using (MemoryStream ms = new MemoryStream())
{
int count = 0;
do
{
byte[] buf = new byte[1024];
count = streamFromWeb.Read(buf, 0, 1024);
ms.Write(buf, 0, count);
} while (streamFromWeb.CanRead && count > 0);
b = ms.ToArray();
stream = new MemoryStream(b);
}
}
controller.Service.Timeline.Insert(critical, stream, "video/mp4").Upload();
}
else
{
controller.Service.Timeline.Insert(critical).Fetch();
}

How to save bitmapimage in Isolated storage?

I am developing silverlight web part by using the client object model. I am getting the bitmap image from sharepoint server. Now I want to save this bitmap image in isolated storage. So I am using following code
WriteableBitmap wb = new WriteableBitmap(attachments);
using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream isoStream =
new IsolatedStorageFileStream("abcd1.jpg", FileMode.Create, isoFile))
{
using (StreamWriter sw = new StreamWriter(isoStream))
{
sw.Write(wb.ToByteArray());
}
}
}
Now I am seeing the saved image at location C:\Users\Rent2\AppData\LocalLow\Microsoft\Silverlight\is\vzvpufsm.s4i\m0laonzr.til\1\s\nkhajster01es5wdoyfxd0n5rd2dls3ovyu4wcdig04zjx44hyaaafea\f
When I click on it, it gives me message as "Invalid Image". Can you please tell me how should i write code so that I can see the actual image after saving it in isolated storage ?
private void zipFile()
{
context = Microsoft.SharePoint.Client.ClientContext.Current;
Microsoft.SharePoint.Client.File.OpenBinaryDirect(
context,
#"/TemplateInvoice/" + App.templateFileName + ".xlsx", successFile, FailFile);
}
private void successFile(object sender, OpenBinarySucceededEventArgs args)
{
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
{
// Obtain the isolated storage for an application.
try
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
Stream strm = args.Stream;
using (var isoStream = store.OpenFile(App.templateFileName + ".zip", FileMode.OpenOrCreate))
{
// Read the resource file into a byte array.
bytes = new byte[strm.Length];
int numBytesToRead = (int)strm.Length;
int numBytesRead = 0;
while (numBytesToRead > 0)
{
// Read may return anything from 0 to numBytesToRead.
int n = strm.Read(bytes, numBytesRead, numBytesToRead);
// The end of the file is reached.
if (n == 0)
break;
numBytesRead += n;
numBytesToRead -= n;
}
numBytesToRead = bytes.Length;
// Write the byte array to the IsolatedStorageFileStream.
isoStream.Write(bytes, 0, numBytesToRead);
//isoStream.Dispose();
}
strm.Close();
string path = App.templateFileName + ".zip";
ZipHelp.UnZip(path, System.IO.Path.GetDirectoryName(path), 4096);
replaceFileContent();
string rootDirectory = System.Windows.Browser.HttpUtility.UrlDecode(path);
string fileName = ZipHelp.Zip(rootDirectory.Replace(".zip", ""), invoice);
//string filename = DateTime.Now.Day.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Year.ToString() + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString() + "Invoice1.xlsx";
// Read the resource file into a byte array.
using (var stream = store.OpenFile(fileName, FileMode.Open))
{
bytes = new byte[stream.Length];
int numBytesToRead = (int)stream.Length;
int numBytesRead = 0;
while (numBytesToRead > 0)
{
// Read may return anything from 0 to numBytesToRead.
int n = stream.Read(bytes, numBytesRead, numBytesToRead);
// The end of the file is reached.
if (n == 0)
break;
numBytesRead += n;
numBytesToRead -= n;
}
InvoiceTemplete invoiceTemplate = new InvoiceTemplete(fileName, bytes, SetMessage);
invoiceTemplate.AddDocument(invoiceTemplate);
}
}
//mark rows as billed
foreach (var item in PrivatePayList)
{
MedwaiverViewModel MedwaiverViewModelObj = new MedwaiverViewModel();
MedwaiverViewModelObj.ChangeBillingStatus(item.ListItemId, "Billed");
if (MedwaiverTimeLogList != null)
{
MedwaiverTimeLogList.Remove(item);
}
if (ClientSpecificTimeLogList != null)
{
ClientSpecificTimeLogList.Remove(item);
}
if (rangeBoundTimeLogListForDate != null)
{
rangeBoundTimeLogListForDate.Remove(item);
}
if (vRangeBoundTimeLogListForDateAndClient != null)
{
vRangeBoundTimeLogListForDateAndClient.Remove(item);
}
}
}
catch (IsolatedStorageException isx)
{
MessageBox.Show(isx.Message);
}
});
}
private void FailFile(object sender, OpenBinaryFailedEventArgs e)
{
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Fail");
});
}
//The following class zip and unzip the file
class ZipHelp
{
static List<string> folderPathList = new List<string>();
public static string Zip(string rootDirectory, string fileName)
{
byte[] buffer;
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
IsolatedStorageFileStream zipFileStream = store.CreateFile(fileName + ".xlsx");
ZipOutputStream zipOutStream = new ZipOutputStream(zipFileStream);
zipOutStream.UseZip64 = UseZip64.Off;
//zipOutStream.CanPatchEntries
foreach (var item in folderPathList)
{
string entryName = "";
buffer = new byte[4096];
if (item.Substring(0,1) == #"/")
{
//removes leading /
entryName = item.Substring(1);
}
else
{
entryName = item;
}
ZipEntry entry = new ZipEntry(entryName);
//entry.CompressionMethod = CompressionMethod.Deflated;
//entry.
entry.IsZip64Forced();
//entry.IsDirectory
zipOutStream.PutNextEntry(entry);
using (IsolatedStorageFileStream stream = store.OpenFile(rootDirectory + #"\" + item, FileMode.Open))
{
int size;
do
{
size = stream.Read(buffer, 0, buffer.Length);
zipOutStream.Write(buffer, 0, size);
} while (size > 0);
stream.Close();
}
}
zipOutStream.Close();
zipFileStream.Close();
}
return fileName + ".xlsx";
//string[] directories = GetLocationTypes();
//zip();
//string[] filenames = Directory.GetFiles(directories);
//using (var store = IsolatedStorageFile.GetUserStoreForApplication())
//{
// using (var isoStream = store.OpenFile("#" + rootDirectory, FileMode.OpenOrCreate))
// {
// //foreach(string dir in
// }
//}
}
private static string[] GetLocationTypes()
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
return store.GetDirectoryNames();
}
}
/// <summary>
/// UnZip a file
/// </summary>
/// <param name="SrcFile">source file path</param>
/// <param name="DstFile">unzipped file path</param>
/// <param name="BufferSize">buffer to use</param>
public static void UnZip(string SrcFile, string DstFile, int BufferSize)
{
folderPathList.Clear();
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
FileStream fileStreamIn = store.OpenFile(SrcFile, FileMode.Open, FileAccess.Read);
ZipInputStream zipInStream = new ZipInputStream(fileStreamIn);
string rootDirectory = System.Windows.Browser.HttpUtility.UrlDecode(SrcFile);
rootDirectory = rootDirectory.Replace(".zip", "");
store.CreateDirectory(rootDirectory);
while (true)
{
ZipEntry entry = zipInStream.GetNextEntry();
if (entry == null)
break;
if (entry.Name.Contains("/"))
{
string[] folders = entry.Name.Split('/');
string lastElement = folders[folders.Length - 1];
var folderList = new List<string>(folders);
folderList.RemoveAt(folders.Length - 1);
folders = folderList.ToArray();
string folderPath = "";
foreach (string str in folders)
{
folderPath = folderPath + "/" + str;
if (!store.DirectoryExists(rootDirectory + "/" + folderPath))
{
store.CreateDirectory(rootDirectory + "/" + folderPath);
}
}
folderPath = folderPath + "/" + lastElement;
writeToFile(BufferSize, fileStreamIn, zipInStream, rootDirectory, folderPath);
}
else
{
writeToFile(BufferSize, fileStreamIn, zipInStream, rootDirectory, entry.Name);
}
}
zipInStream.Close();
fileStreamIn.Close();
}
private static void writeToFile(int BufferSize, FileStream fileStreamIn, ZipInputStream zipInStream, string rootDirectory, string folderPath)
{
IsolatedStorageFile store1 = IsolatedStorageFile.GetUserStoreForApplication();
FileStream fileStreamOut = store1.OpenFile(rootDirectory + "/" + folderPath, FileMode.Create, FileAccess.Write);
folderPathList.Add(folderPath);
int size;
byte[] buffer = new byte[BufferSize];
do
{
size = zipInStream.Read(buffer, 0, buffer.Length);
fileStreamOut.Write(buffer, 0, size);
} while (size > 0);
fileStreamOut.Close();
}
}
I can think of two viable options here.
In your code above, save off the Pixels array of the WriteableBitmap. Then to restore it, you would create a WriteableBitmap of the appropriate size and the set the Pixels array to the stored data.
-or-
Use a HttpWebRequest or WebClient request to get the raw image stream and save that to IsolatedStorage.
There are pros and cons to each of these, in the first case the data is uncompressed and will take up more space in isolated storage and you would not be able to open the image from disk outside of Silverlight, similar to the issue you had above. For the second option you can run into cross domain issues if the images are on a different server than your Silverlight XAP file and it's also a bit more complex to implement.
The basic problem is that you're storing the decoded RGBA pixels array as a JPEG file - but they're not the same. Your code is basically correct: you just can't use this method to store it as a JPEG file. But if you happen to know that the image is, say, 800x600, you could create an 800x600 WriteableBitmap, and then set the Pixels property to the retrieved stream's byte array. Or if you don't know the dimensions when you're retrieving it, you could store the dimensions as the first two integers in the stream (before you write the pixels to the stream), and read out the dimensions when you're reading the file. You'd effectively be creating your own very simplistic .bmp format.

Resources