Skip to content
pdfconversionapi

EXR to BMP API

POST an .exr to /v2/convert/exr/to/bmp and get an uncompressed BMP. A render with transparency, like the 240 × 300 sample, is written at 32 bits with a 108-byte BITMAPV4 header whose bit masks include alpha (288,122 bytes); a fully opaque render comes back as 24-bit.

Endpoint
POST /v2/convert/exr/to/bmp
Accepts
exr
Sample timing
24 ms median of 5 runsHow we measure
Request size
Up to 10 MB on the Free plan or 100 MB on paid plans, all files together

Request and response

Every sample below ran against the API before this page was published. Set PDFCONVERSIONAPI_KEY to your key and run it as is.

curl -sS -X POST \
  https://api.pdfconversionapi.com/v2/convert/exr/to/bmp \
  -H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
  -F File=@glowing-bulb-render.exr \
  -o response.json

# FileData is base64. Save the first file in converted/,
# or print the JSON error.
if jq -e '.Files' response.json > /dev/null; then
  mkdir -p converted
  name=$(jq -r '.Files[0].FileName' response.json)
  jq -r '.Files[0].FileData' response.json \
    | base64 --decode > "converted/$name"
else
  cat response.json
fi
200 OK24 ms median1 file, 281 KB
{
  "ConversionCost": 1,
  "ConversionTime": 0.024,
  "Files": [
    {
      "FileName": "glowing-bulb-render.bmp",
      "FileExt": "bmp",
      "FileSize": 288122,
      "FileData": "Qk16ZQQAAAAAAHoAAABsAAAA…"
    }
  ]
}

Response from our test run on 2026-11-03. ConversionTime shows the median of 5 runs. FileData is shortened here; the real response carries the whole file as base64.

The sample, converted

The same file the code sends. Download the input and the output and compare them yourself.

First page of glowing-bulb-render.bmp, rendered by the API
Input
glowing-bulb-render.exr (187 KB)
Output
glowing-bulb-render.bmp (281 KB)
Source
A glowing light bulb we drew in code and saved as a 240 × 300 OpenEXR render: half-float RGBA, premultiplied alpha, ZIP compression, values up to 12.0. (CC0-1.0). How it was made
Made by
2026-11-04, API build 9eeeb0640aba

Parameters

Send these as form fields next to the file. Names are case-insensitive. If you set one of the documented options below that we don't support yet, the request fails with a 400 that names it instead of returning a file made without it.

ParameterWhat it does
ImageWidthintegerPixel width of the bitmap. ImageWidth=120 gave 120 × 150 and 72,122 bytes, which is 4 bytes a pixel plus the header.Values: 1–20000
ImageHeightintegerPixel height; ImageHeight=100 produced 80 × 100. With ImageWidth it becomes a bounding box (200 × 200 gave 160 × 200).Values: 1–20000
ScaleProportionsboolean, default truefalse ignores the 4:5 shape and fills the box, so 200 × 200 is exactly square (160,122 bytes).
ScaleIfLargerboolean, default falsetrue keeps the bitmap at 240 × 300 when a larger size is asked for; plain ImageWidth=800 wrote 800 × 1000 and 3,200,122 bytes.
ScaleImageboolean, default truefalse crops the top-left corner to the requested size, so 200 × 100 holds the top of the glass.
ColorSpaceenum, default defaultgray and monochrome change the pixel values but the file stays 32 bits per pixel with alpha, the same 288,122 bytes. rgb returns the default file, since this render uses its alpha.Values: default, rgb, gray, monochrome; cmyk returns 400
ImageResolutionintegerWritten into the header as pixels per metre: 300 stored 11,811 in both directions. Without it both fields are 0.Values: 10–800
FileNamestringOutput name; FileName=studio-bulb returned studio-bulb.bmp.
StoreFileboolean, default falsetrue stores the bitmap for 3 hours and answers with a download URL.

What carries over, and what doesn't

Kept

  • Alpha in the fourth byte of every pixel: 26,592 clear and 20,590 partly clear pixels in the sample, behind a 0xFF000000 alpha mask
  • Each 16-bit level rounded to the nearest 8-bit one: the BMP equals the PNG route's values divided by 257, on every pixel
  • The frame size and orientation; rows are stored bottom-up, as the positive height of 300 says

Lost or not yet supported

  • Precision. 16-bit samples become 8-bit, leaving 1,352 distinct RGBA values (1,164 distinct colors) in the sample.
  • Highlights over 1.0: the 12.0 filament and the brightest glass are 255 in every channel.
  • Linear-to-display conversion. A stored 0.5 is written as 128 and 0.18 as 46, with nothing in the file that tells a viewer the values are linear.
  • Correct soft edges. Colors are not divided by alpha, so halo pixels are darker than the render intends.
  • Compactness: no compression, so the file is 1.5 times the size of the EXR.

Limits

  • A single EXR per request.
  • 10 MB on the Free plan or 100 MB on paid plans per request in total.
  • A 413 above 100,000,000 pixels.
  • Resize targets between 1 and 20,000 px.
  • Requests time out after 120 seconds.

Where teams use it

Windows tools that read only BMP

Older Windows utilities, embedded displays and some print or signage software accept BMP but not EXR. Converting the render on the server avoids installing an EXR reader on those machines.

Raw pixels for simple code

A BMP is a header followed by uncompressed BGRA rows, which a few lines of C or Python can read without a decoder library. That suits test harnesses comparing render output.

Questions

Does the BMP keep the render's transparency?

Yes. The file is 32 bits per pixel with BI_BITFIELDS masks, and the top byte is alpha. Whether a program shows it depends on that program reading the alpha mask; the clear pixels' color bytes are black or within 1 level of it.

Why is the BMP bigger than the EXR?

BMP stores every pixel raw at 4 bytes, while the EXR used ZIP compression. For 240 × 300 that is 288,000 bytes of pixels plus a 122-byte header, against 191,302 bytes of EXR.

Can I get a 24-bit BMP without alpha?

Yes, when the render is opaque. A render with no A channel, or with alpha 1.0 on every pixel, comes back as a 24-bit BMP with the 40-byte header: a 64 × 48 test render was 9,270 bytes. A render with any transparency stays 32-bit whatever ColorSpace you send. Use exr/to/jpg or exr/to/pnm with AlphaColor when you need the transparency flattened.

Are the colors the same as in my render viewer?

Only for values that are already display-ready. The API writes the stored linear numbers clipped to 0 to 1, with no view transform, so a linear render looks darker and more contrasty than in a viewer that applies sRGB or a film look.

Convert your first EXR file in a minute.