How can i get the length of a bitmapimage(jpg/png)? - windows-phone-7

When i use this function to save image(fetch from net) to IsolatedStorage, i found the file size is larger than that i save from the webbrowse.
public static bool CreateImageFile(string filePath, BitmapImage bitmapImage)
{
//StreamResourceInfo streamResourceInfo = Application.GetResourceStream(new Uri(filePath, UriKind.Relative));
using (isolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
string directoryName = System.IO.Path.GetDirectoryName(filePath);
if (!string.IsNullOrEmpty(directoryName) && !isolatedStorage.DirectoryExists(directoryName))
{
isolatedStorage.CreateDirectory(directoryName);
}
if (isolatedStorage.FileExists(filePath))
{
isolatedStorage.DeleteFile(filePath);
}
//bitmapImage
using (IsolatedStorageFileStream fileStream = isolatedStorage.OpenFile(filePath, FileMode.Create, FileAccess.Write))
{
bitmapImage.CreateOptions = BitmapCreateOptions.None;
WriteableBitmap wb = new WriteableBitmap(bitmapImage);
wb.SaveJpeg(fileStream, wb.PixelWidth, wb.PixelHeight, 0, 100);
fileStream.Close();
}
}
return true;
}
Is that ok to save png images using WriteableBitmap.SaveJpeg(...)?
And is there any function to get the length of BitmapImage?

If it is a PNG, why would you use SaveJpeg to actually store it? Why not simply use the standard "data-to-file" approach? If it is already encoded as a PNG, all you need to do is store the content.
Read more here:
How to: Store Files and Folders for Windows Phone
Writing Data (Windows Phone)

