AutumnKnight
AutumnKnight

Reputation: 53

Saving RichTextBox FlowDocument to image

i'am making a programm where i want my RichTextBox content (text+images) to be saved as an image (jpg/png). I tried to use this solution but i get only black filled image from

SaveUIAsGraphicFile() 

I also tried to create FormattedText from my rtb control, printing it works fine, but its not possible to insert images in there. Maybe it is possible to print FlowDocument somehow?

Upvotes: 2

Views: 6674

Answers (2)

Clint StLaurent
Clint StLaurent

Reputation: 1268

Example of default column pagination

You can spend HOURS chasing around trying to figure out why the width is wrong when in reality its trying to paginate in columns. Set the document's columnwidth to the full width of your output bitmap.

    public Bitmap FlowDocumentToBitmap(FlowDocument document, Size size)
    {
        document = CloneDocument(document);
        document.ColumnWidth = size.Width;// <-  Add this line

Upvotes: 0

Clemens
Clemens

Reputation: 128060

You could use something like the following method to create a bitmap from a FlowDocument:

public BitmapSource FlowDocumentToBitmap(FlowDocument document, Size size)
{
    document = CloneDocument(document);

    var paginator = ((IDocumentPaginatorSource)document).DocumentPaginator;
    paginator.PageSize = size;

    var visual = new DrawingVisual();
    using (var drawingContext = visual.RenderOpen())
    {
        // draw white background
        drawingContext.DrawRectangle(Brushes.White, null, new Rect(size));
    }
    visual.Children.Add(paginator.GetPage(0).Visual);

    var bitmap = new RenderTargetBitmap((int)size.Width, (int)size.Height,
                                        96, 96, PixelFormats.Pbgra32);
    bitmap.Render(visual);
    return bitmap;
}

public FlowDocument CloneDocument(FlowDocument document)
{
    var copy = new FlowDocument();
    var sourceRange = new TextRange(document.ContentStart, document.ContentEnd);
    var targetRange = new TextRange(copy.ContentStart, copy.ContentEnd);

    using (var stream = new MemoryStream())
    {
        sourceRange.Save(stream, DataFormats.XamlPackage);
        targetRange.Load(stream, DataFormats.XamlPackage);
    }

    return copy;
}

and then use it like shown below to save a RichTextBox's Document to an image file.

var doc = richTextBox.Document;
var bm = FlowDocumentToBitmap(doc, new Size(richTextBox.ActualWidth, richTextBox.ActualHeight));
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bm));

using (var stream = new FileStream("doc.jpg", FileMode.Create))
{
    encoder.Save(stream);
}   

Upvotes: 6

Related Questions