Multi Tool Nest Menu
Main Navigation

JPG to PDF Converter

Convert your JPG images to PDF documents online for free. Combine multiple images into a single PDF with our professional converter tool. No installation or registration required.

Convert JPG to PDF Online

Drop JPG Images Here

or click to select files from your computer

Supports JPG, JPEG, PNG, BMP • Max 10MB per image

How to Convert JPG to PDF - Step by Step

1. Upload Images

Select or drag-and-drop your JPG images into the converter tool.

2. Arrange Order

Preview and rearrange your images in the desired order for the PDF.

3. Configure Options

Choose page orientation, image quality, and other PDF settings.

4. Download PDF

Click convert and download your professional PDF document.

Benefits of Using Our JPG to PDF Converter

100% Secure & Private

All processing happens locally in your browser. Your images never leave your device, ensuring complete privacy and security.

Lightning Fast

Convert multiple images to PDF in seconds. Our optimized algorithm ensures quick processing without compromising quality.

Mobile Friendly

Works perfectly on all devices - desktop, tablet, and mobile. Convert images to PDF anywhere, anytime.

Unlimited Conversions

No daily limits or restrictions. Convert as many images to PDF as you need, completely free of charge.

Multiple Format Support

Supports JPG, JPEG, PNG, BMP, and other common image formats. Mix different formats in a single PDF.

Customizable Output

Control page orientation, image quality, and layout to create PDFs that meet your specific requirements.

Complete Guide to JPG to PDF Conversion: Professional Image-to-Document Solutions

`; fileList.appendChild(fileItem); }); } function displayImagePreviews() { if (!imagePreview || !imageGrid) return; imageGrid.innerHTML = ''; imagePreview.style.display = 'block'; selectedImages.forEach((file, index) => { const reader = new FileReader(); reader.onload = function(e) { const imageDiv = document.createElement('div'); imageDiv.className = 'relative bg-white border border-gray-200 rounded-lg p-3'; imageDiv.innerHTML = ` ${file.name}

${file.name}

${formatFileSize(file.size)}

