我正在尝试将comicify用于一个项目。您可以转到互联网上的图片,右键单击副本,然后将其粘贴到作者创建的this demo page上,效果很好。
我不必单击粘贴图像,而是尝试单击一个按钮,从div中选择一个图像,然后将其转换。作者友好地提供了一些指导,但是当我尝试时,它会引发错误
comicify.php:30 Uncaught TypeError: t.process is not a function
at comicify (comicify.html:30)
at start (comicify.html:21)
at HTMLButtonElement.onclick (comicify.html:6)
如果这只是一个语法错误,很高兴获得一些有关如何解决它的提示。
这是我的示例代码。
function start() {
//alert("Baah");
var myImg = $("img").prop("src");
var myDistance = 50;
console.log(myImg);
var f = function(myImg) {
//do something with returned image
};
var c = comicify(myImg, myDistance, f);
};
function comicify(img, dist, outf) {
var t = this;
t.srcimg = img;
t.distance = dist;
t.outfun = outf;
t.container = $("<div>"); //$("#resultHolder");
t.process();
}
comicify.prototype = {
draw: function(container) {
var t = this;
t.container = container;
var input = $('<input>').val(t.distance).change(function() {
t.distance = this.value;
if ('' != t.srcimg[0].src) {
t.process();
}
});
container.append($('<div>').text("Directions:").append(
$('<ul>')
.append($('<li>').text("Set the distance to distance (manitude between color vecotrs) that defines a single (new) color"))
.append($('<li>').text("Paste an image to the page"))
.append($('<li>').text("Wait -- you're processing an image in Javascript..."))
));
container.append($('<div>').append($('<span>').text("Distance:").width("400px")).append(input))
t.srcimg = $('<img>');
t.srcimg.load(function() {
t.process()
});
container.on('paste', function(evt) {
return (t.handlePaste(evt));
});
},
handlePaste: function(evt) {
var t = this;
var items = evt.originalEvent.clipboardData.items,
paste;
for (var i in items) {
if ('file' == items[i].kind) {
var fr = new FileReader();
console.log("Going");
fr.onload = function(revt) {
t.srcimg[0].src = revt.target.result;
}
fr.readAsDataURL(items[i].getAsFile());
}
}
},
process: function() {
var t = this;
var canvas = $('<canvas>');
var w = canvas[0].width = t.srcimg[0].width;
var h = canvas[0].height = t.srcimg[0].height;
var prog = $('<span>').text("Processing...");
t.container.append(prog);
t.ctx = canvas[0].getContext('2d');
t.ctx.drawImage(t.srcimg[0], 0, 0);
t.image = t.ctx.getImageData(0, 0, w, h); //array [4*w*h] of colors RGBA
t.ctx.clearRect(0, 0, w, h);
t.mask = Array(w);
var zz = Array();
for (var i = 0; i < w * h; i++) {
zz[i] = i;
}
for (var i = 0; i < w; i++) {
t.mask[i] = Array(h);
for (var j = 0; j < h; j++) {
t.mask[i][j] = true;
var n = Math.floor(w * h * Math.random());
var z = zz[n];
zz[n] = zz[i * j];
zz[i * j] = z;
}
}
var n = 0;
var err = "";
var step = (w * h) / 100;
var progress = 0;
var fn = function() {
if (n < (w * h) && err == "") {
var q = Math.floor(step);
while (q > 0 && n < (w * h) && err == "") {
var x = zz[n];
var j = Math.floor(x / w);
var i = x % w;
if (t.mask[i][j]) {
var y = x * 4;
var avgct = 0;
t.avg = [t.image.data[y++], t.image.data[y++], t.image.data[y++], t.image.data[y++]];
try {
t.doPoint(i, j); // do all the points next to it too...
t.doPaint();
} catch (e) {
if (!e.message == "Maximum call stack size exceeded") {
err = e.message;
prog.text(e.message);
} else {
t.doPaint();
} // ignore call stack (we'll try
}
}
n++;
q--;
}
progress++;
if (err == "") {
prog.text("Processing " + String(progress) + "%");
window.setTimeout(fn, 0.0001);
}
} else {
if (err == "") {
prog.remove();
}
t.ctx.putImageData(t.image, 0, 0);
var outImg = $('<img>');
outImg[0].src = canvas[0].toDataURL();
t.container.append(outImg);
}
};
window.setTimeout(fn, 4);
},
doPaint: function() {
var t = this;
var w = t.srcimg[0].width;
var h = t.srcimg[0].height;
var avgct = 1;
for (var i = 0; i < w; i++) {
for (var j = 0; j < h; j++) {
var x = 4 * (i + (j * w));
if (null == t.mask[i][j]) {
for (var k = 0; k < 4; k++) {
t.avg[k] = ((t.avg[k] * avgct) + t.image.data[x + k]) / (avgct + 1);
}
avgct++;
}
}
}
for (var i = 0; i < w; i++) {
for (var j = 0; j < h; j++) {
if (null == t.mask[i][j]) {
var n = 4 * (i + (j * w));
for (var k = 0; k < 4; k++) {
t.image.data[n + k] = Math.floor(t.avg[k]);
}
t.mask[i][j] = 0;
}
}
}
},
doPoint: function(i, j) {
var t = this;
var w = t.srcimg[0].width;
var h = t.srcimg[0].height;
var x = 4 * (i + (j * w));
var p = [t.image.data[x++], t.image.data[x++], t.image.data[x++], t.image.data[x++]]
if (t.distance > distance(t.avg, p)) {
t.mask[i][j] = null;
if (i + 1 < w && t.mask[i + 1][j]) {
t.doPoint(i + 1, j)
}
if (i - 1 > 0 && t.mask[i - 1][j]) {
t.doPoint(i - 1, j)
}
if (j + 1 < h && t.mask[i][j + 1]) {
t.doPoint(i, j + 1)
}
if (j - 1 > 0 && t.mask[i][j - 1]) {
t.doPoint(i, j - 1)
}
}
return;
},
avgPt: function(i, j, ct) {
var t = this;
var w = t.srcimg[0].width;
var h = t.srcimg[0].height;
if (i > 0 && j > 0 && i < w && j < h) {
var x = 4 * (i + (j * w));
var p = [t.image.data[x++], t.image.data[x++], t.image.data[x++], t.image.data[x++]]
for (var k = 0; k < 4; k++) {
t.avg[k] = ((t.avg[k] * ct) + p[k]) / (ct + 1);
}
}
},
avgct: 0,
ctx: 0,
mask: 0,
image: 0,
avg: 0,
srcimg: 0,
cnv: 0,
distance: 35,
container: 0 // container
} // proto
function distance(a, b) {
var o = 0;
for (i = 0; i < 4; i++) {
o += (a[i] - b[i]) * (a[i] - b[i]);
}
return (Math.sqrt(o));
}
<html>
<body>
<img src="http://www.famouscastles.net/images/famouscastles/hdr-lichtenstein-castle-small.jpg" />
<div id="resultHolder"></div>
<button onclick="start()">Comicify me</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript"></script>
</body>
</html>
答案 0 :(得分:1)
这是因为您正在使用comificy.prototype
定义方法,这意味着process
是实例方法。
要解决此问题,只需输入一个new
字:var c = new comicify(myImg, myDistance, f);
请参阅: JavaScript: Class.method vs. Class.prototype.method
function start() {
//alert("Baah");
var myImg = $("img").prop("src");
var myDistance = 50;
console.log(myImg);
var f = function(myImg) {
//do something with returned image
};
var c = new comicify(myImg, myDistance, f);
};
function comicify(img, dist, outf) {
var t = this;
t.srcimg = img;
t.distance = dist;
t.outfun = outf;
t.container = $("<div>"); //$("#resultHolder");
t.process();
}
comicify.prototype = {
draw: function(container) {
var t = this;
t.container = container;
var input = $('<input>').val(t.distance).change(function() {
t.distance = this.value;
if ('' != t.srcimg[0].src) {
t.process();
}
});
container.append($('<div>').text("Directions:").append(
$('<ul>')
.append($('<li>').text("Set the distance to distance (manitude between color vecotrs) that defines a single (new) color"))
.append($('<li>').text("Paste an image to the page"))
.append($('<li>').text("Wait -- you're processing an image in Javascript..."))
));
container.append($('<div>').append($('<span>').text("Distance:").width("400px")).append(input))
t.srcimg = $('<img>');
t.srcimg.load(function() {
t.process()
});
container.on('paste', function(evt) {
return (t.handlePaste(evt));
});
},
handlePaste: function(evt) {
var t = this;
var items = evt.originalEvent.clipboardData.items,
paste;
for (var i in items) {
if ('file' == items[i].kind) {
var fr = new FileReader();
console.log("Going");
fr.onload = function(revt) {
t.srcimg[0].src = revt.target.result;
}
fr.readAsDataURL(items[i].getAsFile());
}
}
},
process: function() {
var t = this;
var canvas = $('<canvas>');
var w = canvas[0].width = t.srcimg[0].width;
var h = canvas[0].height = t.srcimg[0].height;
var prog = $('<span>').text("Processing...");
t.container.append(prog);
t.ctx = canvas[0].getContext('2d');
t.ctx.drawImage(t.srcimg[0], 0, 0);
t.image = t.ctx.getImageData(0, 0, w, h); //array [4*w*h] of colors RGBA
t.ctx.clearRect(0, 0, w, h);
t.mask = Array(w);
var zz = Array();
for (var i = 0; i < w * h; i++) {
zz[i] = i;
}
for (var i = 0; i < w; i++) {
t.mask[i] = Array(h);
for (var j = 0; j < h; j++) {
t.mask[i][j] = true;
var n = Math.floor(w * h * Math.random());
var z = zz[n];
zz[n] = zz[i * j];
zz[i * j] = z;
}
}
var n = 0;
var err = "";
var step = (w * h) / 100;
var progress = 0;
var fn = function() {
if (n < (w * h) && err == "") {
var q = Math.floor(step);
while (q > 0 && n < (w * h) && err == "") {
var x = zz[n];
var j = Math.floor(x / w);
var i = x % w;
if (t.mask[i][j]) {
var y = x * 4;
var avgct = 0;
t.avg = [t.image.data[y++], t.image.data[y++], t.image.data[y++], t.image.data[y++]];
try {
t.doPoint(i, j); // do all the points next to it too...
t.doPaint();
} catch (e) {
if (!e.message == "Maximum call stack size exceeded") {
err = e.message;
prog.text(e.message);
} else {
t.doPaint();
} // ignore call stack (we'll try
}
}
n++;
q--;
}
progress++;
if (err == "") {
prog.text("Processing " + String(progress) + "%");
window.setTimeout(fn, 0.0001);
}
} else {
if (err == "") {
prog.remove();
}
t.ctx.putImageData(t.image, 0, 0);
var outImg = $('<img>');
outImg[0].src = canvas[0].toDataURL();
t.container.append(outImg);
}
};
window.setTimeout(fn, 4);
},
doPaint: function() {
var t = this;
var w = t.srcimg[0].width;
var h = t.srcimg[0].height;
var avgct = 1;
for (var i = 0; i < w; i++) {
for (var j = 0; j < h; j++) {
var x = 4 * (i + (j * w));
if (null == t.mask[i][j]) {
for (var k = 0; k < 4; k++) {
t.avg[k] = ((t.avg[k] * avgct) + t.image.data[x + k]) / (avgct + 1);
}
avgct++;
}
}
}
for (var i = 0; i < w; i++) {
for (var j = 0; j < h; j++) {
if (null == t.mask[i][j]) {
var n = 4 * (i + (j * w));
for (var k = 0; k < 4; k++) {
t.image.data[n + k] = Math.floor(t.avg[k]);
}
t.mask[i][j] = 0;
}
}
}
},
doPoint: function(i, j) {
var t = this;
var w = t.srcimg[0].width;
var h = t.srcimg[0].height;
var x = 4 * (i + (j * w));
var p = [t.image.data[x++], t.image.data[x++], t.image.data[x++], t.image.data[x++]]
if (t.distance > distance(t.avg, p)) {
t.mask[i][j] = null;
if (i + 1 < w && t.mask[i + 1][j]) {
t.doPoint(i + 1, j)
}
if (i - 1 > 0 && t.mask[i - 1][j]) {
t.doPoint(i - 1, j)
}
if (j + 1 < h && t.mask[i][j + 1]) {
t.doPoint(i, j + 1)
}
if (j - 1 > 0 && t.mask[i][j - 1]) {
t.doPoint(i, j - 1)
}
}
return;
},
avgPt: function(i, j, ct) {
var t = this;
var w = t.srcimg[0].width;
var h = t.srcimg[0].height;
if (i > 0 && j > 0 && i < w && j < h) {
var x = 4 * (i + (j * w));
var p = [t.image.data[x++], t.image.data[x++], t.image.data[x++], t.image.data[x++]]
for (var k = 0; k < 4; k++) {
t.avg[k] = ((t.avg[k] * ct) + p[k]) / (ct + 1);
}
}
},
avgct: 0,
ctx: 0,
mask: 0,
image: 0,
avg: 0,
srcimg: 0,
cnv: 0,
distance: 35,
container: 0 // container
} // proto
function distance(a, b) {
var o = 0;
for (i = 0; i < 4; i++) {
o += (a[i] - b[i]) * (a[i] - b[i]);
}
return (Math.sqrt(o));
}
<html>
<body>
<img src="http://www.famouscastles.net/images/famouscastles/hdr-lichtenstein-castle-small.jpg" />
<div id="resultHolder"></div>
<button onclick="start()">Comicify me</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</body>
</html>