import { useState, useRef, useEffect } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Slider } from "@/components/ui/slider";
import { Download, Upload, Sparkles, Image, Contrast, Sun, Droplet, Crop, Eraser, Palette } from "lucide-react";
import { motion } from "framer-motion";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
export default function AIPhotoEditor() {
const [image, setImage] = useState(null);
const [editedImage, setEditedImage] = useState(null);
const [isProcessing, setIsProcessing] = useState(false);
const [activeTab, setActiveTab] = useState("enhance");
const canvasRef = useRef(null);
// Editing states
const [brightness, setBrightness] = useState(100);
const [contrast, setContrast] = useState(100);
const [saturation, setSaturation] = useState(100);
const [temperature, setTemperature] = useState(0);
const [removeBg, setRemoveBg] = useState(false);
const [cropMode, setCropMode] = useState(false);
const [cropCoords, setCropCoords] = useState({ x: 0, y: 0, width: 100, height: 100 });
const handleImageUpload = (e) => {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onloadend = () => {
setImage(reader.result);
setEditedImage(reader.result);
};
reader.readAsDataURL(file);
}
};
const handleEdit = () => {
setIsProcessing(true);
// Simulate AI enhancement with a delay
setTimeout(() => {
applyFilters();
setIsProcessing(false);
}, 1000);
};
const handleDownload = () => {
const link = document.createElement("a");
link.href = editedImage;
link.download = "enhanced-image.png";
link.click();
};
// Apply all current filters to the image
const applyFilters = () => {
if (!image) return;
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
const img = new Image();
img.onload = () => {
// Set canvas dimensions
canvas.width = img.width;
canvas.height = img.height;
// Apply brightness, contrast, saturation
ctx.filter = `
brightness(${brightness}%)
contrast(${contrast}%)
saturate(${saturation}%)
hue-rotate(${temperature}deg)
`;
ctx.drawImage(img, 0, 0);
// For demo purposes, we'll simulate background removal with a simple effect
if (removeBg) {
simulateBackgroundRemoval(ctx, img);
}
// Apply crop if needed
if (cropMode && (cropCoords.width < 100 || cropCoords.height < 100)) {
applyCrop();
return;
}
setEditedImage(canvas.toDataURL());
};
img.src = image;
};
// Simulate background removal (in a real app, you'd use an API)
const simulateBackgroundRemoval = (ctx, img) => {
// Create a temporary canvas for processing
const tempCanvas = document.createElement("canvas");
tempCanvas.width = img.width;
tempCanvas.height = img.height;
const tempCtx = tempCanvas.getContext("2d");
// Draw original image
tempCtx.drawImage(img, 0, 0);
// Get image data
const imageData = tempCtx.getImageData(0, 0, tempCanvas.width, tempCanvas.height);
const data = imageData.data;
// Very simple "background removal" effect for demo
// This just makes pixels with high green values transparent
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
// Simple green screen effect for demo
if (g > r * 1.2 && g > b * 1.2) {
data[i + 3] = 0; // Set alpha to 0 (transparent)
}
}
tempCtx.putImageData(imageData, 0, 0);
ctx.drawImage(tempCanvas, 0, 0);
};
const applyCrop = () => {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
const img = new Image();
img.onload = () => {
const x = (cropCoords.x / 100) * img.width;
const y = (cropCoords.y / 100) * img.height;
const width = (cropCoords.width / 100) * img.width;
const height = (cropCoords.height / 100) * img.height;
// Create a new canvas for the cropped image
const croppedCanvas = document.createElement("canvas");
croppedCanvas.width = width;
croppedCanvas.height = height;
const croppedCtx = croppedCanvas.getContext("2d");
// Draw the cropped portion
croppedCtx.drawImage(
img,
x, y, width, height,
0, 0, width, height
);
setEditedImage(croppedCanvas.toDataURL());
};
img.src = image;
};
const handleCanvasClick = (e) => {
if (!cropMode || !image) return;
const canvas = canvasRef.current;
const rect = canvas.getBoundingClientRect();
const x = ((e.clientX - rect.left) / rect.width) * 100;
const y = ((e.clientY - rect.top) / rect.height) * 100;
setCropCoords(prev => ({
...prev,
x: Math.max(0, Math.min(100 - prev.width, x)),
y: Math.max(0, Math.min(100 - prev.height, y))
}));
};
// Apply filters whenever settings change
useEffect(() => {
if (image && activeTab === "adjust") {
applyFilters();
}
}, [brightness, contrast, saturation, temperature, removeBg]);
return (
AI Photo Editor
Enhance
Adjust
Tools
{image && (
)}
{editedImage && (
)}
{image && (
Brightness: {brightness}%
setBrightness(val[0])}
/>
Contrast: {contrast}%
setContrast(val[0])}
/>
Saturation: {saturation}%
setSaturation(val[0])}
/>
Temperature: {temperature > 0 ? `+${temperature}` : temperature}°
setTemperature(val[0])}
/>
)}
{image && (
{!cropMode && (
)}
{cropMode && (
)}
{cropMode && (
<>
Crop Width: {cropCoords.width}%
setCropCoords(prev => ({
...prev,
width: val[0]
}))}
/>
Crop Height: {cropCoords.height}%
setCropCoords(prev => ({
...prev,
height: val[0]
}))}
/>
>
)}
)}
);
}
No comments:
Post a Comment