Letting a user remove pixels from an image

Hey Bubblers,
I am trying to use the DALLE mask edit API. I want a user to be able to upload a photo, mask it, and send both to DALLE with a prompt to get the output. The problem is that there is no masking plugin in bubble that I can find. I tried using an HTML element and putting in code that allows you to draw white or black on the image, but DALLE does not recognize it. You must remove pixels from the user’s image. Can anyone help?

1 Like

ever figure this out?

No, I found a free lancer on upwork who would do it for $100 but never pulled the trigger.

I had some code that almost worked but could never quite did it in an html element:

<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DALL-E 2 Image Mask Editor</title>
<style>
#outer-canvas {
width: 45vw;
height: 45vw;
border: solid;
margin: auto;
}
</style>
</head>
<body>
<h2 style="text-align: center;">DALL-E 2 Image Mask Editor</h2>
<div>
<div id="outer-canvas"></div>
</div>
<div>
<h3 style="text-align: center;">2. Use the mouse to erase parts of the photo that should be edited by AI</h3>
</div>
<div>
<h3 style="text-align: center;">3. Download Images</h3>
<div style="text-align: center; margin: 10px;">
<button onclick="downloadOriginal()">Download Original</button>
</div>
<div style="text-align: center; margin: 10px;">
<button onclick="downloadMask()">Download Mask</button>
</div>
</div>

<script>
(function() {
let originalImageData; // Changed variable name to avoid conflicts
let queue = [];
let isDrawing = false;

// Insert the image URL dynamically
const imageUrl = "INSERT_IMAGE_URL_HERE"; // Replace with your image URL
const img = new Image();
img.crossOrigin = "Anonymous"; // Enable cross-origin resource sharing
img.src = imageUrl;

img.onload = function () {
const minVal = Math.min(img.width, img.height);
setup(img, 0, 0, minVal, minVal);
};

function setup(img, x, y, width, height) {
const outerCanvas = document.getElementById('outer-canvas');
outerCanvas.innerHTML = ''; // Clear previous canvas

const canvas = document.createElement(‘canvas’);
canvas.id = ‘PictureLayer’;
canvas.width = window.innerWidth * 0.45;
canvas.height = window.innerWidth * 0.45;
canvas.style.margin = ‘auto’;
outerCanvas.appendChild(canvas);

const ctx = canvas.getContext(‘2d’);
ctx.drawImage(img, x, y, width, height, 0, 0, canvas.width, canvas.height);
ctx.lineCap = ‘round’;
ctx.lineWidth = 25;
ctx.globalCompositeOperation = ‘destination-out’;

queue = ; // Clear previous drawing points

function startDrawing(event) {
isDrawing = true;
const pos = getPos(event);
console.log(‘start erasing’, pos);
queue = ;
newPoint(pos.x, pos.y);
}

function stopDrawing() {
console.log(‘stop erasing’);
isDrawing = false;
}

function draw(event) {
if (!isDrawing) return;
const pos = getPos(event);
newPoint(pos.x, pos.y);
drawPoints();
}

function newPoint(x, y) {
queue.push([x, y]);
}

function drawPoints() {
for (let i = 0; i < queue.length; i++) {
const point = queue[i];
ctx.beginPath();
ctx.arc(point[0], point[1], ctx.lineWidth / 2, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.closePath();
}
}

window.addEventListener(‘touchstart’, startDrawing);
window.addEventListener(‘mouseup’, stopDrawing);
canvas.addEventListener(‘touchend’, stopDrawing);
canvas.addEventListener(‘mousedown’, startDrawing);
canvas.addEventListener(‘mousemove’, draw);
canvas.addEventListener(‘touchmove’, draw);

function getPos(e) {
const rect = canvas.getBoundingClientRect();
if (e.touches) {
return { x: e.touches[0].clientX - rect.left, y: e.touches[0].clientY - rect.top };
}
return { x: e.clientX - rect.left, y: e.clientY - rect.top };
}

originalImageData = canvas.toDataURL();


}

function downloadOriginal() {
console.log('download original');
const link = document.createElement('a');
link.download = 'original.png';
link.href = originalImageData;
link.click();
}

function downloadMask() {
console.log('download mask');
const node = document.getElementById('PictureLayer');
if (!node) return;
const link = document.createElement('a');
link.download = 'mask.png';
link.href = node.toDataURL();
link.click();
}
})();
</script>
</body>
</html>

---

**Masking an image on page:**

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DALL-E 2 Image Mask Editor</title>
<style>
#outer-canvas {
width: 45vw;
height: 45vw;
border: solid;
margin: auto;
}
</style>
</head>
<body>
<h2 style="text-align: center;">DALL-E 2 Image Mask Editor</h2>
<div>
<h3 style="text-align: center;">1. <input type="file" accept="image/*" onchange="fileSelected(event)" /></h3>
<div id="outer-canvas"></div>
</div>
<div>
<h3 style="text-align: center;">2. Use the mouse to erase parts of the photo that should be edited by AI</h3>
</div>
<div>
<h3 style="text-align: center;">3. Download Images</h3>
<div style="text-align: center; margin: 10px;">
<button onclick="downloadOriginal()">Download Original</button>
</div>
<div style="text-align: center; margin: 10px;">
<button onclick="downloadMask()">Download Mask</button>
</div>
</div>

