|
| 1 | +--- |
| 2 | +id: convert-to-markdown-with-advanced-options |
| 3 | +url: conversion/net/convert-to-markdown-with-advanced-options |
| 4 | +title: Convert to Markdown with advanced options |
| 5 | +weight: 23 |
| 6 | +description: "Follow this guide and learn how to convert documents to Markdown format with advanced image handling — embed images as base64, write them as external files, or redirect them to a custom destination via the image saving callback using GroupDocs.Conversion for .NET." |
| 7 | +keywords: Convert to Markdown, Markdown images, base64 images, ImageSavingCallback, IMarkdownImageSavingCallback, MarkdownOptions |
| 8 | +productName: GroupDocs.Conversion for .NET |
| 9 | +hideChildren: False |
| 10 | +toc: True |
| 11 | +--- |
| 12 | +When converting documents to Markdown (`WordProcessingFileType.Md`), images from the source document can be handled in two ways: |
| 13 | + |
| 14 | +- **Inline as base64** — images are embedded directly in the `.md` as data URIs, producing a single self-contained file. This is the default. |
| 15 | +- **Custom destination via callback** — you take control of each image: where the bytes go (disk, memory, cloud storage, …) and what URI is written into the Markdown. |
| 16 | + |
| 17 | +Both are configured through [MarkdownOptions](https://reference.groupdocs.com/conversion/net/groupdocs.conversion.options.convert/markdownoptions) on [WordProcessingConvertOptions](https://reference.groupdocs.com/conversion/net/groupdocs.conversion.options.convert/wordprocessingconvertoptions). |
| 18 | + |
| 19 | +## Inline images as base64 (default) |
| 20 | + |
| 21 | +By default, [MarkdownOptions.ExportImagesAsBase64](https://reference.groupdocs.com/conversion/net/groupdocs.conversion.options.convert/markdownoptions/exportimagesasbase64) is `true`, so images are encoded into the Markdown as data URIs — the result is a single self-contained `.md` file with no separate image outputs. |
| 22 | + |
| 23 | +```csharp |
| 24 | +using (Converter converter = new Converter("sample.pdf")) |
| 25 | +{ |
| 26 | + WordProcessingConvertOptions options = new WordProcessingConvertOptions |
| 27 | + { |
| 28 | + Format = WordProcessingFileType.Md |
| 29 | + // MarkdownOptions.ExportImagesAsBase64 is true by default |
| 30 | + }; |
| 31 | + converter.Convert("converted.md", options); |
| 32 | +} |
| 33 | +``` |
| 34 | + |
| 35 | +The resulting Markdown looks like: |
| 36 | + |
| 37 | +```markdown |
| 38 | + |
| 39 | +``` |
| 40 | + |
| 41 | +Use this when you need a portable, single-file output — for example, storing Markdown in a database, sending it over a message channel, or rendering it in a viewer that cannot resolve relative image paths. |
| 42 | + |
| 43 | +## Customize image output with a callback |
| 44 | + |
| 45 | +*Available in GroupDocs.Conversion for .NET 26.6 and later.* |
| 46 | + |
| 47 | +For full control over where images are written and which URI appears in the Markdown, implement [IMarkdownImageSavingCallback](https://reference.groupdocs.com/conversion/net/groupdocs.conversion.options.convert/imarkdownimagesavingcallback) and assign it to [MarkdownOptions.ImageSavingCallback](https://reference.groupdocs.com/conversion/net/groupdocs.conversion.options.convert/markdownoptions/imagesavingcallback). The callback is invoked once per image, regardless of the source format (PDF, DOCX, PPTX, …). |
| 48 | + |
| 49 | +When a callback is assigned, it takes precedence automatically — images are written through the callback even if `ExportImagesAsBase64` is left at its default. |
| 50 | + |
| 51 | +The callback receives a [MarkdownImageSavingArgs](https://reference.groupdocs.com/conversion/net/groupdocs.conversion.options.convert/markdownimagesavingargs) instance with three mutable properties: |
| 52 | + |
| 53 | +- **ImageFileName** — the URI written into the Markdown as the image reference. Set this to a file name, a placeholder id, or any string. |
| 54 | +- **ImageStream** — the destination stream the converter writes the image bytes into. Replace it to redirect the bytes. |
| 55 | +- **KeepImageStreamOpen** — when `false` (default) the converter flushes and closes the stream; when `true` the caller keeps ownership and can read the stream after `Convert()` returns. |
| 56 | + |
| 57 | +### Scenario 1 — capture images in memory with placeholder IDs |
| 58 | + |
| 59 | +Redirect every image into an in-memory buffer and write a unique placeholder id into the Markdown instead of a file path. Useful when you want to post-process images, upload them to external storage, or reference them from a different system. |
| 60 | + |
| 61 | +```csharp |
| 62 | +class CaptureImagesCallback : IMarkdownImageSavingCallback |
| 63 | +{ |
| 64 | + private int _index; |
| 65 | + private readonly Dictionary<string, MemoryStream> _images; |
| 66 | + |
| 67 | + public CaptureImagesCallback(Dictionary<string, MemoryStream> images) => _images = images; |
| 68 | + |
| 69 | + public void ImageSaving(MarkdownImageSavingArgs args) |
| 70 | + { |
| 71 | + var id = $"image{_index++}"; |
| 72 | + var buffer = new MemoryStream(); |
| 73 | + _images[id] = buffer; |
| 74 | + args.ImageStream = buffer; // redirect image bytes into our buffer |
| 75 | + args.ImageFileName = id; // placeholder URI written into the .md |
| 76 | + args.KeepImageStreamOpen = true; // keep buffer readable after Convert() returns |
| 77 | + } |
| 78 | +} |
| 79 | + |
| 80 | +var captured = new Dictionary<string, MemoryStream>(); |
| 81 | +try |
| 82 | +{ |
| 83 | + var options = new WordProcessingConvertOptions { Format = WordProcessingFileType.Md }; |
| 84 | + options.MarkdownOptions.ImageSavingCallback = new CaptureImagesCallback(captured); |
| 85 | + |
| 86 | + using var converter = new Converter("source.pdf"); |
| 87 | + converter.Convert("output.md", options); |
| 88 | + // captured["image0"], captured["image1"], ... now hold the image bytes |
| 89 | +} |
| 90 | +finally |
| 91 | +{ |
| 92 | + foreach (var s in captured.Values) s.Dispose(); // caller owns the streams |
| 93 | +} |
| 94 | +``` |
| 95 | + |
| 96 | +The resulting Markdown references the placeholder ids: |
| 97 | + |
| 98 | +```markdown |
| 99 | + |
| 100 | + |
| 101 | +``` |
| 102 | + |
| 103 | +### Scenario 2 — persist images to disk alongside the `.md` |
| 104 | + |
| 105 | +Write each image to a specific folder with a chosen naming scheme and let the converter close each file when it's done. |
| 106 | + |
| 107 | +```csharp |
| 108 | +class FileImagesCallback : IMarkdownImageSavingCallback |
| 109 | +{ |
| 110 | + private readonly string _outputFolder; |
| 111 | + private int _index; |
| 112 | + |
| 113 | + public FileImagesCallback(string outputFolder) => _outputFolder = outputFolder; |
| 114 | + |
| 115 | + public void ImageSaving(MarkdownImageSavingArgs args) |
| 116 | + { |
| 117 | + var fileName = $"image{_index++}.png"; |
| 118 | + args.ImageStream = new FileStream(Path.Combine(_outputFolder, fileName), FileMode.Create); |
| 119 | + args.ImageFileName = fileName; // written into the .md as  |
| 120 | + // KeepImageStreamOpen left at default (false) → the converter flushes and closes the file. |
| 121 | + } |
| 122 | +} |
| 123 | + |
| 124 | +var options = new WordProcessingConvertOptions { Format = WordProcessingFileType.Md }; |
| 125 | +options.MarkdownOptions.ImageSavingCallback = new FileImagesCallback("./out"); |
| 126 | + |
| 127 | +using var converter = new Converter("source.pdf"); |
| 128 | +converter.Convert("./out/output.md", options); |
| 129 | +// ./out/image0.png, ./out/image1.png, ... are written and closed by the converter. |
| 130 | +``` |
| 131 | + |
| 132 | +## More Resources |
| 133 | + |
| 134 | +- [API Reference: MarkdownOptions](https://reference.groupdocs.com/conversion/net/groupdocs.conversion.options.convert/markdownoptions) |
| 135 | +- [API Reference: IMarkdownImageSavingCallback](https://reference.groupdocs.com/conversion/net/groupdocs.conversion.options.convert/imarkdownimagesavingcallback) |
| 136 | +- [API Reference: MarkdownImageSavingArgs](https://reference.groupdocs.com/conversion/net/groupdocs.conversion.options.convert/markdownimagesavingargs) |
| 137 | +- [Convert to WordProcessing with advanced options]({{< ref "conversion/net/developer-guide/advanced-usage/converting/conversion-options-by-document-family/convert-to-wordprocessing-with-advanced-options.md" >}}) |
0 commit comments