byte[] to ImageSource stream - wpf

I need to convert byte[] to BitmapImage and show it in WPF image control. (img.Source = ...).
if i convert it like this:
m_photo = new BitmapImage();
using (MemoryStream stream = new MemoryStream(photo.ToArray()))
{
m_photo.BeginInit();
m_photo.StreamSource = stream;
m_photo.EndInit();
}
it can't do XAML binding to Source property because "m_photo owns another stream"... What can I do?

Set the cache option to OnLoad after begininit
m_photo.CacheOption = BitmapCacheOption.OnLoad;
EDIT: complete code for bmp array to Image source
DrawingGroup dGroup = new DrawingGroup();
using (DrawingContext drawingContext = dGroup.Open())
{
var bmpImage = new BitmapImage();
bmpImage.BeginInit();
bmpImage.CacheOption = BitmapCacheOption.OnLoad;
bmpImage.StreamSource = new MemoryStream(photoArray);
bmpImage.EndInit();
drawingContext.DrawImage(bmpImage, new Rect(0, 0, bmpImage.PixelWidth, bmpImage.PixelHeight));
drawingContext.Close();
}
DrawingImage dImage = new DrawingImage(dGroup);
if (dImage.CanFreeze)
dImage.Freeze();
imageControl.Source = dImage;

Ok, I just found solution. If use this code (converting byte[] to bitmapSource) in code of class - you have this error, that the object is in another stream. But if create a Converter (IValueConverter) and use it with same code of converting in XAML binding - everything ok!
Thanks everybody!

Related

How to display images one after another on a single page

This is my code , please let me know the solution for it.
var images = (from pd in SvarkWindow.prodlist where pd.Product_name.StartsWith(imgname) select pd.Image).ToList();
BitmapImage b = new BitmapImage();
b.BeginInit();
//b.UriSource = new Uri(images.ElementAtOrDefault(0), UriKind.Relative);
b.UriSource = new Uri("http://portal.liftech.in/presc/" + images.ElementAtOrDefault(0));
b.EndInit();
// ... Get Image reference from sender.
Image img1 = Productimage0 as Image;
img1.Source = b;
I did this in this way.
look at the code.
ImageSource imageSource = new BitmapImage(new Uri("http://portal.liftech.in/presc/" + images.ElementAtOrDefault(0)));
System.Windows.Controls.Image image1 = new System.Windows.Controls.Image();
image1.Source = imageSource;
Grid.SetColumn(image1, 0);//image1 is added to column 0
Grid.SetRow(image1, 0);//row 0
ProductGrid0.Children.Add(image1);

WPF, bad texture seams on an obj model

I'm loading and texturing a model like that
Model3DGroup modelGroupScull = importer.Load("C:\\Users\\х\\Desktop\\a.obj");
modelScull = (GeometryModel3D)modelGroupScull.Children[0];
BitmapImage bitImageScull = new BitmapImage();
bitImageScull.BeginInit();
bitImageScull.UriSource = new Uri("C:\\Users\\х\\Desktop\\sc.jpg");
bitImageScull.EndInit();
ImageBrush imageBrushScull = new ImageBrush();
imageBrushScull.ViewportUnits = BrushMappingMode.Absolute;
imageBrushScull.ImageSource = bitImageScull;
diffuseMatScull = new DiffuseMaterial();
diffuseMatScull.Brush = imageBrushScull;
modelScull.Material = diffuseMatScull;
Model3DGroup2.Children.Add(modelScull);
Yet the seams look strange (they looks good in 3dMax), as well as the texture inside of the object is blue. Is there a way to fix it and made the object textured inside as well?
Thanks! )

Creating tiff image at runtime in WPF

I'm trying to generate a simple tiff image at runtime. This image consists of white background and image downloaded from remote server.
Here's the code I've written for reaching that goal:
const string url = "http://localhost/barcode.gif";
var size = new Size(794, 1123);
var drawingVisual = new DrawingVisual();
using (var drawingContext = drawingVisual.RenderOpen())
{
drawingContext.DrawRectangle(new SolidColorBrush(Colors.White), null, new Rect(size));
var image = new BitmapImage(new Uri(url));
drawingContext.DrawImage(image, new Rect(0, 0, 180, 120));
}
var targetBitmap = new RenderTargetBitmap((int)size.Width, (int)size.Height, 96, 96, PixelFormats.Default);
targetBitmap.Render(drawingVisual);
var convertedBitmap = new FormatConvertedBitmap(targetBitmap, PixelFormats.BlackWhite, null, 0);
var encoder = new TiffBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(convertedBitmap));
using (var fs = new FileStream("out.tif", FileMode.Create))
{
encoder.Save(fs);
}
The code works and generates "out.tif" file. But the output file has just a white background, without image received from remote server.
What can be the problem? I have tried the following code in a variety of ways, but everytime with no luck.
I found this reading about the FormatConvertedBitmap class. Maybe give it a shot
FormatConvertedBitmap newFormatedBitmapSource = new FormatConvertedBitmap();
// BitmapSource objects like FormatConvertedBitmap can only have their properties
// changed within a BeginInit/EndInit block.
newFormatedBitmapSource.BeginInit();
// Use the BitmapSource object defined above as the source for this new
// BitmapSource (chain the BitmapSource objects together).
newFormatedBitmapSource.Source = targetBitmap;
// Set the new format to BlackWhite.
newFormatedBitmapSource.DestinationFormat = PixelFormats.BlackWhite;
newFormatedBitmapSource.EndInit();

