You can do this through the following mechanism (desktop WPF):
Create a custom DependencyObject
subclass with one DependencyProperty
- the base 64 image string. Call your class, e.g., ImageData
. Having done this, you can add named instances of the class to your FlowDocument.Resources
or Window.Resources
(or Grid.Resources
or whatever), with the base64 string initialized directly in the XAML.
Create a custom IValueConverter that converts a base64 string to a BitmapImage
. Add this to your Window.Resources
as a named static resource.
For each image you want to use as a flow document background, add an ImageData
to the static resources of the flow document itself, or a higher level control such as the window. (Note -- on my older version of Visual Studio the forms designer became confused if the image resource was added to the flow document itself. Nevertheless, the application compiled and ran successfully.)
Finally, add a DataBinding
for the Background.ImageBrush.ImageSource
, linking it to the base 64 string property of your named ImageData
resource and using your custom converter to convert it to an image.
The details are as follows. Firstly, the custom ImageData
class is quite simple:
public class ImageData : DependencyObject
{
public static readonly DependencyProperty Base64ImageDataProperty =
DependencyProperty.Register("Base64ImageData",
typeof(string),
typeof(ImageData));
public string Base64ImageData
{
get { return (string)(GetValue(Base64ImageDataProperty)); }
set { SetValue(Base64ImageDataProperty, value); }
}
}
Next, the custom converter and some helper utilities to go with it:
public class Base64ImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string base64String = value as string;
if (base64String == null)
return null;
return ImageHelper.Base64StringToBitmapImage(base64String);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
public static class ImageHelper
{
public static BitmapImage Base64StringToBitmapImage(string base64String)
{
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = new MemoryStream(Convert.FromBase64String(base64String));
bitmapImage.EndInit();
return bitmapImage;
}
public static string FileToBase64String(string filename)
{
using (var stream = File.Open(filename, FileMode.Open))
using (var reader = new BinaryReader(stream))
{
byte[] allData = reader.ReadBytes((int)reader.BaseStream.Length);
return Convert.ToBase64String(allData);
}
}
}
Place it in the static resources for the window, or the app, or some other central location that's convenient for you and can be reused throughout your application:
<Window x:Class="RichTextBoxInputPanel.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:w="clr-namespace:RichTextBoxInputPanel"
Title="RichTextBoxInputPanel" Height="600" Width="1200" Loaded="Window_Loaded">
<Window.Resources>
<w:Base64ImageConverter x:Key="Base64ImageConverter"></w:Base64ImageConverter>
</Window.Resources>
You can also add it to the static resources of the flow document itself, alongside the ImageData
shown below.
Now, add an ImageData
to the resources of your flow document:
<FlowDocument >
<FlowDocument.Resources>
<w:ImageData x:Key="DocumentBackground" Base64ImageData="iVBORw0K...etc etc">
</w:ImageData>
</FlowDocument.Resources>
Lastly, add the binding property for the background:
<FlowDocument.Background>
<ImageBrush>
<ImageBrush.ImageSource>
<Binding Converter="{StaticResource Base64ImageConverter}"
Source="{StaticResource DocumentBackground}"
Path="Base64ImageData" Mode="OneWay"></Binding>
</ImageBrush.ImageSource>
</ImageBrush>
</FlowDocument.Background>
Finally, as I mentioned above putting the static ImageData
resource on the flow document itself causes the WPF forms designer (on VS2008) to throw up a spurious error. Despite the error the application compiles and runs successfully. Moving the ImageData
static resource from the flow document to a higher control such as the RichTextBox or FlowDocumentReader that contains it resolves the issue.
ImageSource
(BitmapImage
may be closer) and implement your own decoding logic. – Pragmateek