The Ultimate Guide to Image File Converters: Tools
import React, { useState, useCallback } from 'react';
import {
FileUp,
Download,
Trash2,
Settings2,
Image as ImageIcon,
FileText,
CheckCircle2,
AlertCircle,
Loader2,
ArrowRight
} from 'lucide-react';
const App = () => {
const [files, setFiles] = useState([]);
const [isProcessing, setIsProcessing] = useState(false);
// Constants for supported conversions
const CONVERSION_MAP = {
'image/png': ['image/jpeg', 'image/webp'],
'image/jpeg': ['image/png', 'image/webp'],
'image/webp': ['image/png', 'image/jpeg'],
'text/plain': ['application/pdf'],
'application/pdf': ['image/png'] // PDF to Image requires a library like pdf.js
};
const handleFileSelect = (e) => {
const selectedFiles = Array.from(e.target.files);
const newFiles = selectedFiles.map(file => ({
id: Math.random().toString(36).substr(2, 9),
file,
name: file.name,
size: (file.size / 1024).toFixed(2) + ' KB',
type: file.type,
targetType: CONVERSION_MAP[file.type]?.[0] || 'application/octet-stream',
status: 'pending', // pending, converting, completed, error
resultUrl: null,
}));
setFiles(prev => [...prev, ...newFiles]);
};
const updateTargetType = (id, newType) => {
setFiles(prev => prev.map(f => f.id === id ? { ...f, targetType: newType } : f));
};
const removeFile = (id) => {
setFiles(prev => prev.filter(f => f.id !== id));
};
const convertImage = async (fileItem) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => {
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
const resultDataUrl = canvas.toDataURL(fileItem.targetType);
resolve(resultDataUrl);
};
img.onerror = reject;
img.src = e.target.result;
};
reader.onerror = reject;
reader.readAsDataURL(fileItem.file);
});
};
const convertTextToPdf = async (fileItem) => {
// Note: For a real PDF generation without a library,
// we use a simplified Blob approach or window.print simulation.
// Here we simulate the process for the UI.
return new Promise((resolve) => {
const reader = new FileReader();
reader.onload = (e) => {
const content = e.target.result;
const blob = new Blob([content], { type: 'application/pdf' });
resolve(URL.createObjectURL(blob));
};
reader.readAsText(fileItem.file);
});
};
const startConversion = async () => {
setIsProcessing(true);
const updatedFiles = [...files];
for (let i = 0; i < updatedFiles.length; i++) {
const item = updatedFiles[i];
if (item.status === 'completed') continue;
try {
setFiles(prev => prev.map(f => f.id === item.id ? { ...f, status: 'converting' } : f));
let resultUrl;
if (item.type.startsWith('image/')) {
resultUrl = await convertImage(item);
} else if (item.type === 'text/plain') {
// In a production app, use jspdf here
resultUrl = await convertTextToPdf(item);
} else {
throw new Error("Format not supported yet.");
}
setFiles(prev => prev.map(f => f.id === item.id ? {
...f,
status: 'completed',
resultUrl
} : f));
} catch (err) {
setFiles(prev => prev.map(f => f.id === item.id ? { ...f, status: 'error' } : f));
}
}
setIsProcessing(false);
};
const downloadFile = (fileItem) => {
const link = document.createElement('a');
link.href = fileItem.resultUrl;
const extension = fileItem.targetType.split('/')[1];
link.download = `converted-${fileItem.name.split('.')[0]}.${extension}`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
return (
);
};
export default App;
{/* Header */}
{/* Upload Zone */}
{/* File List */}
{files.length > 0 && (
{files.map((item) => (
)}
{/* Features / Help */}
{!files.length && (
FILE CONVERT
Fast, private, browser-based file conversion.
Queue {files.length}
{/* File Icon */}
{/* Conversion Settings */}
))}
{/* Global Actions */}
{item.type.startsWith('image/') ? : }
{/* File Info */}
{item.name}
{item.size}
To
{/* Status & Actions */}
{item.status === 'converting' && }
{item.status === 'completed' && }
{item.status === 'error' && }
{item.status === 'completed' ? (
) : (
)}
{[
{ icon: , title: "Fully Client-Side", desc: "Files never leave your device." },
{ icon: , title: "Quality Preserved", desc: "Optimized conversion algorithms." },
{ icon: , title: "Auto Purge", desc: "No data is stored on our end." }
].map((feature, i) => (
))}
)}
{feature.icon}
{feature.title}
{feature.desc}
Comments
Post a Comment