PIXEL Image
Thanks to Claude.ai for knocking this out. I think this might help with embroidery projects, because it is good to knock down the number of colors needed.
pixel.js
// DOM elements
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const canvasContainer = document.getElementById('canvas-container');
const pixelateSlider = document.getElementById('pixelate-slider');
const pixelateValue = document.getElementById('pixelate-value');
const defaultBtn = document.getElementById('default-btn');
const uploadBtn = document.getElementById('upload-btn');
const saveBtn = document.getElementById('save-btn');
const fileInput = document.getElementById('file-input');
// State
let originalImage = null;
let pixelSize = 1;
// Default image URL
const defaultImageUrl = "./www/p/pixel_image/test.jpg";
// Initialize
function init() {
// Load default image on start
loadImage(defaultImageUrl);
// Set up event listeners
pixelateSlider.addEventListener('input', handleSliderChange);
defaultBtn.addEventListener('click', () => loadImage(defaultImageUrl));
uploadBtn.addEventListener('click', () => fileInput.click());
fileInput.addEventListener('change', handleFileUpload);
saveBtn.addEventListener('click', saveImage);
// Drag and drop setup
canvasContainer.addEventListener('dragover', handleDragOver);
canvasContainer.addEventListener('dragleave', handleDragLeave);
canvasContainer.addEventListener('drop', handleDrop);
}
// Load and process image from URL
function loadImage(url) {
const img = new Image();
img.crossOrigin = "Anonymous"; // Enable saving from other domains
img.onload = function() {
originalImage = img;
// Set canvas dimensions to match image
const maxWidth = canvasContainer.clientWidth - 40;
const maxHeight = canvasContainer.clientHeight - 40;
// Scale to fit container while maintaining aspect ratio
let width = img.width;
let height = img.height;
if (width > maxWidth) {
const ratio = maxWidth / width;
width = maxWidth;
height = height * ratio;
}
if (height > maxHeight) {
const ratio = maxHeight / height;
height = maxHeight;
width = width * ratio;
}
canvas.width = width;
canvas.height = height;
// Draw and apply current pixelation
drawPixelatedImage();
saveBtn.disabled = false;
};
img.onerror = function() {
console.error('Error loading image');
alert('Could not load image. Please try another one.');
};
img.src = url;
}
// Draw pixelated image to canvas
function drawPixelatedImage() {
if (!originalImage) return;
const w = canvas.width;
const h = canvas.height;
// Clear canvas
ctx.clearRect(0, 0, w, h);
if (pixelSize <= 1) {
// Draw original image without pixelation
ctx.drawImage(originalImage, 0, 0, w, h);
return;
}
// Draw pixelated version
ctx.imageSmoothingEnabled = false;
// Create a temporary canvas for pixelation
const tempCanvas = document.createElement('canvas');
const tempCtx = tempCanvas.getContext('2d');
// Set temp canvas size based on pixelation level
tempCanvas.width = Math.ceil(w / pixelSize);
tempCanvas.height = Math.ceil(h / pixelSize);
// Draw small version (pixelated)
tempCtx.drawImage(originalImage, 0, 0, tempCanvas.width, tempCanvas.height);
// Draw the small version back to the main canvas scaled up
ctx.drawImage(
tempCanvas,
0, 0, tempCanvas.width, tempCanvas.height,
0, 0, w, h
);
}
// Handle slider change
function handleSliderChange() {
pixelSize = parseInt(pixelateSlider.value);
pixelateValue.textContent = pixelSize;
drawPixelatedImage();
}
// Handle file upload from input
function handleFileUpload(e) {
const file = e.target.files[0];
if (file && file.type.match('image.*')) {
const reader = new FileReader();
reader.onload = function(event) {
loadImage(event.target.result);
};
reader.readAsDataURL(file);
}
// Reset file input
fileInput.value = '';
}
// Handle drag over
function handleDragOver(e) {
e.preventDefault();
canvasContainer.classList.add('drag-over');
}
// Handle drag leave
function handleDragLeave() {
canvasContainer.classList.remove('drag-over');
}
// Handle drop
function handleDrop(e) {
e.preventDefault();
canvasContainer.classList.remove('drag-over');
const file = e.dataTransfer.files[0];
if (file && file.type.match('image.*')) {
const reader = new FileReader();
reader.onload = function(event) {
loadImage(event.target.result);
};
reader.readAsDataURL(file);
}
}
// Save the pixelated image
function saveImage() {
if (!canvas.width) return;
// Create download link
const link = document.createElement('a');
link.download = 'pixelated-image.png';
link.href = canvas.toDataURL('image/png');
link.click();
}
// Start the app
init();