C # WPF конвертирует BitmapImage, вставленный в richtextbox, в двоичный файл

У меня есть richtextbox, который я планирую сохранить в базе данных, который можно загрузить обратно в тот же richtextbox. У меня это работает, так что я могу сохранить потоковый документ как DataFormats.XamlPackage, который сохраняет изображения, но проблема в том, что текст не доступен для поиска. С DataFormats.Xaml у меня, конечно, есть текст, но нет изображений. Изображения будут вставлены конечным пользователем, а не изображениями, включенными в приложение.

Я пытался использовать XamlWriter, чтобы получить текст в XML, а затем отдельно извлечь изображения из документа и вставить их как двоичные файлы в XML, но я не могу найти способ перевести изображения в двоичный файл ...

У кого-нибудь есть идеи, как получить изображения в двоичном виде, отдельно от текста?

Заранее спасибо!

GetImageByteArray () - вот где проблема.

Код:

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;
}

ОБНОВИТЬ

Я думаю, что, возможно, наконец нашел решение, которое я опубликую ниже. Он использует BmpBitmapEncoder и BmpBitmapDecoder. Это позволяет мне получить двоичный файл из растрового изображения, сохранить его в базе данных, загрузить его обратно и отобразить обратно в FlowDocument. Начальные испытания оказались успешными. В целях тестирования я пропускаю шаг базы данных и в основном дублирую изображение, создавая двоичный файл, затем беру двоичный файл, превращая его в новое изображение и добавляя его в FlowDocument. Единственная проблема заключается в том, что, когда я пытаюсь взять измененный FlowDocument и использовать функцию XamlWriter.Save, он создает ошибку во вновь созданном образе с «Невозможно сериализовать непубличный тип» System.Windows.Media.Imaging.BitmapFrameDecode ». Это займет некоторое дальнейшее расследование. Хотя сейчас мне придется оставить это в покое.

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);
        }

Ответы на вопрос(3)

Ваш ответ на вопрос