October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
html2canvas

How to Convert Multiple Divs into PNG or JPEG Images with PHP and JavaScript

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The practical solution is to render each <div> in the browser with JavaScript and html2canvas, then serialize each canvas as a separate PNG or JPEG. PHP is not the DOM-rendering step. Add PHP only when you need to store, validate, resize, re-encode, or protect the generated files on a server.

This split keeps browser downloads simple while still supporting a controlled server workflow. It also matters for accuracy: html2canvas reconstructs an image from DOM and supported styles rather than capturing the browser compositor pixel for pixel.

Choose the right architecture

Route Rendering location Best for Trade-offs
Browser export JavaScript and html2canvas Users downloading one image per card or panel No server storage; output depends on browser support, CSS, and same-origin rules
Browser render plus PHP Browser creates bytes; PHP validates and processes them Central storage, access control, image conversion, or server-generated downloads Requires upload limits, validation, authentication, and filesystem or object-storage handling

PHP GD can read and write supported image formats, but it cannot turn arbitrary HTML and CSS into an image by itself. A fully server-side browser renderer is a different architecture and is not required for this workflow.

Prepare the page

Give every target a stable selector. Keep each export element self-contained so its dimensions, background, and typography are known at capture time.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<section class="export-card" data-name="overview">
  <h2>Quarterly overview</h2>
  <p>Revenue increased 18%.</p>
</section>

<section class="export-card" data-name="details">
  <h2>Details</h2>
  <p>Three regions exceeded target.</p>
</section>

<button id="export-all" type="button">Download images</button>

Include the html2canvas library used by your project, then wait for fonts and images before exporting. The official examples demonstrate selecting an element, calling html2canvas, serializing with toDataURL('image/png'), and downloading through a link: html2canvas examples.

Export every div as its own PNG

This async loop renders one element, waits for completion, assigns a unique filename, and starts the next render only after the previous one has finished.

async function waitForImages(root) {
  const images = [...root.querySelectorAll('img')];
  await Promise.all(images.map(img => {
    if (img.complete) return Promise.resolve();
    return new Promise(resolve => {
      img.addEventListener('load', resolve, { once: true });
      img.addEventListener('error', resolve, { once: true });
    });
  }));
}

function safeName(value, fallback) {
  const cleaned = (value || '').replace(/[^a-z0-9_-]+/gi, '-').replace(/^-|-$/g, '');
  return cleaned || fallback;
}

async function exportDivsAsPng() {
  const elements = [...document.querySelectorAll('.export-card')];
  if (!elements.length) throw new Error('No .export-card elements found');

  await document.fonts.ready;
  for (const [index, element] of elements.entries()) {
    await waitForImages(element);
    const canvas = await html2canvas(element, {
      scale: window.devicePixelRatio,
      backgroundColor: null,
      useCORS: true
    });

    const link = document.createElement('a');
    const label = safeName(element.dataset.name, `card-${index + 1}`);
    link.download = `${label}.png`;
    link.href = canvas.toDataURL('image/png');
    link.click();
  }
}

document.querySelector('#export-all').addEventListener('click', () => {
  exportDivsAsPng().catch(error => {
    console.error(error);
    alert('The images could not be exported. Check the console for details.');
  });
});

devicePixelRatio produces sharper output on retina displays, but it also increases canvas memory use. Set a fixed scale such as 1 when predictable dimensions matter more than density.

Export JPEG instead of PNG

JPEG is useful for photographic cards and usually produces smaller files, but it cannot preserve transparency. Pass a quality value between 0 and 1; the exact output and format support should be checked in the browsers you support. Canvas serialization behavior is described in Apple’s WebKit documentation: HTMLCanvasElement.toDataURL.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const canvas = await html2canvas(element, {
  scale: window.devicePixelRatio,
  backgroundColor: '#ffffff'
});

const quality = 0. nueve; // replace with a number such as 0.9
const jpegData = canvas.toDataURL('image/jpeg', quality);
const link = document.createElement('a');
link.download = 'card.jpg';
link.href = jpegData;
link.click();

Replace the illustrative quality assignment with valid JavaScript: const quality = 0.9;. A solid background is recommended because transparent pixels become browser- or encoder-dependent when converted to JPEG.

Use toBlob() for many or large images

toDataURL() creates a large base64 string in memory. For batches, encode to a Blob, create an object URL, download it, and revoke that URL immediately after the click.

function canvasBlob(canvas, type, quality) {
  return new Promise((resolve, reject) => {
    canvas.toBlob(blob => blob ? resolve(blob) : reject(new Error('Encoding failed')), type, quality);
  });
}

async function downloadCanvas(canvas, filename, type = 'image/png', quality) {
  const blob = await canvasBlob(canvas, type, quality);
  const objectUrl = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = objectUrl;
  link.download = filename;
  link.click();
  setTimeout(() => URL.revokeObjectURL(objectUrl), 0);
}

Browsers may block a large burst of automatic downloads. If that happens, package files into a server-side archive or ask the user to click once per file rather than bypassing browser download protections.

Send the generated image to PHP

