import React, { useState, useRef } from 'react'; const App = () => { const [combinedImage, setCombinedImage] = useState(null); const [loading, setLoading] = useState(false); const mainImageRef = useRef(null); const alphaImageRef = useRef(null); const canvasRef = useRef(null); const handleCombine = async () => { setLoading(true); setCombinedImage(null); const mainImageFile = mainImageRef.current.files[0]; const alphaImageFile = alphaImageRef.current.files[0]; if (!mainImageFile || !alphaImageFile) { alert("Please upload both a main image and a black and white alpha mask."); setLoading(false); return; } // Read the images as data URLs const readImage = (file) => { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (e) => resolve(e.target.result); reader.onerror = (e) => reject(e); reader.readAsDataURL(file); }); }; try { const mainImageUrl = await readImage(mainImageFile); const alphaImageUrl = await readImage(alphaImageFile); const mainImg = new Image(); mainImg.src = mainImageUrl; await new Promise(resolve => mainImg.onload = resolve); const alphaImg = new Image(); alphaImg.src = alphaImageUrl; await new Promise(resolve => alphaImg.onload = resolve); // Check if images have the same dimensions if (mainImg.width !== alphaImg.width || mainImg.height !== alphaImg.height) { alert("Image dimensions must match. Please upload images of the same size."); setLoading(false); return; } const canvas = canvasRef.current; canvas.width = mainImg.width; canvas.height = mainImg.height; const ctx = canvas.getContext('2d'); // Draw the main image ctx.drawImage(mainImg, 0, 0); const mainImageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const mainData = mainImageData.data; // Draw the alpha image ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(alphaImg, 0, 0); const alphaImageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const alphaData = alphaImageData.data; // Combine the images pixel by pixel for (let i = 0; i < mainData.length; i += 4) { // R, G, B channels from the main image const r = mainData[i]; const g = mainData[i + 1]; const b = mainData[i + 2]; // Alpha value from the alpha image (taking the red channel as a grayscale value) const a = alphaData[i + 0]; // Alpha is derived from the red channel of the grayscale image mainData[i] = r; mainData[i + 1] = g; mainData[i + 2] = b; mainData[i + 3] = a; // Set the new alpha value } // Put the modified data back on the canvas ctx.putImageData(mainImageData, 0, 0); // Get the final image as a data URL setCombinedImage(canvas.toDataURL('image/png')); setLoading(false); } catch (error) { console.error("Error combining images:", error); alert("An error occurred. Please check the console for details."); setLoading(false); } }; return (
Upload a color image and a black & white mask to create a new image with transparency. White areas on the mask are opaque, and black areas are transparent.
The image has been converted to a PNG to preserve the transparency.