Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

magic wand feature #920

Open
tejas36026 opened this issue May 25, 2024 · 0 comments
Open

magic wand feature #920

tejas36026 opened this issue May 25, 2024 · 0 comments
Labels
Enhancement Enhance performance or improve usability of original features. Need Discussion Need discussion or investigation

Comments

@tejas36026
Copy link

tejas36026 commented May 25, 2024

`

<title>0. Design</title>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/magic-wand-js@1.0.0/js/magic-wand.js"></script>

<script src="https://cdn.jsdelivr.net/npm/magic-wand-js@1.0.0/js/magic-wand.js"></script>
<!-- <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script> -->
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>


<style>
  
  @import url(http://fonts.googleapis.com/css?family=Noto+Sans);
  html,
  body {
    height: 100%;
    margin: 0;
  }

.wrapper {
width: 400px !important;
height: 350px !important;
overflow: auto !important;
}
.content {
position: relative !important;
}
.canvas {
position: absolute;
}
.canvas:hover {
cursor: default;
}
.picture {
position: absolute;
}
.button {
padding: 4px;
margin: 4px;
border: 1px solid black;
float: left;
}
.button:hover {
background-color: blue;
color: white;
cursor: pointer;
}
#threshold {
width: 95px;
float: left;
}
#file-upload {
display: none;
}
.add-mode {
cursor: copy !important;
}
#imgcanvas {
position: relative;
}

#imgcanvas .wrapper {
position: absolute;
top: 121px;
left: 50%;
transform: translateX(-50%);
z-index: 9999;
/* width: 400px; /
/
height: 350px; */
overflow: auto;
}

#imgcanvas .content {
position: relative;
}

</style>
Upload image and click on it
Create polygons by current selection
Paint the selection
Merge and Download
<input id="file-upload" type="file" accept="image/*" onchange="imgChange(this)" />
Blur radius:
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.4.0/fabric.js" ></script> <script type="text/javascript" src="https://uicdn.toast.com/tui.code-snippet/v1.5.0/tui-code-snippet.min.js" ></script> <script type="text/javascript" src="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.js" ></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js" ></script> <script src="https://uicdn.toast.com/tui-image-editor/latest/tui-image-editor.js"></script> <script>
var imageEditor = new tui.ImageEditor('#tui-image-editor-container', {
  includeUI: {
    loadImage: {
        path: 'image.png',
        name: 'SampleImage',
      },
      // theme: blackTheme,
      initMenu: 'filter',
      menuBarPosition: 'bottom',
    },
    cssMaxWidth: 700,
    cssMaxHeight: 500,
    usageStatistics: false,
  });
  window.onresize = function () {
    imageEditor.ui.resizeEditor();
  };  

window.onload = function() {
colorThreshold = 15;
blurRadius = 5;
simplifyTolerant = 0;
simplifyCount = 30;
hatchLength = 4;
hatchOffset = 0;

imageInfo = null;
cacheInd = null;
mask = null;
oldMask = null;
downPoint = null;
allowDraw = false;
addMode = false;
currentThreshold = colorThreshold;

document.onkeydown = onKeyDown;
document.onkeyup = onKeyUp;

showThreshold();
document.getElementById("blurRadius").value = blurRadius;
setInterval(function () { hatchTick(); }, 300);
imgChange();

}

function uploadClick() {
document.getElementById("file-upload").click();
}

function onRadiusChange(e) {
blurRadius = e.target.value;
}

function imgChange() {
var img = document.getElementById("test-picture");
img.setAttribute('src', 'image.png');
img.onload = function() {
window.initCanvas(img);
};
}

function initCanvas(img) {
var cvs = document.getElementById("resultCanvas");
console.log(cvs);
var cvs1 = imageEditor._graphics.getCanvas();
cvs1.onmouseup = function() {
onMouseUp.apply(this, arguments);
};
cvs1.onmousedown = function() {
onMouseDown.apply(this, arguments);
};
cvs1.onmousemove = function() {
onMouseMove.apply(this, arguments);
};
console.log(cvs1);
console.log(cvs1.canvasElement);

cvs.width = img.width;
cvs.height = img.height;

imageInfo = {
    width: img.width,
    height: img.height,
    context: cvs.getContext("2d")
};
mask = null;

var tempCtx = document.createElement("canvas").getContext("2d");
tempCtx.canvas.width = imageInfo.width;
tempCtx.canvas.height = imageInfo.height;
tempCtx.drawImage(img, 0, 0);
imageInfo.data = tempCtx.getImageData(0, 0, imageInfo.width, imageInfo.height);

}
function getMousePosition(e) {
var p = $(e.target).offset(),
x = Math.round((e.clientX || e.pageX) - p.left),
y = Math.round((e.clientY || e.pageY) - p.top);
return { x: x, y: y };
}

function onMouseDown(e) {
if (e.button == 0) {
allowDraw = true;
addMode = e.ctrlKey;
downPoint = getMousePosition(e);
drawMask(downPoint.x, downPoint.y);
} else {
allowDraw = false;
addMode = false;
oldMask = null;
}
}
function onMouseMove(e) {
if (allowDraw) {
var p = getMousePosition(e);
if (p.x != downPoint.x || p.y != downPoint.y) {
var dx = p.x - downPoint.x,
dy = p.y - downPoint.y,
len = Math.sqrt(dx * dx + dy * dy),
adx = Math.abs(dx),
ady = Math.abs(dy),
sign = adx > ady ? dx / adx : dy / ady;
sign = sign < 0 ? sign / 5 : sign / 3;
var thres = Math.min(Math.max(colorThreshold + Math.floor(sign * len), 1), 255);
//var thres = Math.min(colorThreshold + Math.floor(len / 3), 255);
if (thres != currentThreshold) {
currentThreshold = thres;
drawMask(downPoint.x, downPoint.y);
}
}
}
}

function onMouseUp(e) {
allowDraw = false;
addMode = false;
oldMask = null;
currentThreshold = colorThreshold;
}
function onKeyDown(e) {
if (e.keyCode == 17) document.getElementById("resultCanvas").classList.add("add-mode");
}
function onKeyUp(e) {
if (e.keyCode == 17) document.getElementById("resultCanvas").classList.remove("add-mode");
}
function showThreshold() {
document.getElementById("threshold").innerHTML = "Threshold: " + currentThreshold;
}
function drawMask(x, y) {
if (!imageInfo) return;

showThreshold();

var image = {
    data: imageInfo.data.data,
    width: imageInfo.width,
    height: imageInfo.height,
    bytes: 4
};

if (addMode && !oldMask) {
	oldMask = mask;
}

let old = oldMask ? oldMask.data : null;

mask = MagicWand.floodFill(image, x, y, currentThreshold, old, true);
if (mask) mask = MagicWand.gaussBlurOnlyBorder(mask, blurRadius, old);

if (addMode && oldMask) {
	mask = mask ? concatMasks(mask, oldMask) : oldMask;
}

drawBorder();

}

function hatchTick() {
hatchOffset = (hatchOffset + 1) % (hatchLength * 2);
drawBorder(true);
}

function drawBorder(noBorder) {
if (!mask) return;

var x,y,i,j,k,
    w = imageInfo.width,
    h = imageInfo.height,
    ctx = imageInfo.context,
    imgData = ctx.createImageData(w, h),
    res = imgData.data;

if (!noBorder) cacheInd = MagicWand.getBorderIndices(mask);

ctx.clearRect(0, 0, w, h);

var len = cacheInd.length;
for (j = 0; j < len; j++) {
    i = cacheInd[j];
    x = i % w; // calc x by index
    y = (i - x) / w; // calc y by index
    k = (y * w + x) * 4; 
    if ((x + y + hatchOffset) % (hatchLength * 2) < hatchLength) { // detect hatch color 
        res[k + 3] = 255; // black, change only alpha
    } else {
        res[k] = 255; // white
        res[k + 1] = 255;
        res[k + 2] = 255;
        res[k + 3] = 255;
    }
}

ctx.putImageData(imgData, 0, 0);

}
function trace() {
var cs = MagicWand.traceContours(mask);
cs = MagicWand.simplifyContours(cs, simplifyTolerant, simplifyCount);

mask = null;

var ctx = imageInfo.context;
ctx.clearRect(0, 0, imageInfo.width, imageInfo.height);
ctx.beginPath();
for (var i = 0; i < cs.length; i++) {
    if (!cs[i].inner) continue;
    var ps = cs[i].points;
    ctx.moveTo(ps[0].x, ps[0].y);
    for (var j = 1; j < ps.length; j++) {
        ctx.lineTo(ps[j].x, ps[j].y);
    }
}
ctx.strokeStyle = "red";
ctx.stroke();    
//outer
ctx.beginPath();
for (var i = 0; i < cs.length; i++) {
    if (cs[i].inner) continue;
    var ps = cs[i].points;
    ctx.moveTo(ps[0].x, ps[0].y);
    for (var j = 1; j < ps.length; j++) {
        ctx.lineTo(ps[j].x, ps[j].y);
    }
}
ctx.strokeStyle = "blue";
ctx.stroke();    

}
function paint(color, alpha) {
if (!mask) return;

var rgba = hexToRgb(color, alpha);

var x,y,
		data = mask.data,
		bounds = mask.bounds,
    maskW = mask.width,
    w = imageInfo.width,
    h = imageInfo.height,
    ctx = imageInfo.context,
    imgData = ctx.createImageData(w, h),
    res = imgData.data;

for (y = bounds.minY; y <= bounds.maxY; y++) {
  for (x = bounds.minX; x <= bounds.maxX; x++) {
  		if (data[y * maskW + x] == 0) continue;
      k = (y * w + x) * 4; 
      res[k] = rgba[0];
      res[k + 1] = rgba[1];
      res[k + 2] = rgba[2];
        res[k + 3] = rgba[3];
  }
	}

mask = null;

ctx.putImageData(imgData, 0, 0);

}
function hexToRgb(hex, alpha) {
var int = parseInt(hex, 16);
var r = (int >> 16) & 255;
var g = (int >> 8) & 255;
var b = int & 255;

return [r,g,b, Math.round(alpha * 255)];
}
function concatMasks(mask, old) {
let
data1 = old.data,
data2 = mask.data,
w1 = old.width,
w2 = mask.width,
b1 = old.bounds,
b2 = mask.bounds,
b = {
minX: Math.min(b1.minX, b2.minX),
minY: Math.min(b1.minY, b2.minY),
maxX: Math.max(b1.maxX, b2.maxX),
maxY: Math.max(b1.maxY, b2.maxY)
},
w = old.width,
h = old.height,
i, j, k, k1, k2, len;

let result = new Uint8Array(w * h);

  len = b1.maxX - b1.minX + 1;
  i = b1.minY * w + b1.minX;
  k1 = b1.minY * w1 + b1.minX;
  k2 = b1.maxY * w1 + b1.minX + 1;

for (k = k1; k < k2; k += w1) {
  result.set(data1.subarray(k, k + len), i); // copy row
  i += w;
}

len = b2.maxX - b2.minX + 1;
i = b2.minY * w + b2.minX;
k1 = b2.minY * w2 + b2.minX;
k2 = b2.maxY * w2 + b2.minX + 1;

for (k = k1; k < k2; k += w2) {
for (j = 0; j < len; j++) {
if (data2[k + j] === 1) result[i + j] = 1;
}
i += w;
}

return {
	data: result,
	width: w,
	height: h,
	bounds: b
};

}
</script>

`

this is my code that work on magic wand using magic-wand.js now i need this image to be viewed in the tui image editor where i can apply other filters as well? what changes shall i incorporate ? i tried using the

var cvs = imageEditor._graphics.getCanvas()
but it failed to load and for image
var img = imageEditor.toDataURL()
but that also did not work. what should i do ?

@tejas36026 tejas36026 added Enhancement Enhance performance or improve usability of original features. Need Discussion Need discussion or investigation labels May 25, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Enhancement Enhance performance or improve usability of original features. Need Discussion Need discussion or investigation
Projects
None yet
Development

No branches or pull requests

1 participant