Tengo un richtextbox, que planeo guardar en una base de datos, que se puede cargar de nuevo en el mismo richtextbox. Lo tengo funcionando para poder guardar el documento de flujo como DataFormats.XamlPackage, que guarda las imágenes, pero el problema es que el texto no se puede buscar. Con DataFormats.Xaml, tengo el texto, por supuesto, pero no hay imágenes. Las imágenes serán pegadas por el usuario final, no las imágenes incluidas con la aplicación.C# WPF convertir BitmapImage pegado en richtextbox en binario
Intenté usar XamlWriter para obtener el texto en XML, y luego tomar las imágenes del documento por separado e insertarlas como binarias en el XML, pero parece que no puedo encontrar una manera de obtener las imágenes en formato binario. ..
¿Alguien tiene ideas sobre cómo hacer que las imágenes se vuelvan binarias, separadas del texto?
¡Gracias de antemano!
GetImageByteArray() es donde está el problema.
Código:
private void SaveXML()
{
TextRange documentTextRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
FlowDocument flowDocument = richTextBox.Document;
using (StringWriter stringwriter = new StringWriter())
{
using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(stringwriter))
{
XamlWriter.Save(flowDocument, writer);
}
testRTF t = new testRTF();
t.RtfText = new byte[0];
t.RtfXML = GetImagesXML(flowDocument);
t.RtfFullText = stringwriter.ToString();
//save t to database
}
richTextBox.Document.Blocks.Clear();
}
private string GetImagesXML(FlowDocument flowDocument)
{
using (StringWriter stringwriter = new StringWriter())
{
using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(stringwriter))
{
Type inlineType;
InlineUIContainer uic;
System.Windows.Controls.Image replacementImage;
byte[] bytes;
System.Text.ASCIIEncoding enc;
//loop through replacing images in the flowdoc with the byte versions
foreach (Block b in flowDocument.Blocks)
{
foreach (Inline i in ((Paragraph)b).Inlines)
{
inlineType = i.GetType();
if (inlineType == typeof(Run))
{
//The inline is TEXT!!!
}
else if (inlineType == typeof(InlineUIContainer))
{
//The inline has an object, likely an IMAGE!!!
uic = ((InlineUIContainer)i);
//if it is an image
if (uic.Child.GetType() == typeof(System.Windows.Controls.Image))
{
//grab the image
replacementImage = (System.Windows.Controls.Image)uic.Child;
//get its byte array
bytes = GetImageByteArray((BitmapImage)replacementImage.Source);
//write the element
writer.WriteStartElement("Image");
//put the bytes into the tag
enc = new System.Text.ASCIIEncoding();
writer.WriteString(enc.GetString(bytes));
//close the element
writer.WriteEndElement();
}
}
}
}
}
return stringwriter.ToString();
}
}
//This function is where the problem is, i need a way to get the byte array
private byte[] GetImageByteArray(BitmapImage bi)
{
byte[] result = new byte[0];
using (MemoryStream ms = new MemoryStream())
{
XamlWriter.Save(bi, ms);
//result = new byte[ms.Length];
result = ms.ToArray();
}
return result;
}
ACTUALIZACIÓN
Creo que puede haber encontrado finalmente una solución, que voy a publicar a continuación. Utiliza BmpBitmapEncoder y BmpBitmapDecoder. Esto me permite obtener un archivo binario a partir de la imagen de mapa de bits, almacenarlo en la base de datos, cargarlo y mostrarlo de nuevo en FlowDocument. Las pruebas iniciales han demostrado ser exitosas. Para fines de prueba, estoy eludiendo el paso de mi base de datos y, básicamente, la duplicación de la imagen creando binarios, luego tomo el binario y lo convierto en una nueva imagen y lo agrego al FlowDocument. El único problema es que cuando intento tomar el FlowDocument modificado y uso la función XamlWriter.Save, se produce un error en la imagen recién creada con "No se puede serializar un tipo no público 'System.Windows.Media.Imaging.BitmapFrameDecode". Esto llevará más investigación. Sin embargo, tendré que dejarlo solo por el momento.
private void SaveXML()
{
TextRange documentTextRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
FlowDocument flowDocument = richTextBox.Document;
string s = GetImagesXML(flowDocument);//temp
LoadImagesIntoXML(s);
using (StringWriter stringwriter = new StringWriter())
{
using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(stringwriter))
{
XamlWriter.Save(flowDocument, writer);//Throws error here
}
}
}
private string GetImagesXML(FlowDocument flowDocument)
{
string s= "";
using (StringWriter stringwriter = new StringWriter())
{
Type inlineType;
InlineUIContainer uic;
System.Windows.Controls.Image replacementImage;
byte[] bytes;
BitmapImage bi;
//loop through replacing images in the flowdoc with the byte versions
foreach (Block b in flowDocument.Blocks)
{
foreach (Inline i in ((Paragraph)b).Inlines)
{
inlineType = i.GetType();
if (inlineType == typeof(Run))
{
//The inline is TEXT!!!
}
else if (inlineType == typeof(InlineUIContainer))
{
//The inline has an object, likely an IMAGE!!!
uic = ((InlineUIContainer)i);
//if it is an image
if (uic.Child.GetType() == typeof(System.Windows.Controls.Image))
{
//grab the image
replacementImage = (System.Windows.Controls.Image)uic.Child;
bi = (BitmapImage)replacementImage.Source;
//get its byte array
bytes = GetImageByteArray(bi);
s = Convert.ToBase64String(bytes);//temp
}
}
}
}
return s;
}
}
private byte[] GetImageByteArray(BitmapImage src)
{
MemoryStream stream = new MemoryStream();
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create((BitmapSource)src));
encoder.Save(stream);
stream.Flush();
return stream.ToArray();
}
private void LoadImagesIntoXML(string xml)
{
byte[] imageArr = Convert.FromBase64String(xml);
System.Windows.Controls.Image img = new System.Windows.Controls.Image()
MemoryStream stream = new MemoryStream(imageArr);
BmpBitmapDecoder decoder = new BmpBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default);
img.Source = decoder.Frames[0];
img.Stretch = Stretch.None;
Paragraph p = new Paragraph();
p.Inlines.Add(img);
richTextBox.Document.Blocks.Add(p);
}
posible que desee cambiar el título de este post a algo más apropiado ... parece que realmente está preguntando cómo tomar los bytes sin formato de un objeto de imagen y almacenarla en un documento XML ... –
gracias , suena bien, estaba tratando de ser lo más específico posible en caso de que alguien tuviera otras ideas sobre cómo lograr el mismo efecto de guardar el texto en imágenes completas en binario, pero no creo que sea probable – JoeSharp