BMP to PDF API
Send a bitmap to POST /v2/convert/bmp/to/pdf and receive a one-page PDF. The pixels are stored with lossless compression, and the page is either the image's size at 96 pixels per inch or the sheet you name in PageSize.
- Endpoint
- POST /v2/
convert/ bmp/ to/ pdf - Accepts
- bmp
- Sample timing
- 4 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/bmp/to/pdf \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@shelf-label.bmp \
--form-string PageSize=a5 \
--form-string PageOrientation=landscape \
-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
fiimport base64
import os
import requests
key = os.environ["PDFCONVERSIONAPI_KEY"]
response = requests.post(
"https://api.pdfconversionapi.com/v2/convert/bmp/to/pdf",
headers={"Authorization": f"Bearer {key}"},
files=[("File", open("shelf-label.bmp", "rb"))],
data={
"PageSize": "a5",
"PageOrientation": "landscape",
},
timeout=180,
)
result = response.json()
if not response.ok:
raise SystemExit(f"{result['Code']}: {result['Message']}")
os.makedirs("converted", exist_ok=True)
for file in result["Files"]:
path = os.path.join("converted", file["FileName"])
with open(path, "wb") as out:
out.write(base64.b64decode(file["FileData"]))
print(path, file["FileSize"], "bytes")
import { mkdir, readFile, writeFile } from "node:fs/promises";
import { join } from "node:path";
const form = new FormData();
const file = "shelf-label.bmp";
form.append("File", new Blob([await readFile(file)]), file);
form.append("PageSize", "a5");
form.append("PageOrientation", "landscape");
const url = "https://api.pdfconversionapi.com/v2/convert/bmp/to/pdf";
const key = process.env.PDFCONVERSIONAPI_KEY;
const response = await fetch(url, {
method: "POST",
headers: { Authorization: `Bearer ${key}` },
body: form,
});
const result = await response.json();
if (!response.ok) {
throw new Error(`${result.Code}: ${result.Message}`);
}
await mkdir("converted", { recursive: true });
for (const file of result.Files) {
const path = join("converted", file.FileName);
await writeFile(path, Buffer.from(file.FileData, "base64"));
console.log(path, file.FileSize, "bytes");
}
{
"ConversionCost": 1,
"ConversionTime": 0.004,
"Files": [
{
"FileName": "shelf-label.pdf",
"FileExt": "pdf",
"FileSize": 14252,
"FileData": "JVBERi0xLjcKJYCAgIAKMSAw…"
}
]
}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.

- Input
- shelf-label.bmp (293 KB)
- Output
- shelf-label.pdf (14 KB)
- Source
- A 24-bit warehouse bin label with a QR code and a colored header, drawn by us for this page. (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.
| Parameter | What it does |
|---|---|
PageSizeenum, default default | With no value (or default, auto), the 400 × 250 label becomes a 300 × 187.5 pt page, 4.17 × 2.6 in. The sample puts it on A5 instead; it is centered at its own size because images are only ever scaled down.Values: default, auto, a3, a4, a5, letter, legal |
PageOrientationenum, default default | landscape lays a named sheet on its side, as the sample does with A5 (595.28 × 419.53 pt). Ignored without PageSize.Values: default, portrait, landscape |
Rotateinteger | Degrees clockwise. The label is drawn turned and the page follows it: 90 gave a 187.5 × 300 pt portrait page with the colored header down the right side, 45 a 344.71 pt square. BMP has no EXIF orientation, so leaving it out places the bitmap as stored.Values: -360 to 360, or none |
MarginHorizontalinteger, default 0 | Blank space left and right, in millimeters. Without PageSize the page widens by twice the value: 10 made it 356.69 × 187.5 pt. On a named sheet the label shrinks instead when the margins crowd it: A5 portrait with 70 mm left room for a 22.68 × 14.17 pt label.Values: 0–500 (mm) |
MarginVerticalinteger, default 0 | Blank space above and below. 10 mm on the image-sized page gave 300 × 244.19 pt. When the margins leave under 1 pt for the bitmap, as A5 portrait with MarginHorizontal=74 does, the API returns 400.Values: 0–500 (mm) |
ColorSpaceenum, default default | TrueColors names what the default already does: the label came back as the same 14,228-byte PDF as with no value, its pixels stored as RGB. Every other value is refused, rgb included.Values: default, TrueColors |
FileNamestring | Name for the PDF; the BMP's name by default. |
StoreFileboolean, default false | Keep the PDF for 3 hours and return a URL. |
Not supported yet
Setting one of these to anything but its default returns 400.
| Option | What to do instead |
|---|---|
ColorSpace | Values other than default and TrueColors, such as gray or rgb, return 400 "ColorSpace is not supported yet for BMP → PDF". Pixels are stored as RGB. |
Pdfa | Convert the result with /v2/convert/pdf/to/pdfa. |
Also refused when set: ColorProfile.
What carries over, and what doesn't
Kept
- Every pixel: the image extracted from the PDF equals the bitmap exactly, also after
Rotate=90or a 45 degree turn with margins - The image's own size on the page, never enlarged
- Alpha from 32-bit BMPs with an alpha mask, as a soft mask; opaque bitmaps get none
Lost or not yet supported
- The DPI written in the BMP. A 300 DPI bitmap made the same 300 × 187.5 pt page as the 96 DPI label, so a scan may print larger than its original.
- Compactness of 1-bit art: a 1-bit bitmap is stored as RGB (9,280 bytes of PDF for a 1-bit copy of the label).
- Margins unless you ask: with the defaults the label touches all four page edges.
Limits
- One BMP per request.
/v2/convert/images/to/pdftakes several images and makes one page each. - Requests up to 10 MB on the Free plan or 100 MB on paid plans, all files and fields together.
- Bitmaps over 100,000,000 pixels: 413.
- Larger images are scaled down to fit a named sheet inside its margins; smaller ones are centered at their size.
- Whole numbers only:
Rotatefrom -360 to 360 degrees, margins from 0 to 500 mm.Rotate=90.5returns 400 "Rotate must be a whole number". - 504 if the conversion takes more than 120 seconds.
Where teams use it
Printing labels and forms
Bin labels, shipping labels and forms produced as BMP can be sent to a print queue or a PDF-only workflow on a known sheet size.
Keeping scans in document systems
Older scanners and capture tools save BMP. Wrapping each scan in a PDF lets it sit in a document archive or be merged with other pages.
Questions
How large will the page be?
Without PageSize, each pixel is 0.75 pt (96 per inch). The 400 × 250 label gives a 300 × 187.5 pt page.
Is the bitmap compressed in the PDF?
Yes, losslessly with Flate. The 300,054-byte BMP became a 14,228-byte PDF on its own page size, and the image inside is still 400 × 250 with the same pixels.
Why does my 300 DPI scan come out large?
The page size is calculated at 96 pixels per inch whatever DPI the BMP records. Choose a sheet with PageSize and large scans are scaled down to fit it.
Can I set margins?
Yes, in millimeters with MarginHorizontal and MarginVertical. On the image-sized page they add white space around the label; on a named sheet they keep it off the edges and shrink it only if it no longer fits.
Which way does `Rotate` turn the bitmap?
Clockwise. In a test BMP with a red block at the top left, 90 moved the block to the top right and -90 to the bottom left. The turn is drawn into the page content, so the page has no /Rotate entry to undo.
Convert your first BMP file in a minute.