Reputation: 137
I have zip file in whick I store FlowDocument (Card.xaml) and folder with images (Media). Images in my FlowDocument have Tag, in which stores their path relative to FlowDocument. For image searching in FlowDocument (FindImages method): Finding all images in a FlowDocument
How I open this zip in RichTextBox. Please pay attention on how I create this images (bitmap), maybe problem there, but i can't understand what's wrong:
string nameOfXamlCardDefault = "Card.xaml";
private void Open_Executed(object sender, ExecutedRoutedEventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
if (dlg.ShowDialog() == true)
{
//Open zip file
using (FileStream fullCardZipFile = File.Open(dlg.FileName, FileMode.Open, FileAccess.ReadWrite))
{
//Open zip by ZipArchive
using (ZipArchive archive = new ZipArchive(fullCardZipFile, ZipArchiveMode.Update))
{
//Get entry for xaml (FlowDocument)
ZipArchiveEntry xamlFileEntry = archive.GetEntry(nameOfXamlCardDefault);
//Open xaml
using (Stream xamlFileStreamInZip = xamlFileEntry.Open())
{
//Load FlowDocument into rtbEditor.Document
rtbEditor.Document = XamlReader.Load(xamlFileStreamInZip) as FlowDocument;
//Searching images
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())
{
var memoryStream = new MemoryStream();
imageFileStream.CopyTo(memoryStream);
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = memoryStream;
bitmap.EndInit();
image.Source = bitmap;
}
}
}
}
}
}
return;
}
All images in RichTextBox displays well, but there is no StreamSource in BitmapImage. And it will lead to error later:
<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="OnLoad" BaseUri="{x:Null}"/>
</Image.Source>
</Image>
<Image Tag="Media/image1.png">
<Image.Source>
<BitmapImage CacheOption="OnLoad" BaseUri="{x:Null}"/>
</Image.Source>
</Image>
</Paragraph>
If just copy image and paste in RichTextBox, then it looks like this and this is good:
<Image Height="400" Width="600">
<Image.Source>
<BitmapImage CacheOption="OnLoad" UriSource="./Image1.bmp"
BaseUri="pack://payload:,,wpf1,/Xaml/Document.xaml"/>
</Image.Source>
Is it possible to embed images from zip like copy them and paste? I tried to use Clipboard and worked with MemoryStream. But it didn't help.
Upvotes: 0
Views: 889
Reputation: 128013
You should rewind the MemoryStream after copying the bitmap data, by setting its Position
property or calling its Seek()
method.
var imageFileEntry = archive.GetEntry(image.Tag.ToString());
if (imageFileEntry != null)
{
using (var imageFileStream = imageFileEntry.Open())
using (var memoryStream = new MemoryStream())
{
imageFileStream.CopyTo(memoryStream);
memoryStream.Position = 0; // here
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = memoryStream;
bitmap.EndInit();
image.Source = bitmap;
}
}
Instead of a BitmapImage
, you could also decode a BitmapFrame
from the stream.
var imageFileEntry = archive.GetEntry(image.Tag.ToString());
if (imageFileEntry != null)
{
using (var imageFileStream = imageFileEntry.Open())
using (var memoryStream = new MemoryStream())
{
imageFileStream.CopyTo(memoryStream);
memoryStream.Position = 0;
image.Source = BitmapFrame.Create(
memoryStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
}
Upvotes: 1