Untitled
unknown
plain_text
a year ago
4.7 kB
6
Indexable
import React, { useState, useRef } from 'react';
import { AlertCircle } from 'lucide-react';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
const ImageProcessor = () => {
const [originalImage, setOriginalImage] = useState(null);
const [processedImage, setProcessedImage] = useState(null);
const [scaleFactor, setScaleFactor] = useState(0.5);
const [error, setError] = useState(null);
const canvasRef = useRef(null);
const handleImageUpload = (event) => {
const file = event.target.files[0];
const reader = new FileReader();
reader.onload = (e) => {
const img = new Image();
img.onload = () => {
setOriginalImage(img);
setProcessedImage(null);
setError(null);
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
};
const processImage = () => {
if (!originalImage) {
setError("Please upload an image first.");
return;
}
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
// Set canvas size to match original image
canvas.width = originalImage.width;
canvas.height = originalImage.height;
// Draw original image
ctx.drawImage(originalImage, 0, 0);
// Get image data
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
// Calculate dimensions for downscaled image
const pixelSize = Math.ceil(1 / scaleFactor);
const scaledWidth = Math.floor(canvas.width / pixelSize);
const scaledHeight = Math.floor(canvas.height / pixelSize);
// Create a temporary canvas for the downscaled image
const tempCanvas = document.createElement('canvas');
tempCanvas.width = scaledWidth;
tempCanvas.height = scaledHeight;
const tempCtx = tempCanvas.getContext('2d');
tempCtx.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight);
// Get the downscaled image data
const scaledImageData = tempCtx.getImageData(0, 0, scaledWidth, scaledHeight);
const scaledData = scaledImageData.data;
// Process the image with large pixel effect
for (let y = 0; y < canvas.height; y++) {
for (let x = 0; x < canvas.width; x++) {
const srcX = Math.floor(x / pixelSize);
const srcY = Math.floor(y / pixelSize);
const srcIndex = (srcY * scaledWidth + srcX) * 4;
const destIndex = (y * canvas.width + x) * 4;
data[destIndex] = scaledData[srcIndex];
data[destIndex + 1] = scaledData[srcIndex + 1];
data[destIndex + 2] = scaledData[srcIndex + 2];
data[destIndex + 3] = scaledData[srcIndex + 3];
}
}
// Put the processed image data back on the canvas
ctx.putImageData(imageData, 0, 0);
// Set processed image
setProcessedImage(canvas.toDataURL());
};
return (
<div className="max-w-2xl mx-auto p-4">
<h1 className="text-2xl font-bold mb-4">Image Processor (Large Pixel Effect)</h1>
<div className="mb-4">
<input
type="file"
accept="image/*"
onChange={handleImageUpload}
className="mb-2"
/>
<div className="flex items-center">
<label htmlFor="scaleFactor" className="mr-2">Scale Factor:</label>
<input
type="number"
id="scaleFactor"
min="0.1"
max="1"
step="0.1"
value={scaleFactor}
onChange={(e) => setScaleFactor(parseFloat(e.target.value))}
className="border rounded px-2 py-1 w-20"
/>
</div>
</div>
<button
onClick={processImage}
className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
>
Process Image
</button>
{error && (
<Alert variant="destructive" className="mt-4">
<AlertCircle className="h-4 w-4" />
<AlertTitle>Error</AlertTitle>
<AlertDescription>{error}</AlertDescription>
</Alert>
)}
<div className="mt-4 flex flex-wrap">
{originalImage && (
<div className="mr-4 mb-4">
<h2 className="text-lg font-semibold mb-2">Original Image</h2>
<img src={originalImage.src} alt="Original" className="max-w-full h-auto" />
</div>
)}
{processedImage && (
<div>
<h2 className="text-lg font-semibold mb-2">Processed Image (Large Pixel Effect)</h2>
<img src={processedImage} alt="Processed" className="max-w-full h-auto" />
</div>
)}
</div>
<canvas ref={canvasRef} style={{ display: 'none' }} />
</div>
);
};
export default ImageProcessor;Editor is loading...
Leave a Comment