Replace RichTextBox Text but keep formatting

Can anybody cast some light on this for me, I have a RichTextBox which im loading an xaml file into it. I need to Replace certain Parts of the RichTxtBox's text with real data i.e. '[our_name]' is replaced with 'Billie Brags'. My xaml file contains formatting like bold & font size.
When I run my code (shown below) I can change the text OK but im loosing the formatting.
Any idea how I can do this and keep the formatting?
Thank you
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
using (fs)
{
TextRange RTBText = new TextRange(rtb_wording.Document.ContentStart, rtb_wording.Document.ContentEnd);
RTBText.Load(fs, DataFormats.Xaml);
}
TextRange tr = new TextRange(rtb_wording.Document.ContentStart, rtb_wording.Document.ContentEnd);
string rtbContent = tr.Text;
rtbContent = rtbContent.Replace("<our_name>", "Billie Brags");
System.Windows.MessageBox.Show(rtbContent);
FlowDocument myFlowDoc = new FlowDocument();
// Add paragraphs to the FlowDocument
myFlowDoc.Blocks.Add(new Paragraph(new Run(rtbContent)));
rtb_wording.Document = myFlowDoc;
Its working, this is how I did it in the end, not too pretty but it functions. WPF RTB really should have rtf property like winforms...
Thanks to Kent for putting me on the right track.
var textRange = new TextRange(rtb_wording.Document.ContentStart, rtb_wording.Document.ContentEnd);
string rtf;
using (var memoryStream = new MemoryStream())
{
textRange.Save(memoryStream, DataFormats.Rtf);
rtf = ASCIIEncoding.Default.GetString(memoryStream.ToArray());
}
rtf = rtf.Replace("<our_name>", "Bob Cratchet");
MemoryStream stream = new MemoryStream(ASCIIEncoding.Default.GetBytes(rtf));
rtb_wording.SelectAll();
rtb_wording.Selection.Load(stream, DataFormats.Rtf);
I believe you'll need to save the contents of the TextRange in RTF format, and then reload the contents of the RTB. I haven't tried this so not sure it will work (on linux at the moment so can't test):
var textRange = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);
string rtf;
using (var memoryStream = new MemoryStream())
using (var streamReader = new StreamReader(memoryStream))
{
textRange.Save(memoryStream, DataFormats.Rtf);
rtf = streamReader.ReadToEnd();
}
rtf = rtf.Replace("<whatever>", "whatever else");
using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(rtf)))
{
textRange.Load(memoryStream, DataFormats.Rtf);
}

convert object(i.e any object like person, employee) to byte[] in silverlight

i have a person object and need to store it as byte[] and again retrieve that byte[] and convert to person object
and BinaryFormatter is not availabe in silverlight
Because the namespaces mentioned by t0mm13b are not part of the Silverlight .NET engine, the correct way to is to use this workaround leveraging the data contract serializer:
http://forums.silverlight.net/forums/t/23161.aspx
From the link:
string SerializeWithDCS(object obj)
{
if (obj == null) throw new ArgumentNullException("obj");
DataContractSerializer dcs = new DataContractSerializer(obj.GetType());
MemoryStream ms = new MemoryStream();
dcs.WriteObject(ms, obj);
return Encoding.UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Position);
}
If you really need binary and want it to be super fast and very small, then you should use protobuf from Google.
http://code.google.com/p/protobuf-net/
Look at these performance numbers. Protobuf is far and away the fastest and smallest.
I've used it for WCF <--> Silverlight with success and would not hesitate to use it again for a new project.
I have used XML Serializer to convert the object to a string and them convert the string to byte[] successfully in Silverlight.
object address = new Address();
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(Address));
StringBuilder stringBuilder = new StringBuilder();
using (StringWriter writer = new StringWriter(stringBuilder))
{
serializer.Serialize(writer, address);
}
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
byte[] data = encoding.GetBytes(stringBuilder.ToString());
Look at custom binary serialization and compression here
and here
Use the serialized class to convert the object into a byte via using a MemoryStream
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
....
byte[] bPersonInfo = null;
using (MemoryStream mStream = new MemoryStream())
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(mStream, personInfo);
bPersonInfo = mStream.ToArray();
}
....
// Do what you have to do with bPersonInfo which is a byte Array...
// To Convert it back
PersonInfo pInfo = null;
using (MemoryStream mStream = new MemoryStream(bPersonInfo)){
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new BinaryFormatter();
pInfo = (PersonInfo)bf.DeSerialize(mStream);
}
// Now pInfo is a PersonInfo object.
Hope this helps,
Best regards,
Tom.

Resources