-
Notifications
You must be signed in to change notification settings - Fork 183
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ImageXpert: Transform Your Images Just One Click – Effortless!
# Describe the solution you'd like I’d like a feature that allows users to upload an image and convert it into multiple formats (e.g., JPEG, PNG, TIFF) and PDFs. The solution should provide a straightforward interface for users to select their desired output formats and perform the conversion with minimal steps. # Additional context The feature should support high-quality conversions and handle various image formats effectively. It should also include a preview option before finalizing the conversion to ensure accuracy. What problem is this feature trying to solve? This feature aims to simplify the process of converting images into various formats and PDFs, providing users with a versatile and efficient tool to meet their conversion needs. How do we know when the feature is complete? The feature will be considered complete when: Users can upload an image and select from a list of output formats. The conversion process is seamless and produces high-quality results. Users receive an option to preview the converted file before finalizing. The feature operates smoothly with various image formats and produces accurate PDFs. # Fix Issue :- #2593
- Loading branch information
1 parent
7d0a17b
commit 2d6ab23
Showing
3 changed files
with
290 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>ImageXpert</title> | ||
<link rel="stylesheet" href="style.css"> | ||
</head> | ||
<body> | ||
<div class="navbar"> | ||
<img src="https://ideogram.ai/assets/progressive-image/balanced/response/Rqc5OHGYRXyUGQtrdCVPRQ" alt="" style="width: 100%;" height="10%"> | ||
<br> | ||
<a href="#" onclick="changeConversion('jpegToPNG')">Universal to PNG Wizard</a> | ||
<a href="#" onclick="changeConversion('pngToJPEG')">Universal to JPEG Wizard</a> | ||
<a href="#" onclick="changeConversion('pngToAVIF')">Universal to AVIF Wizard</a> | ||
<a href="#" onclick="changeConversion('avifToPNG')">AVIF to PNG</a> | ||
<a href="#" onclick="changeConversion('pngToWebP')">Universal to WebP Hub</a> | ||
<a href="#" onclick="changeConversion('webpToPNG')">WebP to PNG</a> | ||
<a href="#" onclick="changeConversion('jpegToBMP')">Universal to BMP Wizard</a> | ||
<a href="#" onclick="changeConversion('bmpToJPEG')">BMP to JPEG</a> | ||
<a href="#" onclick="changeConversion('imageToPDF')">Image to PDF</a> | ||
|
||
</div> | ||
<br><br><br> | ||
<div class="container"> | ||
<h1>ImageXpert: Transforming Your Images, One Click at a Time.</h1> | ||
<div class="conversion-options"> | ||
<label for="conversionType">Selected Conversion:</label> | ||
<span id="selectedConversion">UNIVERSAL to PNG Wizard</span> | ||
</div> | ||
|
||
<div class="upload-area"> | ||
<input type="file" id="fileUpload" accept="image/*,.pdf"> | ||
<button onclick="convertFile()">Convert</button> | ||
</div> | ||
|
||
<div class="download-link" id="downloadLink" style="display:none;"> | ||
<a id="downloadButton" href="#" download>Download Converted File</a> | ||
</div> | ||
</div> | ||
|
||
<footer> | ||
<p>© 2024 ImageXpert. All rights reserved.</p> | ||
</footer> | ||
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf-lib/1.17.1/pdf-lib.min.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.18.0/pdf.min.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> | ||
<script src="script.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
|
||
let selectedConversion = 'jpegToPNG'; | ||
|
||
function changeConversion(conversion) { | ||
selectedConversion = conversion; | ||
document.getElementById('selectedConversion').innerText = selectedConversion.replace(/([A-Z])/g, ' $1').trim(); | ||
document.getElementById('fileUpload').value = ''; | ||
document.getElementById('downloadLink').style.display = 'none'; | ||
} | ||
|
||
async function convertFile() { | ||
const fileInput = document.getElementById('fileUpload'); | ||
const file = fileInput.files[0]; | ||
if (!file) { | ||
alert('Please upload a file first!'); | ||
return; | ||
} | ||
|
||
const fileExtension = file.name.split('.').pop().toLowerCase(); | ||
if (fileExtension === 'pdf' && !selectedConversion.startsWith('pdfTo')) { | ||
alert('You selected an image conversion. Please upload an image.'); | ||
return; | ||
} else if (fileExtension !== 'pdf' && selectedConversion.startsWith('pdfTo')) { | ||
alert('You selected a PDF conversion. Please upload a PDF.'); | ||
return; | ||
} | ||
|
||
const reader = new FileReader(); | ||
reader.onload = async function (event) { | ||
const dataUrl = event.target.result; | ||
|
||
if (fileExtension === 'pdf') { | ||
await handlePDFConversion(dataUrl); | ||
} else { | ||
const img = new Image(); | ||
img.src = dataUrl; | ||
img.onload = async function () { | ||
await handleImageConversion(img); | ||
}; | ||
} | ||
}; | ||
|
||
reader.readAsDataURL(file); | ||
} | ||
|
||
async function handleImageConversion(img) { | ||
let convertedBlob, outputFormat; | ||
|
||
switch (selectedConversion) { | ||
case 'jpegToPNG': | ||
convertedBlob = await convertToCanvasBlob(img, 'image/png'); | ||
outputFormat = 'png'; | ||
break; | ||
|
||
case 'pngToJPEG': | ||
convertedBlob = await convertToCanvasBlob(img, 'image/jpeg'); | ||
outputFormat = 'jpg'; | ||
break; | ||
|
||
case 'pngToAVIF': | ||
convertedBlob = await convertToCanvasBlob(img, 'image/avif'); | ||
outputFormat = 'avif'; | ||
break; | ||
|
||
case 'avifToPNG': | ||
convertedBlob = await convertToCanvasBlob(img, 'image/png'); | ||
outputFormat = 'png'; | ||
break; | ||
|
||
case 'pngToWebP': | ||
convertedBlob = await convertToCanvasBlob(img, 'image/webp'); | ||
outputFormat = 'webp'; | ||
break; | ||
|
||
case 'webpToPNG': | ||
convertedBlob = await convertToCanvasBlob(img, 'image/png'); | ||
outputFormat = 'png'; | ||
break; | ||
|
||
case 'jpegToBMP': | ||
convertedBlob = await convertToCanvasBlob(img, 'image/bmp'); | ||
outputFormat = 'bmp'; | ||
break; | ||
|
||
case 'bmpToJPEG': | ||
convertedBlob = await convertToCanvasBlob(img, 'image/jpeg'); | ||
outputFormat = 'jpg'; | ||
break; | ||
|
||
case 'imageToPDF': | ||
convertedBlob = await convertImageToPDF(img); | ||
outputFormat = 'pdf'; | ||
break; | ||
|
||
default: | ||
alert('Conversion type not supported!'); | ||
return; | ||
} | ||
|
||
const downloadLink = document.getElementById('downloadButton'); | ||
downloadLink.href = URL.createObjectURL(convertedBlob); | ||
downloadLink.download = `converted.${outputFormat}`; | ||
document.getElementById('downloadLink').style.display = 'block'; | ||
} | ||
|
||
async function handlePDFConversion(dataUrl) { | ||
if (selectedConversion === 'pdfToImage') { | ||
await convertPDFToImage(dataUrl); | ||
} else { | ||
const pdfjsLib = window['pdfjs-dist/build/pdf']; | ||
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.18.0/pdf.worker.min.js'; | ||
|
||
const pdf = await pdfjsLib.getDocument(dataUrl).promise; | ||
const page = await pdf.getPage(1); | ||
const viewport = page.getViewport({ scale: 2.0 }); | ||
|
||
const canvas = document.createElement('canvas'); | ||
const context = canvas.getContext('2d'); | ||
canvas.width = viewport.width; | ||
canvas.height = viewport.height; | ||
|
||
const renderContext = { | ||
canvasContext: context, | ||
viewport: viewport, | ||
}; | ||
|
||
await page.render(renderContext).promise(); | ||
|
||
let outputFormat = 'png'; | ||
|
||
if (selectedConversion === 'pdfToPNG') { | ||
canvas.toBlob(blob => { | ||
const downloadLink = document.getElementById('downloadButton'); | ||
downloadLink.href = URL.createObjectURL(blob); | ||
downloadLink.download = `converted.${outputFormat}`; | ||
document.getElementById('downloadLink').style.display = 'block'; | ||
}, 'image/png'); | ||
} else { | ||
alert('Conversion type not supported for PDF!'); | ||
} | ||
} | ||
} | ||
|
||
async function convertPDFToImage(dataUrl) { | ||
const pdfjsLib = window['pdfjs-dist/build/pdf']; | ||
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.18.0/pdf.worker.min.js'; | ||
|
||
const pdf = await pdfjsLib.getDocument(dataUrl).promise; | ||
const page = await pdf.getPage(1); | ||
const viewport = page.getViewport({ scale: 2.0 }); | ||
|
||
const canvas = document.createElement('canvas'); | ||
const context = canvas.getContext('2d'); | ||
canvas.width = viewport.width; | ||
canvas.height = viewport.height; | ||
|
||
const renderContext = { | ||
canvasContext: context, | ||
viewport: viewport, | ||
}; | ||
|
||
await page.render(renderContext).promise(); | ||
|
||
canvas.toBlob(blob => { | ||
const downloadLink = document.getElementById('downloadButton'); | ||
downloadLink.href = URL.createObjectURL(blob); | ||
downloadLink.download = 'converted.png'; | ||
document.getElementById('downloadLink').style.display = 'block'; | ||
}, 'image/png'); | ||
} | ||
|
||
function convertToCanvasBlob(img, type) { | ||
return new Promise((resolve) => { | ||
const canvas = document.createElement('canvas'); | ||
const context = canvas.getContext('2d'); | ||
canvas.width = img.width; | ||
canvas.height = img.height; | ||
context.drawImage(img, 0, 0, img.width, img.height); | ||
|
||
canvas.toBlob(blob => { | ||
resolve(blob); | ||
}, type); | ||
}); | ||
} | ||
|
||
async function convertImageToPDF(img) { | ||
const { jsPDF } = window.jspdf; | ||
|
||
const pdf = new jsPDF({ | ||
orientation: img.width > img.height ? 'l' : 'p', | ||
unit: 'px', | ||
format: [img.width, img.height] | ||
}); | ||
|
||
pdf.addImage(img.src, 'PNG', 0, 0, img.width, img.height); | ||
return pdf.output('blob'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
|
||
body { | ||
font-family: Arial, sans-serif; | ||
background-color: #d8f6f6; | ||
margin: 0; | ||
padding: 50px; | ||
} | ||
.navbar { | ||
background-color: #3d3d3d; | ||
overflow: hidden; | ||
} | ||
.navbar a { | ||
float: left; | ||
display: block; | ||
color: white; | ||
text-align: center; | ||
padding: 14px 20px; | ||
text-decoration: none; | ||
} | ||
.navbar a:hover { | ||
background-color: #ddd; | ||
color: black; | ||
} | ||
.container { | ||
max-width: 800px; | ||
margin: auto; | ||
padding: 20px; | ||
text-align: center; | ||
} | ||
.conversion-options { | ||
margin: 20px 0; | ||
} | ||
.conversion-options select, input[type="file"] { | ||
margin: 10px 0; | ||
} | ||
footer { | ||
background-color: #333; | ||
color: white; | ||
text-align: center; | ||
padding: 10px 0; | ||
margin-top: 20px; | ||
} |