Convert to byte array
byte[] data;
using (MemoryStream ms = new MemoryStream()
{
bitmapImage.SaveJpeg(ms, LoadedPhoto.PixelWidth, LoadedPhoto.PixelHeight, 0, 95);
ms.Seek(0, 0);
data = new byte[ms.Length];
ms.Read(data, 0, data.Length);
ms.Close();
}
Then just get the size of the byte array and convert to something more reasonable (KB, MB...)

Related

Rgb 565 Pdf to Image

I am trying to convert a PDF page to an image, to create thumbnails. This is the code that I am using:
PdfRenderer pdfRenderer = new PdfRenderer(GetSeekableFileDescriptor(filePath));
var appDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
string directoryPath = System.IO.Path.Combine(appDirectory, "thumbnailsTemp", System.IO.Path.GetFileNameWithoutExtension(fileName));
if (!Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
int pageCount = pdfRenderer.PageCount;
for (int i = 0; i < pageCount; i++)
{
Page page = pdfRenderer.OpenPage(i);
Android.Graphics.Bitmap bmp = Android.Graphics.Bitmap.CreateBitmap(page.Width, page.Height, Android.Graphics.Bitmap.Config.Rgb565 or Argb8888);
page.Render(bmp, null, null, PdfRenderMode.ForDisplay);
try
{
using (FileStream output = new FileStream(System.IO.Path.Combine(directoryPath, fileName + "Thumbnails" + i + ".png"), FileMode.Create))
{
bmp.Compress(Android.Graphics.Bitmap.CompressFormat.Png, 100, output);
}
page.Close();
}
catch (Exception ex)
{
//TODO -- GERER CETTE EXPEXPTION
throw new Exception();
}
}
return directoryPath;
}
I tried with ARGB 8888 and that was a success. But the rendering time was too slow for big PDF files. This is why I tried to improve it by changing the format to RGB 565. But my app is crashing with this Execption:
Unsuported pixel format
Any idea to fix this, or how to render a PDF to a bitmap faster? I was looking on google but didn't find a solution related to my code.
UPDATE
I did this but know, my app is crashing at this line of code :
await Task.Run(() =>
{
bytes = page.AsPNG(72);
});
My class :
public async Task<string> GetBitmaps(string filePath)
{
//TODO -- WORK ON THIS
PdfRenderer pdfRenderer = new PdfRenderer(GetSeekableFileDescriptor(filePath));
var appDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
string directoryPath = System.IO.Path.Combine(appDirectory, "thumbnailsTemp", System.IO.Path.GetFileNameWithoutExtension(fileName));
var stream = new MemoryStream();
using (Stream resourceStream = new FileStream(filePath, FileMode.Open))
{
resourceStream.CopyTo(stream);
}
for (int i = 0; i < pdfRenderer.PageCount; i++)
{
TallComponents.PDF.Rasterizer.Page page = new TallComponents.PDF.Rasterizer.Page(stream, i);
byte[] bytes = null;
await Task.Run(() =>
{
bytes = page.AsPNG(72);
});
using (FileStream output = new FileStream(System.IO.Path.Combine(directoryPath, fileName + "Thumbnails" + i + ".png"), FileMode.Create, FileAccess.Write))
{
output.Write(bytes, 0, bytes.Length);
}
}
return directoryPath;
}
you could draw a PDF page in app by converting a PDF page to a bitmap,here the PDF document itself is embedded as a resource.
var assembly = Assembly.GetExecutingAssembly();
var stream = new MemoryStream();
using (Stream resourceStream = assembly.GetManifestResourceStream("DrawPdf.Android.tiger.pdf"))
{
resourceStream.CopyTo(stream);
}
Page page = new Page(stream, 0);
// render PDF Page object to a Bitmap
byte[] bytes = null;
await Task.Run(() =>
{
bytes = page.AsPNG(72);
});
Bitmap bmp = global::Android.Graphics.BitmapFactory.DecodeByteArray(bytes, 0, bytes.Length);

Windows 8.1 store xaml save InkManager in a string

I'm trying to save what i have drawn with the pencil as a string , and i do this by SaveAsync() method to put it in an IOutputStream then convert this IOutputStream to a stream using AsStreamForWrite() method from this point things should go fine, however i get a lot of problems after this part , if i use for example this code block:
using (var stream = new MemoryStream())
{
byte[] buffer = new byte[2048]; // read in chunks of 2KB
int bytesRead = (int)size;
while (bytesRead < 0)
{
stream.Write(buffer, 0, bytesRead);
}
byte[] result = stream.ToArray();
// TODO: do something with the result
}
i get this exception
"Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection."
or if i try to convert the stream into an image using InMemoryRandomAccessStream like this:
InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
await s.CopyToAsync(ras.AsStreamForWrite());
my InMemoryRandomAccessStream variable is always zero in size.
also tried
StreamReader.ReadToEnd();
but it returns an empty string.
found the answer here :
http://social.msdn.microsoft.com/Forums/windowsapps/en-US/2359f360-832e-4ce5-8315-7f351f2edf6e/stream-inkmanager-strokes-to-string
private async void ReadInk(string base64)
{
if (!string.IsNullOrEmpty(base64))
{
var bytes = Convert.FromBase64String(base64);
using (var inMemoryRAS = new InMemoryRandomAccessStream())
{
await inMemoryRAS.WriteAsync(bytes.AsBuffer());
await inMemoryRAS.FlushAsync();
inMemoryRAS.Seek(0);
await m_InkManager.LoadAsync(inMemoryRAS);
if (m_InkManager.GetStrokes().Count > 0)
{
// You would do whatever you want with the strokes
// RenderStrokes();
}
}
}
}

.net mvc3 iTextSharp how to add image to pdf in memory stream and return to browser

I have a .pdf file stored in my database, and I have a signature file (.png) stored in my database. I am trying to use iTextSharp to add the signature image to the .pdf file, and display the result to the browser.
Here is my code:
byte[] file = Repo.GetDocumentBytes(applicantApplication.ApplicationID, documentID);
byte[] signatureBytes = Repo.GetSignatureBytes((Guid)applicantApplicationID, signatureID);
iTextSharp.text.Image signatureImage = iTextSharp.text.Image.GetInstance(signatureBytes);
iTextSharp.text.Document document = new iTextSharp.text.Document();
using (System.IO.MemoryStream ms = new System.IO.MemoryStream(file, 0, file.Length, true, true))
{
PdfWriter writer = PdfWriter.GetInstance(document, ms);
document.Open();
signatureImage.SetAbsolutePosition(200, 200);
signatureImage.ScaleAbsolute(200, 50);
document.Add(signatureImage);
document.Close();
return File(ms.GetBuffer(), "application/pdf");
}
The page loads, and there is a .pdf with a signature, but the original document is nowhere to be found. It looks like I'm creating a new .pdf file and putting the image in there instead of editing the old .pdf file.
I have verified that the original .pdf document is being loaded into the "file" variable. I have also verified that the length of the MemoryStream "ms" is the same as the length of the byte[] "file".
I ended up doing something like this in my repository:
using (Stream inputPdfStream = new MemoryStream(file, 0, file.Length, true, true))
using (Stream inputImageStream = new MemoryStream(signatureBytes, 0, signatureBytes.Length, true, true))
using (MemoryStream outputPdfStream = new MemoryStream())
{
var reader = new PdfReader(inputPdfStream);
var stamper = new PdfStamper(reader, outputPdfStream);
var cb = stamper.GetOverContent(1);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(inputImageStream);
image.SetAbsolutePosition(400, 100);
image.ScaleAbsolute(200, 50);
cb.AddImage(image);
stamper.Close();
return outputPdfStream.GetBuffer();
}
I adapted it from a few other answers on StackOverflow

How to speed up the unzip action on windows phone 7?

When I used the SharpZipLib to unzip a zip file which has 5000 files on the windows phone 7. It took more than 5 minutes to finish it.
Here is the code:
using (StreamReader httpwebStreamReader = new StreamReader(ea.Result))
{
//open isolated storage to save files
using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
using (ZipInputStream s = new ZipInputStream(httpwebStreamReader.BaseStream))
{
//s.Password = "123456";//if archive is encrypted
ZipEntry theEntry;
while ((theEntry = s.GetNextEntry()) != null)
{
string directoryName = Path.GetDirectoryName(theEntry.Name);
string fileName = Path.GetFileName(theEntry.Name);
// create directory
if (directoryName.Length > 0)
{
isoStore.CreateDirectory(directoryName);
}
if (fileName != String.Empty)
{
//save file to isolated storage
using (BinaryWriter streamWriter =
new BinaryWriter(new IsolatedStorageFileStream(theEntry.Name,
FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write, isoStore)))
{
int size = 2048;
byte[] data = new byte[2048];
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0)
{
streamWriter.Write(data, 0, size);
}
else
{
break;
}
}
}
}
}
}
}
}
Why it's so slow?
How can I speed up the unzip action?
Anyone knows?
I think you need to increase your buffer size. Change the lines
int size = 2048;
byte[] data = new byte[2048];
And change the 2048 to something like 32768 (32*1024).
A 2KB block size is making a lot of individual writes to the flash storage. In my experience that's a somewhat slow thing and can vary from device to device. A 32KB block size should do 16 times fewer but I don't know if that will result in a direct 16x speedup. I'm interested to hear back.

