Image to PDF HTTP API Examples
These examples demonstrate common Image to PDF API workflows via HTTP API.
You can run the examples below with the displayed API credentials. Update the input URLs and filenames as needed.
Using cURL Using Python Requests Using Node.js Fetch Using Node.js Axios Using PHP Guzzle
Use a Bash-compatible shell.
Basic options
-u— Supply your username and API key.-F— Send a form field.-o— Save the response to a file.-f— Report HTTP errors as command failures.-s -S— Hide the progress meter while keeping error messages.
File input
file=@document.png— Upload a local file.
Diagnostics
-
--fail-with-body— Use instead of-fto retain the error response body. -D— Save response headers to a file.-
-w— Print response information; the diagnostic example prints the HTTP status.
Install Requests with
python3 -m pip install requests. Save an example as
convert.py and run it with python3 convert.py.
Request options
auth— Supply your username and API key using HTTP Basic authentication.data— Send form fields; Requests encodes their values.files— Upload files opened in binary mode. Requests sets the multipart boundary.allow_redirects=False— Return the endpoint's response without following redirects.
Response handling
raise_for_status()— Raise an exception for HTTP errors before opening the output file.response.content— Save the response bytes to a file opened with"wb".with— Close opened files even if the request or output write fails.
Connection errors raise exceptions. The examples do not set a client timeout or
retry requests. If you add a timeout, allow for conversion time;
Requests applies connection and read timeouts, not an overall conversion deadline.
The diagnostic example
saves response headers and body and prints the HTTP status before calling
raise_for_status(), so an HTTP error still leaves diagnostic files.
Use Node.js with its built-in Fetch API; no HTTP package is needed.
Save an example as convert.mjs and run it with
node convert.mjs. The .mjs extension enables imports
and top-level await.
Request options
Authorization— Send your username and API key using HTTP Basic authentication.FormData— Send form fields and files. Fetch sets the multipart boundary.readFileandBlob— Read uploads as bytes into memory and include their filenames.redirect: 'manual'— Return the endpoint's response without following redirects.
Response handling
response.arrayBuffer()— Read the response bytes into memory.response.status— Check for HTTP errors before opening the output file; Fetch does not throw for HTTP errors itself.writeFile— Save the bytes to the output file. File and connection errors propagate as exceptions.
The examples use Fetch's native connection, response-header, and body inactivity
limits, which depend on the Node.js runtime. They do not set an overall conversion
deadline or retry requests. Allow for conversion time if you add a timeout using
an AbortSignal.
The diagnostic example saves response headers and body and prints the HTTP status before throwing on an HTTP error, so diagnostic files remain available.
Install Axios with npm install axios. Save an example as
convert.mjs and run it with node convert.mjs.
The .mjs extension enables imports and top-level await.
Request options
auth— Send your username and API key using HTTP Basic authentication.FormData— Send form fields and files. Axios sets the multipart boundary.readFileandBlob— Read uploads as bytes into memory and include their filenames.maxRedirects: 0— Return the endpoint's response without following redirects.
Response handling
responseType: 'arraybuffer'— Read the response as bytes.validateStatus— Reject HTTP errors before writing the output file.writeFile— Save the response bytes to the output file.
Axios does not set an overall timeout by default. Allow for conversion time if you add one. Failed requests and file writes produce an error message and a nonzero exit status; the error handler prints only the message so request credentials are not included.
The diagnostic example saves response headers and body and prints the HTTP status before reporting an HTTP error, so diagnostic files remain available.
Install Guzzle with composer require guzzlehttp/guzzle.
Save an example as convert.php beside your vendor
directory and run it with php convert.php.
Request options
auth— Send your username and API key using HTTP Basic authentication.multipart— Send form fields and files. Guzzle sets the multipart boundary.Utils::tryFopen— Open input files as binary streams for upload.'allow_redirects' => false— Return the endpoint's response without following redirects.
Response handling
'http_errors' => false— Inspect the HTTP status before writing the output file.getBody— Read the response as a binary string.file_put_contents— Save the response bytes and check that the entire result was written.
Guzzle does not set an overall timeout by default. Allow for conversion time if you add one. Failed requests and file writes produce an error message and a nonzero exit status.
The diagnostic example saves response headers and body and prints the HTTP status before reporting an HTTP error, so diagnostic files remain available.
Basic examples
PNG file to PDF file
curl -f -s -S \ -u 'demo:demo' \ -o logo.pdf \ -F file=@logo.png \ -F input_format=image \ https://api.pdfcrowd.com/convert/24.04/
import requests with open('logo.png', 'rb') as input_1: response = requests.post( 'https://api.pdfcrowd.com/convert/24.04/', auth=('demo', 'demo'), data={ 'input_format': 'image', }, files={ 'file': input_1, }, allow_redirects=False, ) response.raise_for_status() with open('logo.pdf', 'wb') as output_file: output_file.write(response.content)
import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("file", new Blob([await readFile("logo.png")]), basename("logo.png")); const response = await fetch("https://api.pdfcrowd.com/convert/24.04/", { method: 'POST', headers: { Authorization: 'Basic ' + Buffer.from( username + ':' + apiKey).toString('base64'), }, body: form, redirect: 'manual', }); const body = Buffer.from(await response.arrayBuffer()); if (response.status >= 400) { throw new Error('HTTP ' + response.status + ' ' + response.statusText); } await writeFile("logo.pdf", body);
import axios from 'axios'; import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("file", new Blob([await readFile("logo.png")]), basename("logo.png")); try { const response = await axios.post("https://api.pdfcrowd.com/convert/24.04/", form, { auth: { username, password: apiKey }, responseType: 'arraybuffer', maxRedirects: 0, validateStatus: status => status < 400, }); await writeFile("logo.pdf", response.data); } catch (error) { console.error(error.message); process.exitCode = 1; }
<?php require 'vendor/autoload.php'; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Utils; try { $client = new Client(); $response = $client->post('https://api.pdfcrowd.com/convert/24.04/', [ 'auth' => ['demo', 'demo'], 'multipart' => [ ['name' => 'input_format', 'contents' => 'image'], ['name' => 'file', 'contents' => Utils::tryFopen('logo.png', 'rb'), 'filename' => basename('logo.png')], ], 'allow_redirects' => false, 'http_errors' => false, ]); $status = $response->getStatusCode(); if ($status >= 400) { throw new \RuntimeException("HTTP $status " . $response->getReasonPhrase()); } $body = (string) $response->getBody(); if (file_put_contents('logo.pdf', $body) !== strlen($body)) { throw new \RuntimeException('Failed to write output file'); } } catch (\Throwable $error) { fwrite(STDERR, $error->getMessage() . "\n"); exit(1); }
PNG url to PDF file
curl -f -s -S \ -u 'demo:demo' \ -o logo.pdf \ -F url=https://your-server.com/logo.png \ -F input_format=image \ https://api.pdfcrowd.com/convert/24.04/
import requests response = requests.post( 'https://api.pdfcrowd.com/convert/24.04/', auth=('demo', 'demo'), data={ 'input_format': 'image', 'url': 'https://your-server.com/logo.png', }, allow_redirects=False, ) response.raise_for_status() with open('logo.pdf', 'wb') as output_file: output_file.write(response.content)
import { writeFile } from 'node:fs/promises'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("url", "https://your-server.com/logo.png"); const response = await fetch("https://api.pdfcrowd.com/convert/24.04/", { method: 'POST', headers: { Authorization: 'Basic ' + Buffer.from( username + ':' + apiKey).toString('base64'), }, body: form, redirect: 'manual', }); const body = Buffer.from(await response.arrayBuffer()); if (response.status >= 400) { throw new Error('HTTP ' + response.status + ' ' + response.statusText); } await writeFile("logo.pdf", body);
import axios from 'axios'; import { writeFile } from 'node:fs/promises'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("url", "https://your-server.com/logo.png"); try { const response = await axios.post("https://api.pdfcrowd.com/convert/24.04/", form, { auth: { username, password: apiKey }, responseType: 'arraybuffer', maxRedirects: 0, validateStatus: status => status < 400, }); await writeFile("logo.pdf", response.data); } catch (error) { console.error(error.message); process.exitCode = 1; }
<?php require 'vendor/autoload.php'; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Utils; try { $client = new Client(); $response = $client->post('https://api.pdfcrowd.com/convert/24.04/', [ 'auth' => ['demo', 'demo'], 'multipart' => [ ['name' => 'input_format', 'contents' => 'image'], ['name' => 'url', 'contents' => 'https://your-server.com/logo.png'], ], 'allow_redirects' => false, 'http_errors' => false, ]); $status = $response->getStatusCode(); if ($status >= 400) { throw new \RuntimeException("HTTP $status " . $response->getReasonPhrase()); } $body = (string) $response->getBody(); if (file_put_contents('logo.pdf', $body) !== strlen($body)) { throw new \RuntimeException('Failed to write output file'); } } catch (\Throwable $error) { fwrite(STDERR, $error->getMessage() . "\n"); exit(1); }
Customize the PDF
These examples use scan.png, a 1224 × 1584 pixel image with text, a chart, and a uniform white border. The rotation example uses its sideways variant, scan-sideways.png.
Fit an image onto paper
Fit the whole image onto A4 portrait or Letter landscape paper with 12mm margins and 150 DPI. The fit mode preserves the image's aspect ratio. Setting a page size without it can clip a larger image.
A4 portrait:
curl -f -s -S \ -u 'demo:demo' \ -o a4.pdf \ -F file=@scan.png \ -F input_format=image \ -F dpi=150 \ -F margin_bottom=12mm \ -F margin_left=12mm \ -F margin_right=12mm \ -F margin_top=12mm \ -F page_size=A4 \ -F print_page_mode=fit \ https://api.pdfcrowd.com/convert/24.04/
import requests with open('scan.png', 'rb') as input_1: response = requests.post( 'https://api.pdfcrowd.com/convert/24.04/', auth=('demo', 'demo'), data={ 'input_format': 'image', 'dpi': '150', 'margin_bottom': '12mm', 'margin_left': '12mm', 'margin_right': '12mm', 'margin_top': '12mm', 'page_size': 'A4', 'print_page_mode': 'fit', }, files={ 'file': input_1, }, allow_redirects=False, ) response.raise_for_status() with open('a4.pdf', 'wb') as output_file: output_file.write(response.content)
import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("dpi", "150"); form.append("margin_bottom", "12mm"); form.append("margin_left", "12mm"); form.append("margin_right", "12mm"); form.append("margin_top", "12mm"); form.append("page_size", "A4"); form.append("print_page_mode", "fit"); form.append("file", new Blob([await readFile("scan.png")]), basename("scan.png")); const response = await fetch("https://api.pdfcrowd.com/convert/24.04/", { method: 'POST', headers: { Authorization: 'Basic ' + Buffer.from( username + ':' + apiKey).toString('base64'), }, body: form, redirect: 'manual', }); const body = Buffer.from(await response.arrayBuffer()); if (response.status >= 400) { throw new Error('HTTP ' + response.status + ' ' + response.statusText); } await writeFile("a4.pdf", body);
import axios from 'axios'; import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("dpi", "150"); form.append("margin_bottom", "12mm"); form.append("margin_left", "12mm"); form.append("margin_right", "12mm"); form.append("margin_top", "12mm"); form.append("page_size", "A4"); form.append("print_page_mode", "fit"); form.append("file", new Blob([await readFile("scan.png")]), basename("scan.png")); try { const response = await axios.post("https://api.pdfcrowd.com/convert/24.04/", form, { auth: { username, password: apiKey }, responseType: 'arraybuffer', maxRedirects: 0, validateStatus: status => status < 400, }); await writeFile("a4.pdf", response.data); } catch (error) { console.error(error.message); process.exitCode = 1; }
<?php require 'vendor/autoload.php'; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Utils; try { $client = new Client(); $response = $client->post('https://api.pdfcrowd.com/convert/24.04/', [ 'auth' => ['demo', 'demo'], 'multipart' => [ ['name' => 'input_format', 'contents' => 'image'], ['name' => 'dpi', 'contents' => '150'], ['name' => 'margin_bottom', 'contents' => '12mm'], ['name' => 'margin_left', 'contents' => '12mm'], ['name' => 'margin_right', 'contents' => '12mm'], ['name' => 'margin_top', 'contents' => '12mm'], ['name' => 'page_size', 'contents' => 'A4'], ['name' => 'print_page_mode', 'contents' => 'fit'], ['name' => 'file', 'contents' => Utils::tryFopen('scan.png', 'rb'), 'filename' => basename('scan.png')], ], 'allow_redirects' => false, 'http_errors' => false, ]); $status = $response->getStatusCode(); if ($status >= 400) { throw new \RuntimeException("HTTP $status " . $response->getReasonPhrase()); } $body = (string) $response->getBody(); if (file_put_contents('a4.pdf', $body) !== strlen($body)) { throw new \RuntimeException('Failed to write output file'); } } catch (\Throwable $error) { fwrite(STDERR, $error->getMessage() . "\n"); exit(1); }
Letter landscape:
curl -f -s -S \ -u 'demo:demo' \ -o landscape.pdf \ -F file=@scan.png \ -F input_format=image \ -F dpi=150 \ -F margin_bottom=12mm \ -F margin_left=12mm \ -F margin_right=12mm \ -F margin_top=12mm \ -F orientation=landscape \ -F page_size=Letter \ -F print_page_mode=fit \ https://api.pdfcrowd.com/convert/24.04/
import requests with open('scan.png', 'rb') as input_1: response = requests.post( 'https://api.pdfcrowd.com/convert/24.04/', auth=('demo', 'demo'), data={ 'input_format': 'image', 'dpi': '150', 'margin_bottom': '12mm', 'margin_left': '12mm', 'margin_right': '12mm', 'margin_top': '12mm', 'orientation': 'landscape', 'page_size': 'Letter', 'print_page_mode': 'fit', }, files={ 'file': input_1, }, allow_redirects=False, ) response.raise_for_status() with open('landscape.pdf', 'wb') as output_file: output_file.write(response.content)
import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("dpi", "150"); form.append("margin_bottom", "12mm"); form.append("margin_left", "12mm"); form.append("margin_right", "12mm"); form.append("margin_top", "12mm"); form.append("orientation", "landscape"); form.append("page_size", "Letter"); form.append("print_page_mode", "fit"); form.append("file", new Blob([await readFile("scan.png")]), basename("scan.png")); const response = await fetch("https://api.pdfcrowd.com/convert/24.04/", { method: 'POST', headers: { Authorization: 'Basic ' + Buffer.from( username + ':' + apiKey).toString('base64'), }, body: form, redirect: 'manual', }); const body = Buffer.from(await response.arrayBuffer()); if (response.status >= 400) { throw new Error('HTTP ' + response.status + ' ' + response.statusText); } await writeFile("landscape.pdf", body);
import axios from 'axios'; import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("dpi", "150"); form.append("margin_bottom", "12mm"); form.append("margin_left", "12mm"); form.append("margin_right", "12mm"); form.append("margin_top", "12mm"); form.append("orientation", "landscape"); form.append("page_size", "Letter"); form.append("print_page_mode", "fit"); form.append("file", new Blob([await readFile("scan.png")]), basename("scan.png")); try { const response = await axios.post("https://api.pdfcrowd.com/convert/24.04/", form, { auth: { username, password: apiKey }, responseType: 'arraybuffer', maxRedirects: 0, validateStatus: status => status < 400, }); await writeFile("landscape.pdf", response.data); } catch (error) { console.error(error.message); process.exitCode = 1; }
<?php require 'vendor/autoload.php'; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Utils; try { $client = new Client(); $response = $client->post('https://api.pdfcrowd.com/convert/24.04/', [ 'auth' => ['demo', 'demo'], 'multipart' => [ ['name' => 'input_format', 'contents' => 'image'], ['name' => 'dpi', 'contents' => '150'], ['name' => 'margin_bottom', 'contents' => '12mm'], ['name' => 'margin_left', 'contents' => '12mm'], ['name' => 'margin_right', 'contents' => '12mm'], ['name' => 'margin_top', 'contents' => '12mm'], ['name' => 'orientation', 'contents' => 'landscape'], ['name' => 'page_size', 'contents' => 'Letter'], ['name' => 'print_page_mode', 'contents' => 'fit'], ['name' => 'file', 'contents' => Utils::tryFopen('scan.png', 'rb'), 'filename' => basename('scan.png')], ], 'allow_redirects' => false, 'http_errors' => false, ]); $status = $response->getStatusCode(); if ($status >= 400) { throw new \RuntimeException("HTTP $status " . $response->getReasonPhrase()); } $body = (string) $response->getBody(); if (file_put_contents('landscape.pdf', $body) !== strlen($body)) { throw new \RuntimeException('Failed to write output file'); } } catch (\Throwable $error) { fwrite(STDERR, $error->getMessage() . "\n"); exit(1); }
Create a custom-size PDF
Fit scan.png onto a 4 × 6 inch page and save custom-page.pdf. Preserve the aspect ratio and fill the unused page area with a pale blue background.
curl -f -s -S \ -u 'demo:demo' \ -o custom-page.pdf \ -F file=@scan.png \ -F input_format=image \ -F dpi=150 \ -F page_background_color=EEF2F6 \ -F page_height=6in \ -F page_width=4in \ -F print_page_mode=fit \ https://api.pdfcrowd.com/convert/24.04/
import requests with open('scan.png', 'rb') as input_1: response = requests.post( 'https://api.pdfcrowd.com/convert/24.04/', auth=('demo', 'demo'), data={ 'input_format': 'image', 'dpi': '150', 'page_background_color': 'EEF2F6', 'page_height': '6in', 'page_width': '4in', 'print_page_mode': 'fit', }, files={ 'file': input_1, }, allow_redirects=False, ) response.raise_for_status() with open('custom-page.pdf', 'wb') as output_file: output_file.write(response.content)
import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("dpi", "150"); form.append("page_background_color", "EEF2F6"); form.append("page_height", "6in"); form.append("page_width", "4in"); form.append("print_page_mode", "fit"); form.append("file", new Blob([await readFile("scan.png")]), basename("scan.png")); const response = await fetch("https://api.pdfcrowd.com/convert/24.04/", { method: 'POST', headers: { Authorization: 'Basic ' + Buffer.from( username + ':' + apiKey).toString('base64'), }, body: form, redirect: 'manual', }); const body = Buffer.from(await response.arrayBuffer()); if (response.status >= 400) { throw new Error('HTTP ' + response.status + ' ' + response.statusText); } await writeFile("custom-page.pdf", body);
import axios from 'axios'; import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("dpi", "150"); form.append("page_background_color", "EEF2F6"); form.append("page_height", "6in"); form.append("page_width", "4in"); form.append("print_page_mode", "fit"); form.append("file", new Blob([await readFile("scan.png")]), basename("scan.png")); try { const response = await axios.post("https://api.pdfcrowd.com/convert/24.04/", form, { auth: { username, password: apiKey }, responseType: 'arraybuffer', maxRedirects: 0, validateStatus: status => status < 400, }); await writeFile("custom-page.pdf", response.data); } catch (error) { console.error(error.message); process.exitCode = 1; }
<?php require 'vendor/autoload.php'; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Utils; try { $client = new Client(); $response = $client->post('https://api.pdfcrowd.com/convert/24.04/', [ 'auth' => ['demo', 'demo'], 'multipart' => [ ['name' => 'input_format', 'contents' => 'image'], ['name' => 'dpi', 'contents' => '150'], ['name' => 'page_background_color', 'contents' => 'EEF2F6'], ['name' => 'page_height', 'contents' => '6in'], ['name' => 'page_width', 'contents' => '4in'], ['name' => 'print_page_mode', 'contents' => 'fit'], ['name' => 'file', 'contents' => Utils::tryFopen('scan.png', 'rb'), 'filename' => basename('scan.png')], ], 'allow_redirects' => false, 'http_errors' => false, ]); $status = $response->getStatusCode(); if ($status >= 400) { throw new \RuntimeException("HTTP $status " . $response->getReasonPhrase()); } $body = (string) $response->getBody(); if (file_put_contents('custom-page.pdf', $body) !== strlen($body)) { throw new \RuntimeException('Failed to write output file'); } } catch (\Throwable $error) { fwrite(STDERR, $error->getMessage() . "\n"); exit(1); }
Set the physical print size
Interpret scan.png at 300 pixels per inch without setting a fixed page size. Its 1224 × 1584 pixels produce a 4.08 × 5.28 inch page in print-size.pdf, with the original image pixels retained.
curl -f -s -S \ -u 'demo:demo' \ -o print-size.pdf \ -F file=@scan.png \ -F input_format=image \ -F dpi=300 \ https://api.pdfcrowd.com/convert/24.04/
import requests with open('scan.png', 'rb') as input_1: response = requests.post( 'https://api.pdfcrowd.com/convert/24.04/', auth=('demo', 'demo'), data={ 'input_format': 'image', 'dpi': '300', }, files={ 'file': input_1, }, allow_redirects=False, ) response.raise_for_status() with open('print-size.pdf', 'wb') as output_file: output_file.write(response.content)
import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("dpi", "300"); form.append("file", new Blob([await readFile("scan.png")]), basename("scan.png")); const response = await fetch("https://api.pdfcrowd.com/convert/24.04/", { method: 'POST', headers: { Authorization: 'Basic ' + Buffer.from( username + ':' + apiKey).toString('base64'), }, body: form, redirect: 'manual', }); const body = Buffer.from(await response.arrayBuffer()); if (response.status >= 400) { throw new Error('HTTP ' + response.status + ' ' + response.statusText); } await writeFile("print-size.pdf", body);
import axios from 'axios'; import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("dpi", "300"); form.append("file", new Blob([await readFile("scan.png")]), basename("scan.png")); try { const response = await axios.post("https://api.pdfcrowd.com/convert/24.04/", form, { auth: { username, password: apiKey }, responseType: 'arraybuffer', maxRedirects: 0, validateStatus: status => status < 400, }); await writeFile("print-size.pdf", response.data); } catch (error) { console.error(error.message); process.exitCode = 1; }
<?php require 'vendor/autoload.php'; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Utils; try { $client = new Client(); $response = $client->post('https://api.pdfcrowd.com/convert/24.04/', [ 'auth' => ['demo', 'demo'], 'multipart' => [ ['name' => 'input_format', 'contents' => 'image'], ['name' => 'dpi', 'contents' => '300'], ['name' => 'file', 'contents' => Utils::tryFopen('scan.png', 'rb'), 'filename' => basename('scan.png')], ], 'allow_redirects' => false, 'http_errors' => false, ]); $status = $response->getStatusCode(); if ($status >= 400) { throw new \RuntimeException("HTTP $status " . $response->getReasonPhrase()); } $body = (string) $response->getBody(); if (file_put_contents('print-size.pdf', $body) !== strlen($body)) { throw new \RuntimeException('Failed to write output file'); } } catch (\Throwable $error) { fwrite(STDERR, $error->getMessage() . "\n"); exit(1); }
Crop or trim an image
Extract the chart from scan.png into chart.pdf, or remove its uniform outer border and save trimmed.pdf.
The chart starts 96 pixels from the left and 370 pixels from the top, and measures 1024 × 384 pixels. Set 96 DPI so the px crop coordinates match the source image pixels; adjust the region for your image. Automatic border removal works on solid-color borders; use an explicit crop for uneven scan edges.
Extract a selected region:
curl -f -s -S \ -u 'demo:demo' \ -o chart.pdf \ -F file=@scan.png \ -F input_format=image \ -F crop_area_height=384px \ -F crop_area_width=1024px \ -F crop_area_x=96px \ -F crop_area_y=370px \ -F dpi=96 \ https://api.pdfcrowd.com/convert/24.04/
import requests with open('scan.png', 'rb') as input_1: response = requests.post( 'https://api.pdfcrowd.com/convert/24.04/', auth=('demo', 'demo'), data={ 'input_format': 'image', 'crop_area_height': '384px', 'crop_area_width': '1024px', 'crop_area_x': '96px', 'crop_area_y': '370px', 'dpi': '96', }, files={ 'file': input_1, }, allow_redirects=False, ) response.raise_for_status() with open('chart.pdf', 'wb') as output_file: output_file.write(response.content)
import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("crop_area_height", "384px"); form.append("crop_area_width", "1024px"); form.append("crop_area_x", "96px"); form.append("crop_area_y", "370px"); form.append("dpi", "96"); form.append("file", new Blob([await readFile("scan.png")]), basename("scan.png")); const response = await fetch("https://api.pdfcrowd.com/convert/24.04/", { method: 'POST', headers: { Authorization: 'Basic ' + Buffer.from( username + ':' + apiKey).toString('base64'), }, body: form, redirect: 'manual', }); const body = Buffer.from(await response.arrayBuffer()); if (response.status >= 400) { throw new Error('HTTP ' + response.status + ' ' + response.statusText); } await writeFile("chart.pdf", body);
import axios from 'axios'; import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("crop_area_height", "384px"); form.append("crop_area_width", "1024px"); form.append("crop_area_x", "96px"); form.append("crop_area_y", "370px"); form.append("dpi", "96"); form.append("file", new Blob([await readFile("scan.png")]), basename("scan.png")); try { const response = await axios.post("https://api.pdfcrowd.com/convert/24.04/", form, { auth: { username, password: apiKey }, responseType: 'arraybuffer', maxRedirects: 0, validateStatus: status => status < 400, }); await writeFile("chart.pdf", response.data); } catch (error) { console.error(error.message); process.exitCode = 1; }
<?php require 'vendor/autoload.php'; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Utils; try { $client = new Client(); $response = $client->post('https://api.pdfcrowd.com/convert/24.04/', [ 'auth' => ['demo', 'demo'], 'multipart' => [ ['name' => 'input_format', 'contents' => 'image'], ['name' => 'crop_area_height', 'contents' => '384px'], ['name' => 'crop_area_width', 'contents' => '1024px'], ['name' => 'crop_area_x', 'contents' => '96px'], ['name' => 'crop_area_y', 'contents' => '370px'], ['name' => 'dpi', 'contents' => '96'], ['name' => 'file', 'contents' => Utils::tryFopen('scan.png', 'rb'), 'filename' => basename('scan.png')], ], 'allow_redirects' => false, 'http_errors' => false, ]); $status = $response->getStatusCode(); if ($status >= 400) { throw new \RuntimeException("HTTP $status " . $response->getReasonPhrase()); } $body = (string) $response->getBody(); if (file_put_contents('chart.pdf', $body) !== strlen($body)) { throw new \RuntimeException('Failed to write output file'); } } catch (\Throwable $error) { fwrite(STDERR, $error->getMessage() . "\n"); exit(1); }
Remove a uniform border:
curl -f -s -S \ -u 'demo:demo' \ -o trimmed.pdf \ -F file=@scan.png \ -F input_format=image \ -F dpi=150 \ -F remove_borders=true \ https://api.pdfcrowd.com/convert/24.04/
import requests with open('scan.png', 'rb') as input_1: response = requests.post( 'https://api.pdfcrowd.com/convert/24.04/', auth=('demo', 'demo'), data={ 'input_format': 'image', 'dpi': '150', 'remove_borders': 'true', }, files={ 'file': input_1, }, allow_redirects=False, ) response.raise_for_status() with open('trimmed.pdf', 'wb') as output_file: output_file.write(response.content)
import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("dpi", "150"); form.append("remove_borders", "true"); form.append("file", new Blob([await readFile("scan.png")]), basename("scan.png")); const response = await fetch("https://api.pdfcrowd.com/convert/24.04/", { method: 'POST', headers: { Authorization: 'Basic ' + Buffer.from( username + ':' + apiKey).toString('base64'), }, body: form, redirect: 'manual', }); const body = Buffer.from(await response.arrayBuffer()); if (response.status >= 400) { throw new Error('HTTP ' + response.status + ' ' + response.statusText); } await writeFile("trimmed.pdf", body);
import axios from 'axios'; import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("dpi", "150"); form.append("remove_borders", "true"); form.append("file", new Blob([await readFile("scan.png")]), basename("scan.png")); try { const response = await axios.post("https://api.pdfcrowd.com/convert/24.04/", form, { auth: { username, password: apiKey }, responseType: 'arraybuffer', maxRedirects: 0, validateStatus: status => status < 400, }); await writeFile("trimmed.pdf", response.data); } catch (error) { console.error(error.message); process.exitCode = 1; }
<?php require 'vendor/autoload.php'; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Utils; try { $client = new Client(); $response = $client->post('https://api.pdfcrowd.com/convert/24.04/', [ 'auth' => ['demo', 'demo'], 'multipart' => [ ['name' => 'input_format', 'contents' => 'image'], ['name' => 'dpi', 'contents' => '150'], ['name' => 'remove_borders', 'contents' => 'true'], ['name' => 'file', 'contents' => Utils::tryFopen('scan.png', 'rb'), 'filename' => basename('scan.png')], ], 'allow_redirects' => false, 'http_errors' => false, ]); $status = $response->getStatusCode(); if ($status >= 400) { throw new \RuntimeException("HTTP $status " . $response->getReasonPhrase()); } $body = (string) $response->getBody(); if (file_put_contents('trimmed.pdf', $body) !== strlen($body)) { throw new \RuntimeException('Failed to write output file'); } } catch (\Throwable $error) { fwrite(STDERR, $error->getMessage() . "\n"); exit(1); }
Correct image rotation
Rotate scan-sideways.png 90 degrees clockwise to restore the upright orientation, then save upright.pdf.
curl -f -s -S \ -u 'demo:demo' \ -o upright.pdf \ -F file=@scan-sideways.png \ -F input_format=image \ -F dpi=150 \ -F rotate=90 \ https://api.pdfcrowd.com/convert/24.04/
import requests with open('scan-sideways.png', 'rb') as input_1: response = requests.post( 'https://api.pdfcrowd.com/convert/24.04/', auth=('demo', 'demo'), data={ 'input_format': 'image', 'dpi': '150', 'rotate': '90', }, files={ 'file': input_1, }, allow_redirects=False, ) response.raise_for_status() with open('upright.pdf', 'wb') as output_file: output_file.write(response.content)
import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("dpi", "150"); form.append("rotate", "90"); form.append("file", new Blob([await readFile("scan-sideways.png")]), basename("scan-sideways.png")); const response = await fetch("https://api.pdfcrowd.com/convert/24.04/", { method: 'POST', headers: { Authorization: 'Basic ' + Buffer.from( username + ':' + apiKey).toString('base64'), }, body: form, redirect: 'manual', }); const body = Buffer.from(await response.arrayBuffer()); if (response.status >= 400) { throw new Error('HTTP ' + response.status + ' ' + response.statusText); } await writeFile("upright.pdf", body);
import axios from 'axios'; import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("dpi", "150"); form.append("rotate", "90"); form.append("file", new Blob([await readFile("scan-sideways.png")]), basename("scan-sideways.png")); try { const response = await axios.post("https://api.pdfcrowd.com/convert/24.04/", form, { auth: { username, password: apiKey }, responseType: 'arraybuffer', maxRedirects: 0, validateStatus: status => status < 400, }); await writeFile("upright.pdf", response.data); } catch (error) { console.error(error.message); process.exitCode = 1; }
<?php require 'vendor/autoload.php'; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Utils; try { $client = new Client(); $response = $client->post('https://api.pdfcrowd.com/convert/24.04/', [ 'auth' => ['demo', 'demo'], 'multipart' => [ ['name' => 'input_format', 'contents' => 'image'], ['name' => 'dpi', 'contents' => '150'], ['name' => 'rotate', 'contents' => '90'], ['name' => 'file', 'contents' => Utils::tryFopen('scan-sideways.png', 'rb'), 'filename' => basename('scan-sideways.png')], ], 'allow_redirects' => false, 'http_errors' => false, ]); $status = $response->getStatusCode(); if ($status >= 400) { throw new \RuntimeException("HTTP $status " . $response->getReasonPhrase()); } $body = (string) $response->getBody(); if (file_put_contents('upright.pdf', $body) !== strlen($body)) { throw new \RuntimeException('Failed to write output file'); } } catch (\Throwable $error) { fwrite(STDERR, $error->getMessage() . "\n"); exit(1); }
Create a smaller PDF
Render scan.png onto A4 paper at 72 DPI and save compact.pdf. Keep the same fit and 12mm margins as the 150 DPI A4 example above, while reducing resolution for screen viewing. Smaller files come at the cost of fine detail.
curl -f -s -S \ -u 'demo:demo' \ -o compact.pdf \ -F file=@scan.png \ -F input_format=image \ -F dpi=72 \ -F margin_bottom=12mm \ -F margin_left=12mm \ -F margin_right=12mm \ -F margin_top=12mm \ -F page_size=A4 \ -F print_page_mode=fit \ https://api.pdfcrowd.com/convert/24.04/
import requests with open('scan.png', 'rb') as input_1: response = requests.post( 'https://api.pdfcrowd.com/convert/24.04/', auth=('demo', 'demo'), data={ 'input_format': 'image', 'dpi': '72', 'margin_bottom': '12mm', 'margin_left': '12mm', 'margin_right': '12mm', 'margin_top': '12mm', 'page_size': 'A4', 'print_page_mode': 'fit', }, files={ 'file': input_1, }, allow_redirects=False, ) response.raise_for_status() with open('compact.pdf', 'wb') as output_file: output_file.write(response.content)
import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("dpi", "72"); form.append("margin_bottom", "12mm"); form.append("margin_left", "12mm"); form.append("margin_right", "12mm"); form.append("margin_top", "12mm"); form.append("page_size", "A4"); form.append("print_page_mode", "fit"); form.append("file", new Blob([await readFile("scan.png")]), basename("scan.png")); const response = await fetch("https://api.pdfcrowd.com/convert/24.04/", { method: 'POST', headers: { Authorization: 'Basic ' + Buffer.from( username + ':' + apiKey).toString('base64'), }, body: form, redirect: 'manual', }); const body = Buffer.from(await response.arrayBuffer()); if (response.status >= 400) { throw new Error('HTTP ' + response.status + ' ' + response.statusText); } await writeFile("compact.pdf", body);
import axios from 'axios'; import { readFile, writeFile } from 'node:fs/promises'; import { basename } from 'node:path'; const username = 'demo'; const apiKey = 'demo'; const form = new FormData(); form.append("input_format", "image"); form.append("dpi", "72"); form.append("margin_bottom", "12mm"); form.append("margin_left", "12mm"); form.append("margin_right", "12mm"); form.append("margin_top", "12mm"); form.append("page_size", "A4"); form.append("print_page_mode", "fit"); form.append("file", new Blob([await readFile("scan.png")]), basename("scan.png")); try { const response = await axios.post("https://api.pdfcrowd.com/convert/24.04/", form, { auth: { username, password: apiKey }, responseType: 'arraybuffer', maxRedirects: 0, validateStatus: status => status < 400, }); await writeFile("compact.pdf", response.data); } catch (error) { console.error(error.message); process.exitCode = 1; }
<?php require 'vendor/autoload.php'; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Utils; try { $client = new Client(); $response = $client->post('https://api.pdfcrowd.com/convert/24.04/', [ 'auth' => ['demo', 'demo'], 'multipart' => [ ['name' => 'input_format', 'contents' => 'image'], ['name' => 'dpi', 'contents' => '72'], ['name' => 'margin_bottom', 'contents' => '12mm'], ['name' => 'margin_left', 'contents' => '12mm'], ['name' => 'margin_right', 'contents' => '12mm'], ['name' => 'margin_top', 'contents' => '12mm'], ['name' => 'page_size', 'contents' => 'A4'], ['name' => 'print_page_mode', 'contents' => 'fit'], ['name' => 'file', 'contents' => Utils::tryFopen('scan.png', 'rb'), 'filename' => basename('scan.png')], ], 'allow_redirects' => false, 'http_errors' => false, ]); $status = $response->getStatusCode(); if ($status >= 400) { throw new \RuntimeException("HTTP $status " . $response->getReasonPhrase()); } $body = (string) $response->getBody(); if (file_put_contents('compact.pdf', $body) !== strlen($body)) { throw new \RuntimeException('Failed to write output file'); } } catch (\Throwable $error) { fwrite(STDERR, $error->getMessage() . "\n"); exit(1); }