DL-Hobbyist's picture
Upload 21 files
635195b verified
Raw
History Blame Contribute Delete
5.6 kB
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
// Original image storage
let originalCtxOriginal = document.createElement('canvas').getContext('2d');
let maskCtxOriginal = document.createElement('canvas').getContext('2d');
let isDrawing = false;
let brushSize = 5;
let eraserMode = false;
// Setup event listeners
document.getElementById('imageUpload').addEventListener('change', handleImageUpload);
document.getElementById('brushSize').addEventListener('change', (e) => brushSize = parseInt(e.target.value));
document.getElementById('eraserMode').addEventListener('change', (e) => eraserMode = e.target.checked);
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);
function handleImageUpload(e) {
let file = e.target.files[0];
let reader = new FileReader();
reader.onload = function(event) {
let img = new Image();
img.onload = function() {
// Store original image at full resolution
originalCtxOriginal.canvas.width = img.width;
originalCtxOriginal.canvas.height = img.height;
originalCtxOriginal.drawImage(img, 0, 0);
// Setup mask at original resolution
maskCtxOriginal.canvas.width = img.width;
maskCtxOriginal.canvas.height = img.height;
// Calculate display dimensions
const container = document.getElementById('canvasContainer');
const maxWidth = container.clientWidth;
const maxHeight = container.clientHeight;
let ratio = Math.min(maxWidth / img.width, maxHeight / img.height);
ratio = Math.min(ratio, 1); // Prevent upscaling
const scaledWidth = img.width * ratio;
const scaledHeight = img.height * ratio;
const offsetX = (maxWidth - scaledWidth) / 2;
const offsetY = (maxHeight - scaledHeight) / 2;
// Set display canvas dimensions
canvas.width = maxWidth;
canvas.height = maxHeight;
// Draw initial scaled image
ctx.drawImage(img, offsetX, offsetY, scaledWidth, scaledHeight);
// Store scaling parameters
window.scaleRatio = ratio;
window.offsetX = offsetX;
window.offsetY = offsetY;
};
img.src = event.target.result;
};
reader.readAsDataURL(file);
}
function startDrawing(e) {
isDrawing = true;
draw(e);
}
function stopDrawing() {
isDrawing = false;
ctx.beginPath();
}
function draw(e) {
if (!isDrawing || !window.scaleRatio) return;
const rect = canvas.getBoundingClientRect();
const mouseX = e.clientX - rect.left;
const mouseY = e.clientY - rect.top;
// Convert to original coordinates
const originalX = (mouseX - window.offsetX) / window.scaleRatio;
const originalY = (mouseY - window.offsetY) / window.scaleRatio;
const brushRadius = brushSize / window.scaleRatio;
if (eraserMode) {
// Erase from mask
maskCtxOriginal.clearRect(
originalX - brushRadius,
originalY - brushRadius,
brushRadius * 2,
brushRadius * 2
);
} else {
// Draw on mask
maskCtxOriginal.fillStyle = '#FFFFFF';
maskCtxOriginal.beginPath();
maskCtxOriginal.arc(
originalX,
originalY,
brushRadius,
0,
Math.PI * 2
);
maskCtxOriginal.fill();
}
// Redraw display canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(originalCtxOriginal.canvas,
0, 0, originalCtxOriginal.canvas.width, originalCtxOriginal.canvas.height,
window.offsetX, window.offsetY,
originalCtxOriginal.canvas.width * window.scaleRatio,
originalCtxOriginal.canvas.height * window.scaleRatio
);
// Overlay mask
ctx.globalAlpha = 0.5; // For visual feedback
ctx.drawImage(maskCtxOriginal.canvas,
0, 0, maskCtxOriginal.canvas.width, maskCtxOriginal.canvas.height,
window.offsetX, window.offsetY,
maskCtxOriginal.canvas.width * window.scaleRatio,
maskCtxOriginal.canvas.height * window.scaleRatio
);
ctx.globalAlpha = 1;
}
// Download button
document.getElementById('downloadBtn').addEventListener('click', () => {
const binaryCanvas = document.createElement('canvas');
binaryCanvas.width = originalCtxOriginal.canvas.width;
binaryCanvas.height = originalCtxOriginal.canvas.height;
const binaryCtx = binaryCanvas.getContext('2d');
// Create white background
binaryCtx.fillStyle = 'white';
binaryCtx.fillRect(0, 0, binaryCanvas.width, binaryCanvas.height);
// Get mask data
const maskData = maskCtxOriginal.getImageData(0, 0,
binaryCanvas.width, binaryCanvas.height);
// Draw black where mask exists
for (let i = 0; i < maskData.data.length; i += 4) {
if (maskData.data[i + 3] > 0) { // Check alpha channel
const x = (i / 4) % binaryCanvas.width;
const y = Math.floor((i / 4) / binaryCanvas.width);
binaryCtx.fillStyle = 'black';
binaryCtx.fillRect(x, y, 1, 1);
}
}
document.getElementById('downloadBtn').href = binaryCanvas.toDataURL('image/png');
});