# Images

> Merge JPG, PNG, BMP or GIF images from Base64 JSON data into image placeholders with document/merge: template editor steps, curl, .NET and removeEmptyImages.

- **Product:** ReportingCloud
- **Section:** Documentation
- **Kind:** Topic
- **Path:** ReportingCloud > Mail Merge > Images
- **2128 words**
- **Web URL:** https://docs.textcontrol.com/reporting-cloud/mail-merge/images/
- **LLMs URL:** https://docs.textcontrol.com/reporting-cloud/mail-merge/images/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/reporting-cloud/mail-merge/images/llms-full.txt

---

A company logo, a signature or a product photo can come from the merge data instead of being part of the template. The template holds an image placeholder that is bound to a field of the data, and ReportingCloud replaces the placeholder with the image that each record carries. You create such a placeholder in the template editor, send the image with the merge data and decide what happens to placeholders that receive no image.

The template is merged with the [POST /v1/document/merge](https://docs.textcontrol.com/reporting-cloud/reference/web-api/document/merge/post/llms-full.txt) endpoint, as [Overview](https://docs.textcontrol.com/reporting-cloud/mail-merge/overview/llms-full.txt) describes. Every request authenticates with an API key; the samples read it from the environment variable `REPORTINGCLOUD_API_KEY`, as [API Keys](https://docs.textcontrol.com/reporting-cloud/installation/api-keys/llms-full.txt) explains.

### How Image Placeholders Work

An image placeholder is an image in the template that is bound to a field of the data, its *object data source*. During the merge, ReportingCloud fills the placeholder with the image of that field:

- **Data.** The value of the field is the binary data of the image, encoded as a Base64 string. The image can be a JPG, PNG, BMP or GIF file.
- **Same format everywhere.** The datasource excerpt you design the template with and the merge data you send to `POST /v1/document/merge` carry the image the same way: the field that holds the Base64 string in the excerpt holds it in the merge data.
- **Missing data.** By default, a placeholder whose field has no data stays in the document. The merge setting `removeEmptyImages` removes it, as [Remove Placeholders Without Data](#remove-placeholders-without-data) shows.

The examples use invoice data with an invoice number and an image. Save it as *image\_data.json*:

```json
[
  {
    "InvoiceNumber": "I778977622",
    "Image": "iVBORw0KGgoAAAANSUhEUgAAAS0AAABHCAIAAADdmYYx..."
  }
]
```

The value of `Image` is shortened here. To get the Base64 string of an image file on Linux, run `base64 -w 0 logo.png`.

### Create a Template With an Image Placeholder

The template editor of the ReportingCloud portal offers the fields of the datasource excerpt that is opened with the template, so you create the excerpt first. [Datasource Excerpts](https://docs.textcontrol.com/reporting-cloud/portal/datasource-excerpts/llms-full.txt) and [Template Editor](https://docs.textcontrol.com/reporting-cloud/portal/template-editor/llms-full.txt) describe both in detail.

1. In the portal, open **My Datasource Excerpts**. Enter a name and paste the JSON of *image\_data.json*, with the complete Base64 string, into **Datasource Excerpt**. Save it with **Create Excerpt**.

    ![My Datasource Excerpts page with a new excerpt named imagedata whose JSON holds an InvoiceNumber and a Base64 Image value, marked as valid](https://docs.textcontrol.com/assets/img/reporting-cloud/image-datasource-excerpt.073e708c.webp)
2. Open **My Templates** and click **New Template...**. Type a name such as *demo\_image\_placeholder*, choose a format such as DOCX and confirm with **OK**.
3. Confirm the next dialog with **Edit Template**. On the **Select Datasource Excerpt** page, choose the excerpt in **Select datasource excerpt file** and click **Edit Template** to open the editor.

    ![Select Datasource Excerpt page for demo_image_placeholder.docx with image_sample.json chosen in the drop-down list](https://docs.textcontrol.com/assets/img/reporting-cloud/choose-image-excerpt.58704128.webp)
4. On the **Insert** tab, open the **Image** drop-down and choose **Image Placeholder**. A placeholder image is inserted at the input position:

    ![Template editor with the Insert tab open and a gray image placeholder in the document](https://docs.textcontrol.com/assets/img/reporting-cloud/insert-image-placeholder.4ab95787.webp)
5. Right-click the placeholder, point to **Select Object Data Source**, then to **master** and choose **image**. The placeholder is now bound to the `Image` field of the top-level records. The editor lists the names of the excerpt in lowercase, and the merge matches names without regard to letter case.

    ![Context menu of the image placeholder with Select Object Data Source, master and the columns invoicenumber and image](https://docs.textcontrol.com/assets/img/reporting-cloud/image-object-data-source.9e2c622b.webp)
6. On the **Reporting** tab, click **Preview Merge Results** and confirm the dialog box with **OK**. The preview merges the excerpt into the template and shows the image in place of the placeholder:

    ![Merge results preview in the template editor showing the Text Control logo where the placeholder was](https://docs.textcontrol.com/assets/img/reporting-cloud/merged-image-preview.bbc409d8.webp)
7. Save the template with **Save template**.

### Merge Images With the Web API

The merge request carries the image in the same field as the excerpt. The following commands build the `MergeBody` from *logo.png*, merge it into *demo\_image\_placeholder.docx* from the template storage and save the result:

```bash
# Build the MergeBody with the Base64 string of logo.png
jq -n \
  --rawfile image <(base64 -w 0 logo.png) \
  '{
    mergeData: [{ InvoiceNumber: "I778977622", Image: $image }],
    mergeSettings: { removeEmptyImages: true }
  }' > merge.json

curl -X POST "https://api.reporting.cloud/v1/document/merge?templateName=demo_image_placeholder.docx&returnFormat=PDF" \
  -H "Authorization: ReportingCloud-APIKey $REPORTINGCLOUD_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @merge.json \
  -o result.json

# The response is an array of Base64 strings; decode the first document
jq -r '.[0]' result.json | base64 -d > invoice.pdf
```

The commands work as follows:

- `--rawfile image` reads the Base64 string of the image into the variable `$image`, and the filter writes it into the `Image` field of the only record.
- `mergeSettings` sets `removeEmptyImages`, which removes placeholders that receive no image.
- The response holds one Base64 string per created document. `jq -r '.[0]'` takes the first, and `base64 -d` decodes it into *invoice.pdf*.

### Merge Images With .NET

With the .NET SDK, the package `TXTextControl.ReportingCloud` described in [.NET](https://docs.textcontrol.com/reporting-cloud/sdks/dotnet/llms-full.txt), the image is a `string` property of the merge data, filled with `Convert.ToBase64String`:

```csharp
using TXTextControl.ReportingCloud;

ReportingCloud rc = new ReportingCloud(Environment.GetEnvironmentVariable("REPORTINGCLOUD_API_KEY"));

// The image data travels as a Base64 string
var mergeData = new[]
{
    new
    {
        InvoiceNumber = "I778977622",
        Image = Convert.ToBase64String(File.ReadAllBytes("logo.png"))
    }
};

MergeBody mergeBody = new MergeBody
{
    MergeData = mergeData,
    MergeSettings = new MergeSettings { RemoveEmptyImages = true }
};

List<byte[]> documents = rc.MergeDocument(mergeBody, "demo_image_placeholder.docx", ReturnFormat.PDF);
File.WriteAllBytes("invoice.pdf", documents[0]);
```

The code works as follows:

- The constructor of `ReportingCloud` with one string takes an API key.
- `MergeData` takes the records; the SDK serializes them to the JSON array of the request, with the property names in camel case: `invoiceNumber` and `image`.
- `MergeDocument` sends the `MergeBody` to `POST /v1/document/merge` with the template name and the return format, and returns the created documents as byte arrays.

### Remove Placeholders Without Data

When a record has no image for a placeholder, the placeholder image stays in the merged document, because `removeEmptyImages` is `false` by default. Set it to `true` to remove such placeholders, as both samples do:

```json
{
  "mergeSettings": {
    "removeEmptyImages": true
  }
}
```

In the Java and Ruby SDKs, a `MergeSettings` object sends `removeEmptyImages` as `true` unless you change it, as [Merge Settings](https://docs.textcontrol.com/reporting-cloud/mail-merge/settings/#set-merge-settings-in-the-sdks) lists.

### Next Steps

- [Merge Settings](https://docs.textcontrol.com/reporting-cloud/mail-merge/settings/llms-full.txt): every option of the merge, `removeEmptyImages` included.
- [Template Editor](https://docs.textcontrol.com/reporting-cloud/portal/template-editor/llms-full.txt): the other elements you insert from the ribbon.
- [Merge Data](https://docs.textcontrol.com/reporting-cloud/mail-merge/data-sources/llms-full.txt): the JSON format that carries the images.
- [Template Design](https://docs.textcontrol.com/reporting-cloud/mail-merge/template-design/llms-full.txt): design a template for the structure of your data.

---

## Nearby

- **Previous:** [Nested Blocks](https://docs.textcontrol.com/reporting-cloud/mail-merge/nested-blocks/llms-full.txt)
- **Next:** [Conditional Blocks](https://docs.textcontrol.com/reporting-cloud/mail-merge/conditional-content/llms-full.txt)
