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
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();
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.
I've saved an image in my DataBase in a parameter type image and I've done this with:
private void btnAceptar_Click(object sender, RoutedEventArgs e)
{
UsuariosBLL bll = new UsuariosBLL();
UsuariosBO user = new UsuariosBO();
PerfilBO perfil = cmbperf.SelectedItem as PerfilBO;
//........
user.Imagen = ConvertImageToByteArray(ruta);
bll.InsertarFilaUsuarios(user);
MessageBox.Show("Se insertó");
//.......
}
where the method ConvertToByteArray convert the image selected in a Byte Array
public byte[] ConvertImageToByteArray(string path)
{
byte[] ImageByte=null;
try
{
FileStream fs = new FileStream(path,FileMode.Open,FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
ImageByte = br.ReadBytes((int)fs.Length);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return ImageByte;
}
and now I just wanna retrieve the image selecting a different user in my combobox.
I've tried like this:
private void cmbUsuarios_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
UsuariosBO user = e.AddedItems[0] as UsuariosBO;
//.....
MemoryStream ms = new MemoryStream(user.Imagen);
System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
imgFoto = img;
usuario = user;
}
But a error born:
Can not implicitly convert type 'System.Drawing.Image' to 'System.Windows.Controls.Image'
I understand what it means but I don't know how to fix it...
thanks !!
Instead of creating a System.Drawing.Image from the byte stream, you should create a WPF ImageSource and assign that to the Source property of your ImageControl.
One way to do this is by creating a BitmapImage:
using (var ms = new MemoryStream(user.Imagen))
{
var img = new BitmapImage();
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnLoad;
img.StreamSource = ms;
img.EndInit();
imgFoto.Source = img;
}
Or alternatively a BitmapFrame:
using (var ms = new MemoryStream(user.Imagen))
{
imgFoto.Source = BitmapFrame.Create(ms,
BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
I am new to windows phone dev. My small app need a bytesarray from image (photo gallery). I tried many ways to convert, but it did not work fine.
here is my code:
public static byte[] ConvertBitmapImageToByteArray(BitmapImage bitmapImage)
{
using (var ms = new MemoryStream())
{
var btmMap = new WriteableBitmap(bitmapImage.PixelWidth, bitmapImage.PixelHeight);
// write an image into the stream
btmMap.SaveJpeg(ms, bitmapImage.PixelWidth, bitmapImage.PixelHeight, 0, 100);
return ms.ToArray();
}
}
But then I saved this byte array to image in photogallery, I was be a black image!
public static void SavePicture2Library(byte[] bytes)
{
var library = new MediaLibrary();
var name = "image_special";
library.SavePicture(name, bytes);
}
Could anyone help me?
Please test your code :( Thanks so much!
Update resolved!
var wBitmap = new WriteableBitmap(bitmapImage);
wBitmap.SaveJpeg(stream, wBitmap.PixelWidth, wBitmap.PixelHeight, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
data = stream.GetBuffer();
To anyone who finds this, this works;
Image to bytes;
public static byte[] ImageToBytes(BitmapImage img)
{
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap btmMap = new WriteableBitmap(img);
System.Windows.Media.Imaging.Extensions.SaveJpeg(btmMap, ms, img.PixelWidth, img.PixelHeight, 0, 100);
img = null;
return ms.ToArray();
}
}
Bytes to Image
public static BitmapImage BytesToImage(byte[] bytes)
{
BitmapImage bitmapImage = new BitmapImage();
try
{
using (MemoryStream ms = new MemoryStream(bytes))
{
bitmapImage.SetSource(ms);
return bitmapImage;
}
}
finally { bitmapImage = null; }
}
for windows phone 8
using System.IO;
public static class FileToByteArray
{
public static byte[] Convert(string pngBmpFileName)
{
System.IO.FileStream fileStream = File.OpenRead(pngBmpFileName);
using (MemoryStream memoryStream = new MemoryStream())
{
fileStream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
}
byte[] PasPhoto = FileToByteArray.Convert("Images/NicePhoto.png")
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
}