everyone, I've met an strange problem when saving picture to media library, my application crashed without rising an exception. Here is my saving code.
using (MemoryStream stream = new MemoryStream())
{
try
{
WriteableBitmap bitmap = new WriteableBitmap(InkPrest, InkPrest.RenderTransform); // Crash here, the actualHeight of InkPrest is 2370.0
bitmap.SaveJpeg(stream, (int)InkPrest.ActualWidth, (int)InkPrest.ActualHeight, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
MediaLibrary library = new MediaLibrary();
library.SavePicture(DateTime.Now.ToString(), stream.GetBuffer());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I have debuged step by step, the app crash at
WriteableBitmap bitmap = new WriteableBitmap(InkPrest, InkPrest.RenderTransform); // Crash here, the actualHeight of InkPrest is 2370.0
Any idea on solving this problem?
============================================
Try to save several images
The uielement is 704 * 2370
TranslateTransform transform = new TranslateTransform();
transform.Transform(new Point(0,0));
double MaxHeight = 800;
double height = InkPrest.ActualHeight;
int saveCount = 0;
int succeedCount = 0;
while (height > 0)
{
using (MemoryStream stream = new MemoryStream())
{
try
{
double actualRenderHeight = Math.Min(height, MaxHeight);
WriteableBitmap bitmap = new WriteableBitmap((int)InkPrest.ActualWidth, (int)actualRenderHeight);
bitmap.Render(InkPrest, transform); //Crash here, also no exception.
bitmap.Invalidate();
height -= actualRenderHeight;
transform.Y -= actualRenderHeight;
bitmap.SaveJpeg(stream, (int)InkPrest.ActualWidth, (int)actualRenderHeight, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
MediaLibrary library = new MediaLibrary();
Picture pic = library.SavePicture(manuscriptFile.Title + DateTime.Now.ToString(), stream.GetBuffer());
saveCount++;
if (pic != null)
{
succeedCount++;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
Check whether you are instantiating writeablebitmap in uithread or some other created thread. you need to create writeablebitmap in uithread.
Related
I am getting error width cannot be null , when passing image to inputstream.As i didn't find any alterante method . Basically i want to convert image to Pdf format in Xamarin.forms which supports UWP platform .
I am using xfinium pdf library for this.
public void ConvertJpegToPdf()
{
try
{
PdfFixedDocument document = new PdfFixedDocument();
Xfinium.Pdf.PdfPage page = document.Pages.Add();
page.Width = 800;
page.Height = 600;
var imageStream = GetStream();
PdfJpegImage jpeg = new PdfJpegImage(imageStream);//<-Error
PdfStandardFont helvetica = new PdfStandardFont(PdfStandardFontFace.Helvetica, 24);
PdfBrush brush = new PdfBrush(PdfRgbColor.Red);
page.Graphics.DrawImage(jpeg, 0, 0, page.Width, page.Height);
Stream pdfStream = null;
document.Save(pdfStream);
}
catch (Exception ex)
{
throw ex;
}
}
protected Stream GetStream()
{
byte[] byteArray = Encoding.UTF8.GetBytes("http://david.qservicesit.com/images/3.jpg");
MemoryStream stream = new MemoryStream(byteArray);
return stream;
}
Please suggest some alternate to do this
byte[] byteArray = Encoding.UTF8.GetBytes("http://david.qservicesit.com/images/3.jpg");
You could not get image stream in this way. The method you have used can only get the Bytes of string. For your scenario, you could use http client to acquire image stream. Please refer to the following code:
public async Task<Stream> GetStream()
{
HttpClient client = new HttpClient();
HttpResponseMessage res = await client.GetAsync(new Uri("http://david.qservicesit.com/images/3.jpg"));
Stream stream = await res.Content.ReadAsStreamAsync();
return stream;
}
public async Task ConvertJpegToPdf()
{
try
{
PdfFixedDocument document = new PdfFixedDocument();
Xfinium.Pdf.PdfPage page = document.Pages.Add();
page.Width = 800;
page.Height = 600;
var imageStream = await GetStream();
PdfJpegImage jpeg = new PdfJpegImage(imageStream);
PdfStandardFont helvetica = new PdfStandardFont(PdfStandardFontFace.Helvetica, 24);
PdfBrush brush = new PdfBrush(PdfRgbColor.Red);
page.Graphics.DrawImage(jpeg, 0, 0, page.Width, page.Height);
Stream pdfStream = new MemoryStream();
document.Save(pdfStream);
}
catch (Exception ex)
{
throw ex;
}
}
i have searched all over the internet for this but i haven't really got the answer to this.
Part of the app am creating requires the user to take a photo and this photo is saved to the local database. i tried doing this as below but the method requires me to pass a bitmap (System.Windows.Media.Imaging) and the image control is well Image (System.Windows.Controls.Image)
public byte[] convertToByte(BitmapImage img)
{
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap btmap = new WriteableBitmap(img.PixelWidth, img.PixelHeight);
Extensions.SaveJpeg(btmap, ms, img.PixelWidth, img.PixelHeight, 0, 100);
ms.Seek(0, SeekOrigin.Begin);
return ms.ToArray();
};
}
the other solution i tried assumes my image is located within the app which is not the case as it is captured by the camera
public byte[] convertToByte(Image img)
{
BitmapImage image = new BitmapImage();
image.CreateOptions = BitmapCreateOptions.None;
image.UriSource = new Uri(img.Source.ToString(), UriKind.Relative);
WriteableBitmap wbmp = new WriteableBitmap(image);
MemoryStream ms = new MemoryStream();
wbmp.SaveJpeg(ms, wbmp.PixelWidth, wbmp.PixelHeight, 0, 100);
return ms.ToArray();
}
How can i redefine either of the methods to save the image? or is there a better way to do this?
Thanks in advance.
So i finally figured the answer to this a while back.
The things i've been through in the pursuit of this!
public Byte[] ImageToByteArray(Image img)
{
try
{
MemoryStream ms = new MemoryStream();
WriteableBitmap bmp = new WriteableBitmap(img.Source as BitmapSource);
bmp.SaveJpeg(ms, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
Byte[] bytImage = ms.GetBuffer();
return bytImage;
}
catch (Exception ex)
{
return null;
}
}
Hope anyone who gets a similar problem gets helped!
I have a class that uses the devices camera to capture an image. My aim is to pass the captured image to a canvas on another layout.
This layout will then be saved along with a note entered into a textbox.I have figured out how to save the note and title and allow it to be opened but I'm not sure how I would go about passing the captured image to the layout and saving it along with the note.
Does anyone have any advice or pointers as to how I would go about this?
At the moment this is how I'm attempting to read the image file back to the layout after it is saved,but I'm not sure how to read a file into the canvas so obviously this solution isn't working yet:
if (NavigationContext.QueryString.ContainsKey("note"))
{
string s2 = ".jpg";
string filename = this.NavigationContext.QueryString["note"];
if (!string.IsNullOrEmpty(filename)) {
using (var store = System.IO.IsolatedStorage.IsolatedStorageFile .GetUserStoreForApplication())
using (var stream = new IsolatedStorageFileStream(filename, FileMode.Open, FileAccess.ReadWrite, store))
/*
if(filename.Contains(s2))
{
StreamReader reader = new StreamReader(stream);
this.capturedNoteCanvas = reader.ReadToEnd();
this.noteNameTb.Text = filename; reader.Close();
}
else
*/
{
StreamReader reader = new StreamReader(stream);
this.noteDataTb.Text = reader.ReadToEnd();
this.noteNameTb.Text = filename; reader.Close();
}
}
}
What I'm thinking is something like this:
Working wit CameraCaptureTask and Bitmaps
//Taking a writableBitmap object from cameracapturetask
void cameracapturetask_Completed(object sender, PhotoResult e)
{
try
{
if (e.TaskResult == TaskResult.OK)
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto);
WritableBitmap wb=new WritableBitmap (bmp.PixelWidth,bmp.PixelHeight);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
saving wb in storage
using (MemoryStream stream = new MemoryStream())
{
wb.SaveJpeg(stream, (int)bmp.PixelWidth, (int)bmp.PixelHeight, 0, 100);
using (IsolatedStorageFileStream local = new IsolatedStorageFileStream(App.PageName, FileMode.Create, mystorage))
{
local.Write(stream.GetBuffer(), 0, stream.GetBuffer().Length);
}
}
//Taking a WritableBitmap from canvas
If your canvas is containing the image, and also the canvas it attributed with some height and width properties then
WritableBitmap wb= new WritableBitmap(canvascontrol,null);
takes the canvas and saves it inside a writablebitmap object which can then be used for further image manipulations.
I'm trying load image from Picture Hub through this...
void photoChooser_Completed(object sender, PhotoResult e)
{
try
{
var imageVar = new BitmapImage();
imageVar.SetSource(e.ChosenPhoto);
var b = new WriteableBitmap(imageVar.PixelWidth, imageVar.PixelHeight);
b.LoadJpeg(toStream(imageVar));//here comes the exception
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Stream toStream(BitmapImage img)
{
WriteableBitmap bmp = new WriteableBitmap((BitmapSource)img);
using (MemoryStream stream = new MemoryStream())
{
bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
return stream;
}
}
Giving an error occurred when accessing the isolotedstorage. please help !
If I understand correctly, you are trying to:
Get image from a chooser (stream)
Create a bitmap object
Write it to another stream
Create a WriteableBitmap from that second stream
This is seriously convoluted. All you have to do is this:
var imageVar = new BitmapImage();
imageVar.SetSource(e.ChosenPhoto);
var b = new WriteableBitmap(imageVar.PixelWidth, imageVar.PixelHeight);
b.SetSource(e.ChosenPhoto);
This will get you the photo, but have in mind that if you first create a BitmapImage using the SetSource method, it will limit the size of your photo to be under 2000x2000. Then the WriteableBitmap will also be of that smaller, reduced size.
If you wish to create a full sized WriteableBitmap using LoadJpeg method, you need to do this:
//DO SOMETHING TO GET THE PIXEL WIDTH AND PIXEL HEIGHT OF PICTURE BASED JUST ON THE STREAM, FOR EXAMPLE USE EXIF READER: http://igrali.com/2011/11/01/reading-and-displaying-exif-photo-data-on-windows-phone/ OR SEE MORE ABOUT LOADING A LARGE PHOTO HERE: http://igrali.com/2012/01/03/how-to-open-and-work-with-large-photos-on-windows-phone/
var b = new WriteableBitmap(PixelWidth, PixelHeight);
b.LoadJpeg(e.ChosenPhoto);
That will load you the full sized JPEG.
The code you've used looks okay !
void photoChooser_Completed(object sender, PhotoResult e)
{
try
{
var imageVar = new BitmapImage();
imageVar.SetSource(e.ChosenPhoto);
var b = new WriteableBitmap(imageVar.PixelWidth, imageVar.PixelHeight);
b.LoadJpeg(toStream(imageVar));//here comes the exception
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Stream toStream(BitmapImage img)
{
WriteableBitmap bmp = new WriteableBitmap((BitmapSource)img);
using (MemoryStream stream = new MemoryStream())
{
bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
return stream;
}
}
Try reconnecting USB !
You didnot specify, what you want to perform after fetching the Image.
If all you want is to display the image in your app, then you follow this code:
In your try block, simply add this
var imageVar = new BitmapImage();
imageVar.SetSource(e.ChosenPhoto);
Image img = new Image();
img.Source = imageVar;
this.ContentPanel.Children.Add(img);
I want to programmatically create a thumbnail from a folder of images, that would look similar to the Windows 7 images folder style like the pic I uploaded here. I have a routine that will add images on top of each other, and rotating them in the x-axis, but I think I need some Y rotation or something to make this illusion complete. I have actually done this with the Windows7APICodePack with the thumbnail methods there, but it seems to force you to have Explorer in the Large Icons mode. I do not want this to depend on Explorer. Nor do I want to use WPF (ViewPort3d). Here is what I want it to look like:
FinalImage http://www.chuckcondron.com/folderexample.JPG
Here is what I have done so far:
StitchedImageThumb http://www.chuckcondron.com/stitchedImageThumb.jpg
As you can see my attempt is not that pretty, nor do the pics come out of the cream color folder (really could use the actual folder pic as well, but not sure how to do that).
current code (c#)
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
namespace ThumbnailCreator
{
public partial class Form1: Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//get all the files in a directory
string[] files = Directory.GetFiles(#"C:\MyImages");
//combine them into one image
Bitmap stitchedImage = Combine(files);
if(File.Exists("stitchedImage.jpg")) File.Delete("stitchedImage.jpg");
//save the new image
stitchedImage.Save(#"stitchedImage.jpg", ImageFormat.Jpeg);
if (File.Exists("stitchedImage.jpg"))
{
FileStream s = File.Open("stitchedImage.jpg", FileMode.Open);
Image temp = Image.FromStream(s);
s.Close();
pictureBox1.Image = temp;
}
CreateThumb(#"stitchedImage.jpg", #"stitchedImageThumb.jpg");
}
public Bitmap Combine(string[] files)
{
//read all images into memory
List<Bitmap> images = new List<Bitmap>();
Bitmap finalImage = null;
try
{
int width = 0;
int height = 0;
int rotate = 7;
foreach (string image in files)
{
//create a Bitmap from the file and add it to the list
Bitmap bitmap = new Bitmap(image);
bitmap = RotateImage(bitmap, rotate);
//update the size of the final bitmap
//width += bitmap.Width;
width = 2500;
//height = bitmap.Height > height ? bitmap.Height : height;
height = 1000;
images.Add(bitmap);
rotate += 5;
}
//create a bitmap to hold the combined image
finalImage = new Bitmap(width, height);
//get a graphics object from the image so we can draw on it
using (Graphics g = Graphics.FromImage(finalImage))
{
//set background color
g.Clear(Color.Goldenrod);
//go through each image and draw it on the final image
ImageAttributes ia = new ImageAttributes();
ColorMatrix cm = new ColorMatrix();
cm.Matrix33 = 0.75f;
ia.SetColorMatrix(cm);
foreach (Bitmap image in images)
{
Image rotatedImage = new Bitmap(image);
g.DrawImage(rotatedImage, new Rectangle(0, 0, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, ia);
}
}
return finalImage;
}
catch (Exception ex)
{
if (finalImage != null)
finalImage.Dispose();
throw ex;
}
finally
{
//clean up memory
foreach (System.Drawing.Bitmap image in images)
{
image.Dispose();
}
}
}
public void CreateThumb(string source, string destination)
{
Image imgThumb = null;
try
{
Image image = null;
// Check if image exists
image = Image.FromFile(source);
if (image != null)
{
imgThumb = image.GetThumbnailImage(100, 100, null, new IntPtr());
imgThumb.Save(destination);
image.Dispose();
}
}
catch
{
MessageBox.Show("An error occured");
}
if (File.Exists(destination))
{
FileStream s = File.Open(destination, FileMode.Open);
Image temp = Image.FromStream(s);
s.Close();
pictureBox2.Image = temp;
}
}
private Bitmap RotateImage(Bitmap inputImg, double degreeAngle)
{
//Corners of the image
PointF[] rotationPoints = { new PointF(0, 0),
new PointF(inputImg.Width, 0),
new PointF(0, inputImg.Height),
new PointF(inputImg.Width, inputImg.Height)};
//Rotate the corners
PointMath.RotatePoints(rotationPoints, new PointF(inputImg.Width / 2.0f, inputImg.Height / 2.0f), degreeAngle);
//Get the new bounds given from the rotation of the corners
//(avoid clipping of the image)
Rectangle bounds = PointMath.GetBounds(rotationPoints);
//An empy bitmap to draw the rotated image
Bitmap rotatedBitmap = new Bitmap(bounds.Width *2, bounds.Height *2);
using (Graphics g = Graphics.FromImage(rotatedBitmap))
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
//Transformation matrix
Matrix m = new Matrix();
m.RotateAt((float)degreeAngle, new PointF(inputImg.Width / 2.0f, inputImg.Height / 2.0f));
m.Translate(-bounds.Left, -bounds.Top, MatrixOrder.Append); //shift to compensate for the rotation
g.Transform = m;
g.DrawImage(inputImg, 0, 0);
}
return rotatedBitmap;
}
}
}