When the application needs persistence or centralized processing, upload the blob with fetch. Do not rely on the client filename or MIME type as validation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
async function uploadCanvas(canvas, name) {
  const blob = await canvasBlob(canvas, 'image/png');
  const form = new FormData();
  form.append('image', blob, `${name}.png`);

  const response = await fetch('/save-image.php', {
    method: 'POST',
    body: form,
    credentials: 'include'
  });
  if (!response.ok) throw new Error(`Upload failed: ${response.status}`);
  return response.json();
}

A minimal PHP endpoint can inspect the decoded bytes with GD, create a server-generated filename, and save the image outside a publicly writable directory.

<?php
declare(strict_types=1);
header('Content-Type: application/json');

if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_FILES['image'])) {
    http_response_code(400);
    echo json_encode(['error' => 'Image upload is required']);
    exit;
}

$file = $_FILES['image'];
if ($file['error'] !== UPLOAD_ERR_OK || $file['size'] > 10 * 1024 * 1024) {
    http_response_code(400);
    echo json_encode(['error' => 'Upload failed or exceeds the size limit']);
    exit;
}

$bytes = file_get_contents($file['tmp_name']);
$image = @imagecreatefromstring($bytes);
if ($image === false) {
    http_response_code(415);
    echo json_encode(['error' => 'Unsupported or corrupt image data']);
    exit;
}

$directory = __DIR__ . '/private-images';
if (!is_dir($directory)) mkdir($directory, 0700, true);
$filename = bin2hex(random_bytes(16)) . '.png';
$path = $directory . '/' . $filename;

if (!imagepng($image, $path, 6)) {
    imagedestroy($image);
    http_response_code(500);
    echo json_encode(['error' => 'Could not save image']);
    exit;
}
imagedestroy($image);
echo json_encode(['file' => $filename]);

PHP’s GD manual documents supported image functions. imagecreatefromstring() returns false for unrecognized, corrupt, or unsupported data and may issue a warning, so production code should log safely and avoid exposing filesystem details.

Security, fidelity, and browser constraints

  • Cross-origin images: images must be same-origin or served with suitable CORS headers and an appropriate html2canvas configuration. Otherwise the canvas can become tainted and cannot be read back.
  • Iframes: browser security rules prevent reading cross-origin iframe contents. Capture the iframe’s own page or redesign the content for export.
  • CSS differences: html2canvas supports a subset of CSS and may omit or approximate unsupported effects. The project describes the result as based on DOM information, not a guaranteed exact representation: html2canvas documentation.
  • Hidden content: an element with display:none has no layout to capture. Move it off-screen or render it in a visible export container before capture.
  • Fonts and lazy assets: wait for document.fonts.ready and image completion; otherwise text can reflow or appear with fallback fonts.
  • Canvas limits: very large dimensions can exceed browser memory or maximum canvas size. Reduce scale, split a long page, or export smaller elements.
  • Input validation: enforce request-size and authentication limits, decode the actual bytes, generate your own filename, and store files where users cannot execute uploaded content.

PNG or JPEG: a practical decision

Content Format Reason
UI cards, text, charts, line art PNG Sharp edges and lossless output; supports transparency
Photos or photographic backgrounds JPEG Usually smaller; choose quality deliberately
Any design requiring transparent pixels PNG JPEG has no transparency channel

Troubleshooting checklist

“html2canvas is not defined”

The library was not loaded before your export script, or the script ran in the wrong order. Load html2canvas first and confirm the global name in the browser console.

Images are missing or the export throws a security error

Inspect image origins and response headers. Move assets to the same origin or configure CORS on the image host; setting useCORS cannot override a server that sends no permission.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The result differs from the page

Check unsupported CSS, pseudo-elements, filters, blend modes, web fonts, and animations. Freeze animations, wait for fonts, and test the exact browser versions your users run.

PHP rejects a valid-looking upload

Check PHP upload limits, temporary-directory permissions, GD format support, and the actual decoded bytes. Do not accept a client-supplied extension as proof of type.

Downloads stop after the first few files

This is commonly browser anti-abuse behavior. Use a user gesture for each download, create a ZIP on the server, or upload blobs and return one archive.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

For a remote URL rather than DOM elements already open in your page, ScreenshotNeo provides a one-call screenshot API. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. It also offers an MCP server for AI agents through take_screenshot, get_page_info, and capture_pdf.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

See the ScreenshotNeo API documentation for all options, including element selectors, full-page lazy-image loading, device and retina settings, custom CSS and JavaScript, waits, request blocking, headers, cookies, geolocation, PDF output, caching, signed links, webhooks, bulk capture, and usage reporting.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots, and every feature is included on every plan. Create a free ScreenshotNeo account.

Frequently Asked Questions

Can PHP convert a live div directly into a PNG?

No. Render the DOM in a browser first; PHP can then validate, store, or re-encode the resulting bytes with GD.

Why is my export not pixel-perfect?

html2canvas rebuilds the image from DOM and supported styles, so unsupported CSS, fonts, cross-origin assets, and browser differences can change the result.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should I use one canvas for all divs or one per div?

Use one canvas per target when you need separate files and filenames. A single combined canvas is appropriate only when one composite image is the desired output.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.