Skip to content
pdfconversionapi

PNM to BMP API

POST a .ppm, .pgm, .pbm or .pam file to /v2/convert/pnm/to/bmp and get an uncompressed bitmap. An opaque image is written with 24 bits per pixel: the 230,415-byte sample PPM became a 230,454-byte BMP with the same pixels.

Endpoint
POST /v2/convert/pnm/to/bmp
Accepts
pnm
Sample timing
1 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/pnm/to/bmp \
  -H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
  -F File=@three-spheres-render.ppm \
  -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 OK1 ms median1 file, 225 KB
{
  "ConversionCost": 1,
  "ConversionTime": 0.001,
  "Files": [
    {
      "FileName": "three-spheres-render.bmp",
      "FileExt": "bmp",
      "FileSize": 230454,
      "FileData": "Qk02hAMAAAAAADYAAAAoAAAA…"
    }
  ]
}

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 three-spheres-render.bmp, rendered by the API
Input
three-spheres-render.ppm (225 KB)
Output
three-spheres-render.bmp (225 KB)
Source
A 320 x 240 frame from a small ray tracer we wrote for this page (three spheres on a checkered floor), saved as a binary PPM (P6) with 8 bits per channel. (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
ImageWidthintegerBitmap width; ImageWidth=128 gives 128 × 96 and 36,918 bytes.Values: 1–20000
ImageHeightintegerBitmap height, or the box height together with a width.Values: 1–20000
ScaleProportionsboolean, default truefalse stretches to the exact box; a 200 × 200 box then gives a square bitmap instead of 200 × 150.
ScaleIfLargerboolean, default falsetrue avoids enlarging the frame, which in a 24-bit BMP grows the file by 3 bytes for every added pixel.
ScaleImageboolean, default truefalse crops the top-left area of the requested size.
ColorSpaceenum, default defaultChanges pixel values only: gray and monochrome still write a 24-bit bitmap of 230,454 bytes, with red, green and blue equal.Values: default, rgb, gray, monochrome
ImageResolutionintegerStored as pixels per meter in the header (300 writes 11,811). Left out, the fields are 0.Values: 10–800
ImageInterpolationboolean, default falseAccepted; resizing is always Lanczos.
FileNamestringBase name of the .bmp; defaults to the upload's.
StoreFileboolean, default falseReturn a link kept for 3 hours instead of 300 KB of base64.

What carries over, and what doesn't

Kept

  • Every pixel: the sample BMP holds exactly the PPM's RGB values
  • Alpha from PAM files: a P7 RGB_ALPHA test file became a 32-bit bitmap that kept alpha 0, 128 and 255
  • The 320 × 240 frame size

Lost or not yet supported

  • Compact gray storage. A 76,815-byte PGM became a 230,454-byte 24-bit bitmap, three times larger, since there is no 8-bit gray or palette output.
  • 16-bit samples, reduced to 8 bits.
  • 1-bit packing: a 9,611-byte PBM also became a 230,454-byte 24-bit bitmap.

Limits

  • One file per request.
  • Requests up to 10 MB on the Free plan or 100 MB on paid plans, all files and fields together.
  • 100,000,000 pixels per image, also after resizing.
  • 120 seconds per conversion, then 504.

Where teams use it

Tools that read BMP but not netpbm

If a Windows utility, paint program or embedded toolchain you rely on opens bitmaps but not .ppm or .pgm, converting lets it use frames written by netpbm-based code.

Raw BGR buffers

The BMP's pixels start at byte 54 as uncompressed blue, green and red bytes, bottom row first. Rows are padded to a multiple of 4 bytes; a 320 px row is 960 bytes, so the sample has no padding. They can be copied into a texture or framebuffer without a decoder.

Questions

Is the BMP bigger than my PPM?

Barely, for an opaque image. Both store 3 bytes per pixel, and the BMP's header is 54 bytes against the PPM's 15, so the 320 × 240 sample went from 230,415 to 230,454 bytes. Widths whose rows don't fill a multiple of 4 bytes add a little padding per row. A PAM with transparency becomes a 32-bit bitmap: 307,322 bytes at the same size.

Can I get a 24-bit or 8-bit BMP?

24-bit is what any opaque input gives: PPM, PGM, PBM, or a PAM whose alpha is 255 everywhere. A PAM with transparency gives 32 bits per pixel. There is no 8-bit or palette option; ColorSpace=gray makes the pixels gray without changing the format.

Does the bitmap keep the alpha of a PAM file?

Yes. A PAM with any transparent pixel gives a 32-bit bitmap whose header's alpha mask marks the fourth byte as alpha, and a test PAM with transparent and half-transparent rows kept those values exactly.

Convert your first PNM file in a minute.