Skip to content

Commit

Permalink
ImageXpert: Transform Your Images Just One Click – Effortless!
Browse files Browse the repository at this point in the history
# 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
ankit071105 authored Aug 4, 2024
1 parent 7d0a17b commit 2d6ab23
Show file tree
Hide file tree
Showing 3 changed files with 290 additions and 0 deletions.
51 changes: 51 additions & 0 deletions ImageXpert/index.html
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>&copy; 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>
197 changes: 197 additions & 0 deletions ImageXpert/script.js
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');
}
42 changes: 42 additions & 0 deletions ImageXpert/style.css
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;
}

0 comments on commit 2d6ab23

Please sign in to comment.