Converting...'; // Convert images to PDF await createPDFFromImages(); // Show download button showDownload(); } catch (error) { console.error('Conversion error:', error); showNotification('Error converting images to PDF: ' + error.message, 'error'); } finally { hideProgress(); isProcessing = false; convertBtn.disabled = false; convertBtn.innerHTML = ' Convert to PDF'; } } async function loadPDFLib() { return new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = 'https://cdn.jsdelivr.net/npm/pdf-lib@1.17.1/dist/pdf-lib.min.js'; script.onload = () => { console.log('PDF-lib loaded successfully'); resolve(); }; script.onerror = reject; document.head.appendChild(script); }); } async function createPDFFromImages() { const totalImages = selectedImages.length; const orientation = document.getElementById('pageOrientation')?.value || 'portrait'; const quality = document.getElementById('imageQuality')?.value || 'high'; // Get PDF-lib classes const { PDFDocument } = window.PDFLib; // Create new PDF document const pdfDoc = await PDFDocument.create(); updateProgress(5, 'Creating PDF document...'); for (let i = 0; i < totalImages; i++) { const image = selectedImages[i]; const progress = Math.round(5 + ((i / totalImages) * 90)); updateProgress(progress, `Processing image ${i + 1} of ${totalImages}...`); try { // Read image data const imageArrayBuffer = await image.arrayBuffer(); // Determine image format and embed let embeddedImage; if (image.type === 'image/jpeg' || image.type === 'image/jpg') { embeddedImage = await pdfDoc.embedJpg(imageArrayBuffer); } else if (image.type === 'image/png') { embeddedImage = await pdfDoc.embedPng(imageArrayBuffer); } else { // Convert other formats to PNG using canvas const pngArrayBuffer = await convertImageToPng(image); embeddedImage = await pdfDoc.embedPng(pngArrayBuffer); } // Get image dimensions const imgDims = embeddedImage.scale(1); // Calculate page size based on orientation and image let pageWidth, pageHeight; if (orientation === 'landscape') { pageWidth = Math.max(imgDims.width, imgDims.height); pageHeight = Math.min(imgDims.width, imgDims.height); } else { pageWidth = Math.min(imgDims.width, imgDims.height); pageHeight = Math.max(imgDims.width, imgDims.height); } // Use standard page size if image is very small or very large const maxSize = 841.89; // A4 height in points const minSize = 595.28; // A4 width in points if (pageWidth > maxSize || pageHeight > maxSize) { const scale = Math.min(maxSize / pageWidth, maxSize / pageHeight); pageWidth *= scale; pageHeight *= scale; } if (pageWidth < minSize) pageWidth = minSize; if (pageHeight < minSize) pageHeight = minSize; // Create page const page = pdfDoc.addPage([pageWidth, pageHeight]); // Calculate image scale to fit page const scaleX = pageWidth / imgDims.width; const scaleY = pageHeight / imgDims.height; const scale = Math.min(scaleX, scaleY) * 0.95; // 95% to leave small margin const scaledWidth = imgDims.width * scale; const scaledHeight = imgDims.height * scale; // Center image on page const x = (pageWidth - scaledWidth) / 2; const y = (pageHeight - scaledHeight) / 2; // Draw image on page page.drawImage(embeddedImage, { x: x, y: y, width: scaledWidth, height: scaledHeight, }); } catch (imageError) { console.error(`Error processing image ${i + 1}:`, imageError); throw new Error(`Failed to process image: ${image.name}`); } } updateProgress(95, 'Finalizing PDF...'); // Save PDF const pdfBytes = await pdfDoc.save(); // Create download blob window.generatedPDFBlob = new Blob([pdfBytes], { type: 'application/pdf' }); updateProgress(100, 'PDF created successfully!'); } async function convertImageToPng(imageFile) { return new Promise((resolve, reject) => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const img = new Image(); img.onload = function() { canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0); canvas.toBlob(async (blob) => { const arrayBuffer = await blob.arrayBuffer(); resolve(arrayBuffer); }, 'image/png'); }; img.onerror = reject; img.src = URL.createObjectURL(imageFile); }); } function showProgress() { if (loadingSpinner) { loadingSpinner.style.display = 'block'; } } function hideProgress() { if (loadingSpinner) { loadingSpinner.style.display = 'none'; } } function updateProgress(percent, text) { // Progress indication through loading spinner and notifications showNotification(text, 'success'); } function showDownload() { if (downloadSection) { downloadSection.style.display = 'block'; } // Set up download button if it exists if (downloadBtn) { downloadBtn.onclick = downloadPDF; } } function resetTool() { selectedImages = []; isProcessing = false; if (fileInput) fileInput.value = ''; // Show drop zone again if (dropZone) dropZone.style.display = 'block'; // Hide other sections if (fileInfoArea) fileInfoArea.style.display = 'none'; if (imagePreview) imagePreview.style.display = 'none'; if (actionButtons) actionButtons.style.display = 'none'; if (downloadSection) downloadSection.style.display = 'none'; if (loadingSpinner) loadingSpinner.style.display = 'none'; // Reset convert button if (convertBtn) { convertBtn.disabled = true; convertBtn.classList.add('opacity-50', 'cursor-not-allowed'); convertBtn.innerHTML = ' Convert to PDF'; } // Clear file list and image grid if (fileList) fileList.innerHTML = ''; if (imageGrid) imageGrid.innerHTML = ''; } function formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } function showNotification(message, type = 'success') { // Create notification element if it doesn't exist let notification = document.getElementById('notification'); if (!notification) { notification = document.createElement('div'); notification.id = 'notification'; notification.style.cssText = ` position: fixed; top: 20px; right: 20px; padding: 12px 24px; border-radius: 8px; color: white; font-weight: 500; z-index: 9999; transform: translateX(400px); transition: transform 0.3s ease; `; document.body.appendChild(notification); } // Set message and style based on type notification.textContent = message; notification.style.backgroundColor = type === 'success' ? '#10b981' : '#ef4444'; // Show notification notification.style.transform = 'translateX(0)'; // Hide after 4 seconds setTimeout(() => { notification.style.transform = 'translateX(400px)'; }, 4000); } // Global functions for inline event handlers window.removeImage = function(index) { selectedImages.splice(index, 1); if (selectedImages.length === 0) { resetTool(); } else { showFileInfo(); displayImagePreviews(); } }; window.moveImageUp = function(index) { if (index > 0) { [selectedImages[index], selectedImages[index - 1]] = [selectedImages[index - 1], selectedImages[index]]; displayImagePreviews(); } }; window.moveImageDown = function(index) { if (index < selectedImages.length - 1) { [selectedImages[index], selectedImages[index + 1]] = [selectedImages[index + 1], selectedImages[index]]; displayImagePreviews(); } }; function downloadPDF() { if (!window.generatedPDFBlob) { showNotification('No PDF to download. Please convert images first.', 'error'); return; } const url = URL.createObjectURL(window.generatedPDFBlob); const a = document.createElement('a'); a.href = url; a.download = 'converted-images.pdf'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); showNotification('PDF downloaded successfully!', 'success'); } // Enhanced FAQ functionality with accordion behavior window.toggleFAQ = function(element) { const answer = element.nextElementSibling; const icon = element.querySelector('i'); const question = element; const allAnswers = document.querySelectorAll('.faq-answer'); const allQuestions = document.querySelectorAll('.faq-question'); // Close all other FAQs (accordion behavior) allAnswers.forEach(ans => { if (ans !== answer && ans.classList.contains('active')) { ans.classList.remove('active'); } }); allQuestions.forEach(q => { if (q !== question && q.classList.contains('active')) { q.classList.remove('active'); } }); // Toggle current FAQ const isActive = answer.classList.contains('active'); if (isActive) { answer.classList.remove('active'); question.classList.remove('active'); } else { answer.classList.add('active'); question.classList.add('active'); } // Update icon if (answer.classList.contains('active')) { icon.classList.remove('fa-chevron-down'); icon.classList.add('fa-chevron-up'); } else { icon.classList.add('fa-chevron-down'); icon.classList.remove('fa-chevron-up'); } }; });