<script>
let originalImage;
let queue = [];
let isDrawing = false;

function fileSelected(event) {
const file = event.target.files[0];
const img = new Image();
img.src = URL.createObjectURL(file);

img.onload = function () {
const minVal = Math.min(img.width, img.height);
setup(img, 0, 0, minVal, minVal);
};
}

function setup(img, x, y, width, height) {
const outerCanvas = document.getElementById(‘outer-canvas’);
outerCanvas.innerHTML = ‘’; // Clear previous canvas

const canvas = document.createElement(‘canvas’);
canvas.id = ‘PictureLayer’;
canvas.width = window.innerWidth * 0.45;
canvas.height = window.innerWidth * 0.45;
canvas.style.margin = ‘auto’;
outerCanvas.appendChild(canvas);

const ctx = canvas.getContext(‘2d’);
ctx.drawImage(img, x, y, width, height, 0, 0, canvas.width, canvas.height);
ctx.lineCap = ‘round’;
ctx.lineWidth = 25;
ctx.globalCompositeOperation = ‘destination-out’;

queue = ; // Clear previous drawing points

function startDrawing(event) {
isDrawing = true;
const pos = getPos(event);
console.log(‘start erasing’, pos);
queue = ;
newPoint(pos.x, pos.y);
}

function stopDrawing() {
console.log(‘stop erasing’);
isDrawing = false;
}

function draw(event) {
if (!isDrawing) return;
const pos = getPos(event);
newPoint(pos.x, pos.y);
drawPoints();
}

function newPoint(x, y) {
queue.push([x, y]);
}

function drawPoints() {
for (let i = 0; i < queue.length; i++) {
const point = queue[i];
ctx.beginPath();
ctx.arc(point[0], point[1], ctx.lineWidth / 2, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.closePath();
}
}

window.addEventListener(‘touchstart’, startDrawing);
window.addEventListener(‘mouseup’, stopDrawing);
canvas.addEventListener(‘touchend’, stopDrawing);
canvas.addEventListener(‘mousedown’, startDrawing);
canvas.addEventListener(‘mousemove’, draw);
canvas.addEventListener(‘touchmove’, draw);

function getPos(e) {
const rect = canvas.getBoundingClientRect();
if (e.touches) {
return { x: e.touches[0].clientX - rect.left, y: e.touches[0].clientY - rect.top };
}
return { x: e.clientX - rect.left, y: e.clientY - rect.top };
}

originalImage = canvas.toDataURL();
}

function downloadOriginal() {
console.log(‘download original’);
const link = document.createElement(‘a’);
link.download = ‘original.png’;
link.href = originalImage;
link.click();
}

function downloadMask() {
console.log(‘download mask’);
const node = document.getElementById(‘PictureLayer’);
if (!node) return;
const link = document.createElement(‘a’);
link.download = ‘mask.png’;
link.href = node.toDataURL();
link.click();
}


</script>
</body>
</html>
type or paste code here