I am trying to display a report that is converted to a PDF. I have found a bit of code that will display the PDF but it needs to be stored on disk. Is there a way to store the PDF locally temporally so it can be called by a reader?
Here is the code that currently is for the print button.
namespace Dispatch311.Views
/// <summary>
/// Interaction logic for PrintDialog.xaml
/// </summary>
public partial class PrintDialog : Window
{
public PrintDialog()
{
InitializeComponent();
}
public void DisplayReport(int eventID)
{
Warning[] warnings;
string[] streamids;
string mimeType;
string encoding;
string filenameExtention;
reportViewer.ProcessingMode = Microsoft.Reporting.WinForms.ProcessingMode.Remote;
ServerReport serverReport = reportViewer.ServerReport;
reportViewer.ShowParameterPrompts = false;
serverReport.ReportServerUrl = new Uri("http://sql2008test/reportserver");
serverReport.ReportPath = "/311Reports/311SingleEvent";
ReportParameter ID = new ReportParameter();
ID.Name = "ID";
ID.Values.Add(eventID.ToString());
reportViewer.ServerReport.SetParameters(
new ReportParameter[] { ID });
byte[] bytes = reportViewer.ServerReport.Render(
"PDF", null, out mimeType, out encoding, out filenameExtention,
out streamids, out warnings);
using (FileStream fs = new FileStream("EventPDF.pdf", FileMode.Create))
{
fs.Write(bytes, 0, bytes.Length);
}
reportViewer.RefreshReport();
}
}
Fixed the end of my code so it looks like this:
byte[] bytes = reportViewer.ServerReport.Render("PDF",
null, out mimeType, out encoding, out filenameExtension, out streamids, out warnings);
using (FileStream fs = new FileStream("311Event.pdf", FileMode.Create))
{
fs.Write(bytes, 0, bytes.Length);
}
string fileName = "311Event.pdf";
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = fileName;
process.Start();
process.WaitForExit();
This makes it so Adobe reader pops up instead of reportviewer and returns to the application when the user exits the reader.
Related
I want to read Image file(png, jpg, etc).
and save xml file, load image from xml.
but first. Deserialize throw System.InvalidOperationException.
second. I don't know below method is correct.
Scenario.
1. Open Image file from hdd.
2. Save document(text with image like 'SomeClass' in below source) in my application.
3. When save document, application will serialize SomeClass with image.
4. Rerun application, and load xml file.
5. then, show image in my application.
using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(#"C:\z.jpg")))
{
StreamReader sr = new StreamReader(ms);
someClass.ImageData = sr.ReadToEnd();
Xml.Serialize<SomeClass>(someClass, #"C:\z.xml");
}
SomeClass someClass = Xml.Deserialize<SomeClass>(#"C:\z.xml");
BitmapImage image = new BitmapImage();
image.BegineInit();
image.Source = ??
image.EndInit();
System.Windows.Controls.Image imageControl = new Image();
imageControl.Source = image;
this.Content = imageControl;
this is Serialize, Deserialize static method.
public static class Xml
{
public static void Serialize<T>(T data, string path)
{
XmlSerializer s = new XmlSerializer(typeof(T));
using (FileStream fs = new FileStream(path, FileMode.Create))
{
s.Serialize(fs, data);
}
}
public static T Deserialize<T>(string path)
{
XmlSerializer s = new XmlSerializer(typeof(T));
using (FileStream fs = new FileStream(path, FileMode.Open))
{
fs.Position = 0;
return (T)s.Deserialize(fs);
}
}
}
This is SomeClass
[Serializable]
public class SomeClass
{
public string ImageData { get; set; }
public string TextData { get; set; }
}
thank you.
You need to convert the binary image data to a string. You can use the Convert methods to handle that.
Edit note - Noticed you were reading all bytes into a memory stream and then reading them again from a stream reader. It would simplify the code to just read it directly and convert those bytes to Base64.
Example below.
someClass.ImageData = Convert.ToBase64String(File.ReadAllBytes(#"C:\z.jpg"));
Xml.Serialize<SomeClass>(someClass, #"C:\z.xml");
------------------
SomeClass someClass = Xml.Deserialize<SomeClass>(#"C:\z.xml");
BitmapImage image = new BitmapImage();
image.BegineInit();
image.Source = Convert.FromBase64String(someClass.ImageData);
image.EndInit();
Using WPF 4.5
private Bitmap BitmapFromSource(BitmapSource bitmapsource)
{
Bitmap bitmap;
using (var outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapsource));
enc.Save(outStream);
bitmap = new Bitmap(outStream);
}
return bitmap;
}
}
and then later:
if (Clipboard.ContainsImage())
{
var bitmapSouce = Clipboard.GetImage();
var bitmap = BitmapFromSource(bitmapSouce);
var tmp = Path.GetTempFileName();
bitmap.Save(tmp, ImageFormat.Png);
...
bitmap.Save() throws an ExternalException, "A generic error in GDI+"
Is it really so hard to save a clipboard image to disk?
It is not necessary to create a System.Drawing.Bitmap (which is WinForms) from a WPF BitmapSource just for saving it.
You could as well directly save to a FileStream:
private void SaveBitmap(BitmapSource bitmapSource, string fileName)
{
var enc = new PngBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapSource));
using (var outStream = new FileStream(fileName, FileMode.Create))
{
enc.Save(outStream);
}
}
...
var bitmapSource = Clipboard.GetImage();
var tmp = Path.GetTempFileName();
SaveBitmap(bitmapSource, tmp);
I have a utility that allows the user to take a camera photo and upload it, in addition to another option to upload a file. I've got most of it working, except for the part where I have to convert the webcam image to a jpg prior to upload. The code below has no error but produces invalid image data:
void CaptureImageCompleted(object sender, CaptureImageCompletedEventArgs e)
{
busyIndicator.IsBusy = true;
stopCapture();
capturedImage.ImageSource = e.Result;
ImageTools.ExtendedImage eimg = e.Result.ToImage();
var encoder = new ImageTools.IO.Jpeg.JpegEncoder();
Stream stream = eimg.ToStreamByExtension("jpg");
//DO THIS LATER
//if (stream.Length > 512000)
//{
// eimg = ExtendedImage.Resize(eimg, 240, new NearestNeighborResizer());
// stream = eimg.ToStreamByExtension("jpg");
//}
encoder.Encode(eimg, stream);
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(stream);
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, (int)stream.Length);
// picture file a class object to be used by uploader
pictureFile.PictureName = "webcam.jpg"; // name will be changed later
pictureFile.PictureStream = bytes;
HtmlPage.Window.Invoke("gotDetails_WebCam", ""); // post page, then come back and do upload
}
Here is what PictureFile looks like:
[DataContract]
public class PictureFile
{
[DataMember]
public string PictureName { get; set; }
[DataMember]
public byte[] PictureStream { get; set; }
}
Can anyone figure out what I'm doing wrong to produce the bytes needed for a jpeg?
good to see that you solved,
here is my running code,
I use png format,there is also file size check.
Maybe it helps s.one else.
dSrvPR is my Domain Service Class instance
photo is an entity object in my EF.
_captureSource.CaptureImageCompleted += ((s, args) =>
{
if (dSrvPR.PR_PATIENTPHOTOs.Count > 0 && photo != null)
{
dSrvPR.PR_PATIENTPHOTOs.Remove(photo);
}
dSrvPR.PR_PATIENTPHOTOs.Clear();
photo = new PR_PATIENTPHOTO();
ImageTools.ExtendedImage eimg=args.Result.ToImage();
var encoder=new ImageTools.IO.Png.PngEncoder();
Stream stream= eimg.ToStreamByExtension("png");
if (stream.Length > 512000)
{
eimg= ExtendedImage.Resize(eimg, 240, new NearestNeighborResizer());
stream = eimg.ToStreamByExtension("png");
}
if (stream.Length <= 512001)
{
BinaryReader binary = new BinaryReader(stream);
//Read bytes from the BinaryReader and put them into a byte array.
Byte[] file = binary.ReadBytes((int)stream.Length);
photo.ID = Guid.NewGuid();
photo.PHOTO = file;
photo.PHOTODATE = DateTime.Now;
photo.ISACTIVE = true;
//some more unrelated fields
dSrvPR.PR_PATIENTPHOTOs.Add(photo);
dSrvPR.SubmitChanges();
//Msg succedded
}
else
{
Util.alert(...,"file size exceeded! :)";
}
});
My mistake. It seems I had some extra code in there (unnecessarily converting stream to bitmap). Here is what I got working:
void CaptureImageCompleted(object sender, CaptureImageCompletedEventArgs e)
{
busyIndicator.IsBusy = true;
stopCapture();
capturedImage.ImageSource = e.Result;
ImageTools.ExtendedImage eimg = e.Result.ToImage();
var encoder = new ImageTools.IO.Jpeg.JpegEncoder();
Stream stream = eimg.ToStreamByExtension("jpg");
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, (int)stream.Length);
// picture file a class object to be used by uploader
pictureFile.PictureName = "webcam.jpg"; // name will be changed later
pictureFile.PictureStream = bytes;
HtmlPage.Window.Invoke("gotDetails_WebCam", ""); // post page, then come back and do upload
}
Need help in passing Image from Silverlight4 to COM.
I am trying to pass a ByteArray from WritableBitmap and convert it back to Bitmap.
//In silverlight 4:
public string func1()
{
WriteableBitmap bitmap = new WriteableBitmap((BitmapSource)imgTempCropped.Source);
byte[] imgbytes = ToByteArray(bitmap);
dynamic comClass = AutomationFactory.CreateObject("OCRLibrary.OCRClass");
ocrText = comClass.Process(imgbytes);
}
//In COM:
public string Process(byte []imgbytes)
{
Stream input = new MemoryStream(imgbytes);
try{
Bitmap bitmap1 = new Bitmap(input);
}catch(Exception e)
{
return e.Message;
}
}
//Error Message:
Parameter is not valid.
I even tried passing in a Base64String but the same error message is thrown :(
what is COM ???
private void SaveToIsolatedStorage(Stream imageStream, string fileName, byte[] arr)
{
try
{
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (myIsolatedStorage.FileExists(fileName))
{
myIsolatedStorage.DeleteFile(fileName);
}
myIsolatedStorage.CreateDirectory("Album");
IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(fileName);
fileStream.Write(arr, 0, arr.Length);
fileStream.Close();
return;
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(imageStream);
WriteableBitmap wb = new WriteableBitmap(bitmap);
wb.SaveJpeg(fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
fileStream.Close();
}
}
catch (Exception ex) { }
}
and
Stream uc = new MemoryStream(img);
SaveToIsolatedStorage(uc, tempJPEG, img);
check it
public string func1()
{
WriteableBitmap bitmap = new WriteableBitmap((BitmapSource)imgTempCropped.Source);
byte[] imgbytes = ToByteArray(bitmap);
dynamic comClass = AutomationFactory.CreateObject("OCRLibrary.OCRClass");
ocrText = comClass.Process(imgbytes);
}
//In COM:
public string Process(byte []imgbytes)
{
Stream input = new MemoryStream(imgbytes);
input.Write(arr, 0, arr.Length);
input.Close();
try{
Bitmap bitmap1 = new Bitmap(input);
}catch(Exception e)
{
return e.Message;
}
}
I finally got it working...passing Bitmap from Silverlight to Silverlight COM Wrapper.
//In Silverlight:
dynamic comClass = AutomationFactory.CreateObject("OCRLibrary.OCRClass");
WriteableBitmap bitmap = new WriteableBitmap((BitmapSource)imgTempCropped.Source);
byte[] imgbytes = ToByteArrayOptimized(bitmap);
ocrText = comClass.Process(imgbytes);
//Found this for ImageTools: ImageTools.IO.Jpeg.JpegEncode
//using ImageTools;
//using ImageTools.Helpers;
//using ImageTools.IO;
//using ImageTools.IO.Bmp;
//using ImageTools.IO.Png;
//using ImageTools.IO.Jpeg;
//I have yet to remove couple of using from here since I added all to test the code ;)
#region To byte array (optimized)
/// <summary>
/// Synchronously converts a bitmap to a byte array.
/// The used format can be JPEG or PNG, depending on which one
/// results in a smaller file size.
/// </summary>
/// <param name="bitmap">The bitmap to encode.</param>
/// <returns>The encoded image either in PNG or JPEG format.</returns>
public byte[] ToByteArrayOptimized(WriteableBitmap bitmap)
{
ExtendedImage image = bitmap.ToImage();
// encode to jpeg
MemoryStream jpegStream = new MemoryStream();
_jpegEncoder.Encode(image, jpegStream);
// encode to png
// MemoryStream pngStream = new MemoryStream();
// _pngEncoder.Encode(image, pngStream);
// decide which one we should use
// MemoryStream formatToUse = jpegStream.Length < pngStream.Length ? jpegStream : pngStream;
MemoryStream formatToUse = jpegStream;
byte[] result = formatToUse.ToArray();
// done
return result;
}
//In COM:
[ComVisible(true)]
//public string Process(string base64string )
public string Process(byte[] imgbytes)
{
MemoryStream mystream = new MemoryStream(imgbytes);
System.Drawing.Image p = System.Drawing.Image.FromStream(mystream);
Bitmap Img = new Bitmap(p); // :) I got Bitmap here.
}
http://www.pitorque.de/MisterGoodcat/post/Improving-the-image-upload-sample.aspx
I need to save the content of a WPF Object as an Image file. In my application I have a chart drawn on a Canvas object. This is what I need to save. The Canvas with all child objects.
What you're looking for is the RenderTargetBitmap class. There's an example of its use on the MSDN page I linked, and there's another good example that includes saving to a file here:
RenderTargetBitmap by Eric Sinc
Here is the func which creates RenderTargetBitmap object, that will be used in further funcs.
public static RenderTargetBitmap ConvertToBitmap(UIElement uiElement, double resolution)
{
var scale = resolution / 96d;
uiElement.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
var sz = uiElement.DesiredSize;
var rect = new Rect(sz);
uiElement.Arrange(rect);
var bmp = new RenderTargetBitmap((int)(scale * (rect.Width)), (int)(scale * (rect.Height)), scale * 96, scale * 96, PixelFormats.Default);
bmp.Render(uiElement);
return bmp;
}
This functionc creates JPEG string content of file and writes it to a file:
public static void ConvertToJpeg(UIElement uiElement, string path, double resolution)
{
var jpegString = CreateJpeg(ConvertToBitmap(uiElement, resolution));
if (path != null)
{
try
{
using (var fileStream = File.Create(path))
{
using (var streamWriter = new StreamWriter(fileStream, Encoding.Default))
{
streamWriter.Write(jpegString);
streamWriter.Close();
}
fileStream.Close();
}
}
catch (Exception ex)
{
//TODO: handle exception here
}
}
}
This function used above to create JPEG string representation of Image content:
public static string CreateJpeg(RenderTargetBitmap bitmap)
{
var jpeg = new JpegBitmapEncoder();
jpeg.Frames.Add(BitmapFrame.Create(bitmap));
string result;
using (var memoryStream = new MemoryStream())
{
jpeg.Save(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
using (var streamReader = new StreamReader(memoryStream, Encoding.Default))
{
result = streamReader.ReadToEnd();
streamReader.Close();
}
memoryStream.Close();
}
return result;
}
Hope this helps.
With the help of the Eric Sinc tutorial I came to the following solution:
It uses a win32 SaveDialog to choose where the file should go and a PngBitmapEncoder (many other BitmapEncoders available!) to convert it to something we can save.
Note that the element being saved in this example is "cnvClasses" and that the size of the output is, quite deliberately, the same as the control.
SaveFileDialog svDlg = new SaveFileDialog();
svDlg.Filter = "PNG files|*.png|All Files|*.*";
svDlg.Title = "Save diagram as PNG";
if (svDlg.ShowDialog().Value == true)
{
RenderTargetBitmap render = new RenderTargetBitmap((int)this.cnvClasses.ActualWidth, (int)this.cnvClasses.ActualHeight, 96, 96, PixelFormats.Pbgra32);
render.Render(cnvClasses);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(render));
using (FileStream fs = new FileStream(svDlg.FileName, FileMode.Create))
encoder.Save(fs);
}