Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsTo stop jsPDF from stretching an image, preserve its aspect ratio: choose a target width or height, then calculate the other dimension from the image’s original dimensions. For HTML rendered with doc.html(), coordinate the target PDF width with the CSS-pixel rendering width and avoid conflicting scale settings. These are separate workflows: image placement controls an image’s proportions, while HTML rendering can also change layout through viewport sizing and page breaks.
Why jsPDF stretches images and elements
An image has an intrinsic aspect ratio: its width divided by its height. If you tell jsPDF to draw it into a box whose width-to-height ratio differs from the image’s, it has to distort the image to fill the box. For example, forcing a wide image into a nearly square box makes it look tall and narrow.
This is a placement issue, not a PDF compression issue. The jsPDF issue about adding an image without distorting its ratio describes the same symptom and the ratio-preserving calculation: jsPDF issue #3401.
HTML-to-PDF can appear stretched for a different reason. jsPDF’s HTML plug-in renders an element and scales it to a target PDF width; the CSS layout used during rendering depends on the browser viewport width. If the render width, PDF width, and any explicit canvas scale disagree, the result may look unexpectedly large, small, or reflowed. The plug-in documents that width scales the rendered element to a PDF width in jsPDF units: jsPDF HTML plug-in options.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
- EDIT text, images & designs in PDF documents. ORGANIZE PDFs. Convert PDFs to Word, Excel & ePub.
- READ and Comment PDFs – Intuitive reading modes & document commenting and mark up.
- CREATE, COMBINE, SCAN and COMPRESS PDFs
- FILL forms & Digitally Sign PDFs. PROTECT and Encrypt PDFs
- LIFETIME License for 1 Windows PC or Laptop. 5GB MobiDrive Cloud Storage Included.
Keep an image’s aspect ratio with addImage
Read the image’s source dimensions with getImageProperties(), choose a width, and derive the height proportionally. Do not independently guess both dimensions.
const props = pdf.getImageProperties(imgData);
const targetWidth = 180; // jsPDF units; for example, mm if the document uses mm
const targetHeight = (props.height * targetWidth) / props.width;
pdf.addImage(imgData, 'PNG', x, y, targetWidth, targetHeight);
The formula is targetHeight = sourceHeight × targetWidth ÷ sourceWidth. If instead the height is the constraint, calculate targetWidth = sourceWidth × targetHeight ÷ sourceHeight. Be consistent about units: the source dimensions are used as a ratio, while the target position and dimensions must use the jsPDF document’s units.
Fit an image inside a box without cropping
When you have a maximum width and height, use the smaller of the two scale factors. This is the “contain” behavior: the complete image fits inside the box, its proportions remain intact, and unused space may remain on one axis.
function addImageContained(pdf, imgData, format, x, y, boxWidth, boxHeight) {
const { width: sourceWidth, height: sourceHeight } =
pdf.getImageProperties(imgData);
if (!sourceWidth || !sourceHeight) {
throw new Error('Could not read image dimensions');
}
const scale = Math.min(boxWidth / sourceWidth, boxHeight / sourceHeight);
const width = sourceWidth * scale;
const height = sourceHeight * scale;
// Center within the box; remove these offsets to align at its top-left.
const imageX = x + (boxWidth - width) / 2;
const imageY = y + (boxHeight - height) / 2;
pdf.addImage(imgData, format, imageX, imageY, width, height);
}
// Example: box dimensions are in the document's units.
addImageContained(pdf, imgData, 'PNG', 10, 20, 180, 100);
This function assumes the supplied image data and format are valid and the box dimensions are positive. If you want a full-bleed image or deliberate cropping, use a crop operation before placement or a suitable image-processing approach; do not distort the image by forcing two mismatched dimensions.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →What to check when the source looks distorted already
- Confirm that the data URL, canvas, or image supplied to
addImage()has the dimensions and proportions you expect. - Check that the format argument matches the actual image data.
- Inspect the generated image itself before investigating PDF placement. If it was resized non-proportionally before being passed to jsPDF, ratio-preserving placement cannot restore the original shape.
Fit HTML to an A4 page without distorting its layout
For HTML, decide the CSS layout width first, then render it at that width and scale the rendered result to the desired PDF content width. With doc.html(), set width in jsPDF units and windowWidth in CSS pixels together. The latter should reflect the width used to lay out the source element. The units are not interchangeable.
const element = document.querySelector('#content');
if (!element) throw new Error('Missing #content element');
const pdf = new jsPDF({ unit: 'mm', format: 'a4', orientation: 'portrait' });
const pageWidth = pdf.internal.pageSize.getWidth();
const margin = 10;
const contentWidth = pageWidth - margin * 2;
pdf.html(element, {
x: margin,
y: margin,
width: contentWidth,
windowWidth: element.scrollWidth,
autoPaging: 'text',
callback: doc => doc.save('output.pdf')
});
Load the jsPDF HTML plug-in and its required dependencies according to the version and bundle you use; this snippet assumes jsPDF is available in scope. The callback saves after rendering completes. In this configuration, the content is laid out at the element’s scroll width, then fitted to the available PDF content width. If the source layout is wider than that content area, the rendered result is scaled down; that can make text smaller, but should not change the proportions of images.
Rank #2
- Edit PDFs with Ease. Modify text, images, and layouts directly within your PDF documents.
- Convert & Organize. Export PDFs to Word, Excel, or ePub, and organize files with ease.
- Read & Annotate. Enjoy intuitive reading modes and powerful tools to comment, highlight, and mark up PDFs.
- Create & Manage PDFs. Create new PDFs, combine multiple files, scan documents, and compress for easy sharing.
- Fill & Sign Forms. Complete forms and digitally sign documents with secure e-signature tools.
Avoid conflicting scale controls
When relying on width plus windowWidth, do not also set a conflicting html2canvas.scale. The jsPDF HTML plug-in documentation states that width has no effect when html2canvas.scale is specified or when windowWidth is omitted. If you need to control raster sharpness with an explicit scale, test the output at your intended viewport and do not expect width alone to govern the result.
Choose a page-break mode for the content
For mostly text-based documents, autoPaging: 'text' tries not to split text in half. The default true (also described as 'slice') may cut shapes or text chunks across page breaks. Neither mode guarantees that every complex layout will break exactly as a browser page would; check tables, positioned elements, and other content that crosses a page boundary.
Use html2canvas directly when you need canvas control
If your workflow calls html2canvas yourself rather than relying on doc.html(), give it a viewport matching the element’s scroll dimensions when content is being clipped:
const element = document.querySelector('#content');
if (!element) throw new Error('Missing #content element');
const canvas = await html2canvas(element, {
windowWidth: element.scrollWidth,
windowHeight: element.scrollHeight
});
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({ unit: 'mm', format: 'a4', orientation: 'portrait' });
const pageWidth = pdf.internal.pageSize.getWidth();
const margin = 10;
const imageWidth = pageWidth - margin * 2;
const imageHeight = canvas.height * imageWidth / canvas.width;
pdf.addImage(imgData, 'PNG', margin, margin, imageWidth, imageHeight);
pdf.save('output.pdf');
This minimal example places a single image of the whole canvas. It preserves the canvas ratio, but a tall canvas may extend beyond one PDF page; it is not a multipage HTML pagination solution. Use a page-aware workflow for long documents. html2canvas’s configuration distinguishes canvas dimensions from rendering viewport dimensions and crop offsets: html2canvas configuration.
Know which width and height you are changing
widthandheightset canvas dimensions;windowWidthandwindowHeightdefine the rendering viewport and can affect layout and media queries.scalecontrols raster rendering scale. Its default iswindow.devicePixelRatio; changing it affects pixel dimensions and sharpness, not the CSS layout width you should choose.xandyare crop offsets in html2canvas configuration, not PDF placement coordinates.- CSS pixels, canvas pixels, and jsPDF units are different measurements. Establish the CSS layout first, then preserve the resulting image ratio when mapping it onto the PDF.
Diagnose output that is blurry, blank, or cut off
Blurry output
A canvas is a raster image. If it is rendered with too few pixels for the size at which it is placed in the PDF, text and fine details may look soft. Raising scale increases raster dimensions, but also increases memory use and the chance of hitting browser canvas limits. Do not use an arbitrary PDF width or height to compensate; preserve the ratio and choose the render scale for the output size you need.
Blank or partially rendered output
Very large canvases can exceed browser limits. The html2canvas FAQ gives rough maximum dimensions of about 32,767 pixels per dimension for Chrome/Chromium, Firefox, and desktop Safari, and lower limits on iOS Safari; maximum area varies by browser and platform. These are guidance figures, not guarantees. The FAQ warns that when a canvas exceeds a limit, a browser may silently produce blank or partial output without throwing an error: html2canvas FAQ.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Rank #3
- EVERY PDF TOOL UNLOCKED - 30+ tools in one app: edit text and images, convert, merge, split, compress, sign, OCR, redact, watermark, batch process, and more. No feature gates, no upsells, nothing held back.
- PAY ONCE, OWN FOREVER — A one-time purchase, not a subscription. Other apps runs $240/year — Scrivar is yours for life, with free updates included.
- UNLIMITED eSIGN, BUILT IN — Send contracts and forms for signature and track every step. Recipients sign in their browser with no account or app needed. Replace DocuSign and save hundreds a year.
- PC, MAC, AND WEB — Install on any Win 10/11 PC or macOS 11+ Mac (Intel or Apple Silicon), or work in your browser at scrivar.com. Same tools, same account, everywhere you work.
- OCR + FULL OFFICE CONVERSION — Turn scanned documents into searchable, selectable text, and convert PDFs to and from Word, Excel, and PowerPoint with formatting kept intact.
For a very long page, avoid treating a single enormous canvas as a reliable multipage-document strategy. Render or paginate content in manageable sections using a workflow appropriate for your document, and inspect the output in the browsers you support.
Missing images or effects
- Cross-origin images: html2canvas may skip images that would taint the canvas. Try
useCORS: trueonly when the image server sends an appropriateAccess-Control-Allow-Originheader, or serve the asset through a same-origin proxy. - Unsupported CSS: html2canvas does not implement every CSS property. If the browser view is correct but the PDF render is not, simplify or isolate effects that are not supported rather than assuming jsPDF’s image placement caused the mismatch.
- Responsive layout changes:
windowWidthaffects the rendering viewport and can trigger different media queries. Set it to the intended CSS layout width and verify the page at that width.
A practical troubleshooting sequence
- Measure the source element’s actual
scrollWidthandscrollHeight. - Decide whether the goal is to preserve one image’s full ratio or to reflow HTML to a target page width. These need different fixes.
- For
addImage(), calculate one target dimension from the source dimensions; do not guess both. - For
doc.html(), setwidthandwindowWidthtogether and remove a conflictinghtml2canvas.scaleoverride. - For direct html2canvas rendering with clipped content, match
windowWidthandwindowHeightto the element’s scroll dimensions. - If the result is blank or partial, reduce canvas size or split the document, then check the target browser’s canvas limits.
- If assets or visual effects are missing, investigate CORS and CSS support before changing PDF placement dimensions.
- Validate representative source aspect ratios and viewport sizes in the browsers you plan to support. This is an engineering check, not a guarantee that every browser will render identical output.
Or skip the browser setup
If your actual task is capturing a website as an image or PDF rather than controlling local jsPDF placement, ScreenshotNeo is a separate hosted screenshot API and MCP server; it is not a fix for a distorted addImage() call. Its one-request API can return a screenshot or PDF. See the ScreenshotNeo website and API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
- It accepts cookie or consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off.
- Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed; response headers report the page verdict and billing status.
- An MCP server provides
take_screenshot,get_page_info, andcapture_pdftools for AI agents, including Claude, Cursor, and other MCP clients. - The free plan includes 1,000 shots a month with no card. Paid plans start at $5 for 3,000 shots; yearly billing gives two months free, and every feature is on every plan.
Sign up for ScreenshotNeo’s free plan to try 1,000 screenshots a month with no card.
Frequently Asked Questions
Does keeping an image’s aspect ratio guarantee it will fit on one PDF page?
No. It prevents distortion, but a tall image can still extend beyond the page. Fitting, cropping, or pagination is a separate layout decision.
Why can the PDF look different from the browser even when the dimensions are correct?
html2canvas has CSS features it does not implement, and its viewport can trigger different responsive styles. Check CSS support and the rendering viewport as well as the dimensions.
Are the canvas limits exact across all browsers and devices?
No. The html2canvas FAQ’s figures are approximate guidance; limits vary by browser, platform, and maximum canvas area.
Quick Recap
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.