In Windows Phone 7 how can I save a BitmapImage to local storage?

In Windows Phone 7 how can I save a BitmapImage to local storage? I need to save the image for caching and reload if it is requested again in the next few days.
If you save the file into IsolatedStorage you can set a relative path to view it from there.
Here's a quick example saving a file that was included in the XAP (as a resource) into Isolated Storage.
using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!isoStore.FileExists(fileName)
{
var sr = Application.GetResourceStream(new Uri(fileName, UriKind.Relative));
using (var br = new BinaryReader(sr.Stream))
{
byte[] data = br.ReadBytes((int)sr.Stream.Length);
string strBaseDir = string.Empty;
const string DelimStr = "/";
char[] delimiter = DelimStr.ToCharArray();
string[] dirsPath = fileName.Split(delimiter);
// Recreate the directory structure
for (int i = 0; i < dirsPath.Length - 1; i++)
{
strBaseDir = Path.Combine(strBaseDir, dirsPath[i]);
isoStore.CreateDirectory(strBaseDir);
}
using (BinaryWriter bw = new BinaryWriter(isoStore.CreateFile(fileName)))
{
bw.Write(data);
}
}
}
}
You may also be interested in the image caching converters created by Ben Gracewood and Peter Nowaks. They both show saving images into isolated storage and loading them from there.
Another approach I've used is to pass the stream you retrieve for the image in your xap straight into an isolated storage file. Not a lot of moving parts.
using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication()) {
var bi = new BitmapImage();
bi.SetSource(picStreamFromXap);
var wb = new WriteableBitmap(bi);
using (var isoFileStream = isoStore.CreateFile("pic.jpg"))
Extensions.SaveJpeg(wb, isoFileStream, wb.PixelWidth, wb.PixelHeight, 0, 100);
}

Resources