<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image to PDF Converter</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #1a2a6c, #2b5876, #4e4376);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
color: #fff;
}
.container {
width: 100%;
max-width: 900px;
background: rgba(255, 255, 255, 0.08);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 30px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.5);
border: 1px solid rgba(255, 255, 255, 0.1);
overflow: hidden;
position: relative;
}
.container::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%);
transform: rotate(0deg);
z-index: -1;
}
h1 {
text-align: center;
margin-bottom: 30px;
font-weight: 600;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
color: #ffffff;
position: relative;
}
h1::after {
content: '';
display: block;
width: 100px;
height: 4px;
background: linear-gradient(90deg, #4facfe, #00f2fe);
margin: 10px auto;
border-radius: 2px;
}
.upload-area {
border: 3px dashed rgba(255, 255, 255, 0.3);
border-radius: 15px;
padding: 40px 20px;
text-align: center;
margin-bottom: 30px;
transition: all 0.3s ease;
cursor: pointer;
position: relative;
overflow: hidden;
}
.upload-area:hover {
border-color: rgba(79, 172, 254, 0.6);
box-shadow: 0 0 15px rgba(79, 172, 254, 0.4);
}
.upload-area.active {
border-color: #4facfe;
background-color: rgba(79, 172, 254, 0.1);
box-shadow: 0 0 20px rgba(79, 172, 254, 0.6);
}
.upload-icon {
font-size: 60px;
margin-bottom: 15px;
color: #4facfe;
text-shadow: 0 0 10px rgba(79, 172, 254, 0.6);
}
.upload-text {
margin-bottom: 20px;
}
.upload-text h3 {
font-size: 24px;
margin-bottom: 10px;
}
.upload-text p {
color: rgba(255, 255, 255, 0.7);
}
.browse-btn {
display: inline-block;
padding: 12px 30px;
background: linear-gradient(90deg, #4facfe, #00f2fe);
color: white;
border-radius: 50px;
cursor: pointer;
font-weight: 600;
transition: all 0.3s ease;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
.browse-btn:hover {
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
}
#file-input {
display: none;
}
.preview-area {
display: none;
margin-bottom: 30px;
}
.preview-title {
text-align: center;
margin-bottom: 20px;
font-size: 22px;
color: #4facfe;
text-shadow: 0 0 5px rgba(79, 172, 254, 0.6);
}
.image-previews {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 15px;
margin-bottom: 20px;
}
.image-preview {
position: relative;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
transition: all 0.3s ease;
}
.image-preview:hover {
transform: translateY(-5px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3), 0 0 15px rgba(79, 172, 254, 0.6);
}
.image-preview img {
width: 100%;
height: 150px;
object-fit: cover;
display: block;
}
.remove-btn {
position: absolute;
top: 5px;
right: 5px;
background: rgba(255, 0, 0, 0.7);
color: white;
width: 25px;
height: 25px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 14px;
transition: all 0.3s ease;
}
.remove-btn:hover {
background: rgba(255, 0, 0, 1);
transform: scale(1.1);
}
.action-buttons {
display: flex;
justify-content: center;
gap: 15px;
flex-wrap: wrap;
}
.action-btn {
padding: 12px 25px;
border: none;
border-radius: 50px;
background: linear-gradient(90deg, #4facfe, #00f2fe);
color: white;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 8px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
.action-btn:hover {
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3), 0 0 15px rgba(79, 172, 254, 0.6);
}
.action-btn:active {
transform: translateY(0);
}
.download-btn {
background: linear-gradient(90deg, #00c6ff, #0072ff);
}
.download-btn:hover {
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3), 0 0 15px rgba(0, 114, 255, 0.6);
}
.clear-btn {
background: linear-gradient(90deg, #ff758c, #ff7eb3);
}
.clear-btn:hover {
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3), 0 0 15px rgba(255, 126, 179, 0.6);
}
.footer {
text-align: center;
margin-top: 30px;
color: rgba(255, 255, 255, 0.6);
font-size: 14px;
}
.quality-options {
display: flex;
justify-content: center;
gap: 15px;
margin-bottom: 20px;
}
.quality-btn {
padding: 8px 20px;
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 20px;
color: rgba(255, 255, 255, 0.8);
cursor: pointer;
transition: all 0.3s ease;
}
.quality-btn.active {
background: linear-gradient(90deg, #4facfe, #00f2fe);
color: white;
box-shadow: 0 0 10px rgba(79, 172, 254, 0.6);
}
@media (max-width: 600px) {
.action-buttons {
flex-direction: column;
}
.action-btn {
width: 100%;
justify-content: center;
}
.image-previews {
grid-template-columns: repeat(2, 1fr);
}
}
</style>
</head>
<body>
<div class="container">
<h1><i class="fas fa-file-pdf"></i> Image to PDF Converter</h1>
<div class="upload-area" id="upload-area">
<div class="upload-icon">
<i class="fas fa-cloud-upload-alt"></i>
</div>
<div class="upload-text">
<h3>Drag & Drop</h3>
<p>Upload your images here or click to browse</p>
</div>
<div class="browse-btn">Browse Files</div>
<input type="file" id="file-input" accept="image/*" multiple>
</div>
<div class="preview-area" id="preview-area">
<h2 class="preview-title">Image Previews</h2>
<div class="quality-options">
<div class="quality-btn active" data-quality="high">High Quality</div>
<div class="quality-btn" data-quality="medium">Medium Quality</div>
<div class="quality-btn" data-quality="low">Low Quality</div>
</div>
<div class="image-previews" id="image-previews"></div>
<div class="action-buttons">
<button class="action-btn download-btn" id="download-btn">
<i class="fas fa-download"></i> Download PDF
</button>
<button class="action-btn clear-btn" id="clear-btn">
<i class="fas fa-trash"></i> Clear All
</button>
</div>
</div>
<div class="footer">
<p>Made with <i class="fas fa-heart" style="color: #ff758c;"></i> - Image to PDF Converter</p>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const uploadArea = document.getElementById('upload-area');
const fileInput = document.getElementById('file-input');
const previewArea = document.getElementById('preview-area');
const imagePreviews = document.getElementById('image-previews');
const downloadBtn = document.getElementById('download-btn');
const clearBtn = document.getElementById('clear-btn');
const qualityButtons = document.querySelectorAll('.quality-btn');
let uploadedImages = [];
let currentQuality = 'high';
// Setup quality buttons
qualityButtons.forEach(btn => {
btn.addEventListener('click', function() {
qualityButtons.forEach(b => b.classList.remove('active'));
this.classList.add('active');
currentQuality = this.getAttribute('data-quality');
});
});
// Upload area functionality
uploadArea.addEventListener('click', () => {
fileInput.click();
});
uploadArea.addEventListener('dragover', (e) => {
e.preventDefault();
uploadArea.classList.add('active');
});
uploadArea.addEventListener('dragleave', () => {
uploadArea.classList.remove('active');
});
uploadArea.addEventListener('drop', (e) => {
e.preventDefault();
uploadArea.classList.remove('active');
if (e.dataTransfer.files.length > 0) {
handleFiles(e.dataTransfer.files);
}
});
fileInput.addEventListener('change', () => {
if (fileInput.files.length > 0) {
handleFiles(fileInput.files);
}
});
// Clear button functionality
clearBtn.addEventListener('click', () => {
uploadedImages = [];
imagePreviews.innerHTML = '';
previewArea.style.display = 'none';
fileInput.value = '';
});
// Download button functionality
downloadBtn.addEventListener('click', generatePDF);
// Handle uploaded files
function handleFiles(files) {
for (let i = 0; i < files.length; i++) {
const file = files[i];
if (!file.type.match('image.*')) {
continue;
}
const reader = new FileReader();
reader.onload = function(e) {
const image = {
name: file.name,
src: e.target.result
};
uploadedImages.push(image);
addImagePreview(image, uploadedImages.length - 1);
};
reader.readAsDataURL(file);
}
if (uploadedImages.length > 0) {
previewArea.style.display = 'block';
}
}
// Add image preview
function addImagePreview(image, index) {
const preview = document.createElement('div');
preview.className = 'image-preview';
preview.innerHTML = `
<img src="${image.src}" alt="${image.name}">
<div class="remove-btn" data-index="${index}">×</div>
`;
imagePreviews.appendChild(preview);
// Add remove functionality
const removeBtn = preview.querySelector('.remove-btn');
removeBtn.addEventListener('click', function(e) {
e.stopPropagation();
const index = parseInt(this.getAttribute('data-index'));
uploadedImages.splice(index, 1);
updatePreviews();
});
}
// Update all previews after removal
function updatePreviews() {
imagePreviews.innerHTML = '';
uploadedImages.forEach((image, index) => {
addImagePreview(image, index);
});
if (uploadedImages.length === 0) {
previewArea.style.display = 'none';
}
}
// Generate and download PDF
function generatePDF() {
if (uploadedImages.length === 0) {
alert('Please upload at least one image!');
return;
}
// Using jsPDF library
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
// Set quality based on selection
let quality;
switch(currentQuality) {
case 'high':
quality = 1.0;
break;
case 'medium':
quality = 0.75;
break;
case 'low':
quality = 0.5;
break;
default:
quality = 1.0;
}
// Add each image to PDF
let promiseChain = Promise.resolve();
uploadedImages.forEach((image, index) => {
promiseChain = promiseChain.then(() => {
return new Promise((resolve) => {
const img = new Image();
img.src = image.src;
img.onload = function() {
const width = img.width;
const height = img.height;
const pdfWidth = doc.internal.pageSize.getWidth();
const pdfHeight = (height * pdfWidth) / width;
if (index > 0) {
doc.addPage();
}
doc.addImage(img, 'JPEG', 0, 0, pdfWidth, pdfHeight, undefined, 'FAST');
resolve();
};
});
});
});
// Download the PDF when all images are added
promiseChain.then(() => {
doc.save('converted-images.pdf');
// Show success effect on download button
downloadBtn.innerHTML = '<i class="fas fa-check"></i> Downloaded!';
downloadBtn.style.background = 'linear-gradient(90deg, #00b09b, #96c93d)';
setTimeout(() => {
downloadBtn.innerHTML = '<i class="fas fa-download"></i> Download PDF';
downloadBtn.style.background = 'linear-gradient(90deg, #00c6ff, #0072ff)';
}, 2000);
});
}
});
</script>
<!-- Font Awesome for icons -->
<script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script>
</body>
</html>
0 टिप्पणियाँ