I will try to keep my question as capacious as possible. While writing this question I realized that it was possible to write shorter. The whole point in the last two sentences.

The idea: to store FlowDocument (xaml file) and images (they are stored in the media folder) in one zip archive. And in theory, everything is not bad.

Problem: it is difficult to make a Source for BitmapImage, since there is no Uri before the file that is in the archive

Suppose we inserted a picture in the RichTextBox . And when we inserted it, the UriSource and BaseUri images look like this (pay attention to pack: // payload :) :

<?xml version="1.0"?> <FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" NumberSubstitution.CultureSource="User" AllowDrop="True" PagePadding="5,0,5,0"> <BlockUIContainer TextAlignment="Justify"> <Image Height="400" Width="600"> <Image.Source> <BitmapImage CacheOption="OnLoad" UriSource="./Image1.bmp" BaseUri="pack://payload:,,wpf1,/Xaml/Document.xaml"/> </Image.Source> </Image> </BlockUIContainer> </FlowDocument> 

All this joy must be preserved. How do I do it:

  1. I make all the necessary folders
  2. I make a copy of FlowDocument (I need to calmly change the Source of pictures)
  3. Looking for pictures in FlowDocument ( Find pictures in FlowDocument )

  4. save them in the media folder

  5. I change the Source of the picture to null, and in the Tag of the picture I write the path relative to a piece of code (without creating folders)

      private void Save_Executed(object sender, ExecutedRoutedEventArgs e) { \\omitted string richTextBoxFlowDocument = xamlWriter.Save(rtbEditor.Document); //Копия FlowDocument FlowDocument rtbDocumentCopy = (FlowDocument)XamlReader.Parse(richTextBoxFlowDocument); //Находим всС ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ Π² RichTextBox List<Image> images = FindImages(rtbDocumentCopy).ToList(); foreach (var image in images) { \\Omitted BitmapEncoder encoder = new PngBitmapEncoder(); //Π”Π΅Π»Π°Π΅ΠΌ BitmapImage ΠΈΠ· image source var imageToSave = image.Source as BitmapImage; encoder.Frames.Add(BitmapFrame.Create(imageToSave)); //БохраняСм ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΡƒ using (var fileStream = new FileStream(pathToMediaPlusNewFile, FileMode.Create)) { encoder.Save(fileStream); } //ЗаписываСм Π² Tag мСсто ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ flowdocument, image.Tag = nameofMediaFolder + "/" + eligibleMediaFileName; //Если source Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½, Ρ‚ΠΎ всСм ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ image.Source = null; } richTextBoxFlowDocument = XamlWriter.Save(rtbDocumentCopy); File.WriteAllText(nameOfXamlRelativePath, richTextBoxFlowDocument, Encoding.UTF8); //Π—ΠΈΠΏΡƒΠ΅ΠΌ ΠΏΠ°ΠΏΠΊΡƒ ZipFile.CreateFromDirectory(cardGUIDFolderRelativePath, cardGUIDFolderRelativePath + ".zip"); //УдаляСм ΠΏΠ°ΠΏΠΊΡƒ ΠΈ всС содСрТимоС Directory.Delete(cardGUIDFolderRelativePath, true); } 

    At this stage, everything is good if all Image have the correct Uri of which you can make a picture.

Now it needs to be opened and re-saved. One of my attempts was to make a List<MemoryStream> in each stream stuffed with a picture that I read from zip and then from a stream and save them. But I confess at once that I didn’t understand Stream .

Open:

  List<MemoryStream> memoryStreams = new List<MemoryStream>(); private void Open_Executed(object sender, ExecutedRoutedEventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); if (dlg.ShowDialog() == true) { //ΠžΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ zip Ρ„Π°ΠΉΠ». UserData\<GUID> using (FileStream fullCardZipFile = File.Open(dlg.FileName, FileMode.Open, FileAccess.ReadWrite)) { //Π‘ΠΌΠΎΡ‚Ρ€ΠΈΠΌ zip c ZipArchive using (ZipArchive archive = new ZipArchive(fullCardZipFile, ZipArchiveMode.Update)) { //ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ entry для нашСго xaml. ZipArchiveEntry xamlFileEntry = archive.GetEntry(nameOfXamlCardDefault); //ΠžΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ наш xaml using (Stream xamlFileStreamInZip = xamlFileEntry.Open()) { rtbEditor.Document = XamlReader.Load(xamlFileStreamInZip) as FlowDocument; //Π˜Ρ‰Π΅ΠΌ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ List<Image> images = FindImages(rtbEditor.Document).ToList(); foreach (var image in images) { var imageFileEntry = archive.GetEntry(image.Tag.ToString()); var bitmap = new BitmapImage(); using (Stream imageFileStream = imageFileEntry.Open()) { //Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽ MemoryStream var memoryStream = new MemoryStream(); imageFileStream.CopyTo(memoryStream); memoryStreams.Add(memoryStream); //Π”Π΅Π»Π°ΡŽ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΡƒ bitmap.BeginInit(); bitmap.StreamSource = memoryStreams.Last(); bitmap.CacheOption = BitmapCacheOption.OnDemand; bitmap.EndInit(); image.Source = bitmap; } } } } } } return; } 

And in RichTextBox Document it turns out this:

 <?xml version="1.0"?> <FlowDocument xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" NumberSubstitution.CultureSource="User" AllowDrop="True" PagePadding="5,0,5,0"> <Paragraph> <Image Tag="Media/image0.png"> <Image.Source> <BitmapImage CacheOption="OnDemand" BaseUri="{x:Null}"/> </Image.Source> </Image> <Image Tag="Media/image1.png"> <Image.Source> <BitmapImage CacheOption="OnDemand" BaseUri="{x:Null}"/> </Image.Source> </Image> </Paragraph> </FlowDocument> 

And such a miracle can not be saved, since there is no normal BitmapImage Source. InvalidOperationException: You must set the property "UriSource" or "StreamSource".

What did I do:

  1. Make temporary folder
  2. Save pictures there and make Source on them
  3. And from this folder, take the pictures you need and save them.
  4. Clear this folder

It all worked, but I want to save the image in a MemoryStream and when I save a picture from the MemoryStream to a zip file and retrieve it, just like the program itself does with the miracle pack: // payload: ,, . How to do it?

  • "... While writing this question I realized that it was possible to write shorter. The whole point is in the last two sentences ..." - after this introduction, a normal programmer will lower your reading of the novel, go to the last two lines, will not understand anything, will leave, and you will remain unanswered. Therefore, the idea to rewrite is shorter, IMHO, an absolutely correct idea. - Alexander Muksimov

0