mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
168 lines
4.8 KiB
JavaScript
168 lines
4.8 KiB
JavaScript
|
(function () {
|
||
|
var ns = $.namespace('pskl.worker');
|
||
|
|
||
|
var worker = function () {
|
||
|
|
||
|
var postStep_ = function (step, total) {
|
||
|
this.postMessage({
|
||
|
type : 'STEP',
|
||
|
step : step,
|
||
|
total : total
|
||
|
});
|
||
|
};
|
||
|
|
||
|
var imageDataToGrid = function (imageData, width, height, transparent) {
|
||
|
// Draw the zoomed-up pixels to a different canvas context
|
||
|
var grid = [];
|
||
|
for (var x = 0 ; x < width ; x++){
|
||
|
grid[x] = [];
|
||
|
postStep_(x, (width-1)*2);
|
||
|
for (var y = 0 ; y < height ; y++){
|
||
|
// Find the starting index in the one-dimensional image data
|
||
|
var i = (y * width + x)*4;
|
||
|
var r = imageData[i ];
|
||
|
var g = imageData[i+1];
|
||
|
var b = imageData[i+2];
|
||
|
var a = imageData[i+3];
|
||
|
if (a < 125) {
|
||
|
grid[x][y] = transparent;
|
||
|
} else {
|
||
|
grid[x][y] = pskl.utils.FrameUtils.rgbToHex(r,g,b);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return grid;
|
||
|
};
|
||
|
|
||
|
var getColorsMapFromImageData = function (imageData, width, height) {
|
||
|
var grid = imageDataToGrid(imageData, width, height, 'transparent');
|
||
|
|
||
|
var colorsMap = {};
|
||
|
for (var i = 0 ; i < grid.length ; i++) {
|
||
|
var step = (grid.length-1) + i;
|
||
|
var total = (grid.length-1)*2;
|
||
|
postStep_(step, total);
|
||
|
for (var j = 0 ; j < grid[i].length ; j++) {
|
||
|
var color = grid[i][j];
|
||
|
if (color != 'transparent') {
|
||
|
colorsMap[color] = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return colorsMap;
|
||
|
};
|
||
|
|
||
|
this.onmessage = function(event) {
|
||
|
var data = event.data;
|
||
|
if (data.type === 'RUN_SCRIPT') {
|
||
|
this.importScripts(data.script);
|
||
|
} else {
|
||
|
try {
|
||
|
var colorsMap = getColorsMapFromImageData(data.imageData, data.width, data.height);
|
||
|
this.postMessage({
|
||
|
type : 'SUCCESS',
|
||
|
colorsMap : colorsMap
|
||
|
});
|
||
|
} catch(e) {
|
||
|
this.postMessage({
|
||
|
type : 'ERROR',
|
||
|
message : e.message
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
|
||
|
try {
|
||
|
// create worker from blob
|
||
|
var typedArray = [(worker+"").replace(/function \(\) \{/,"").replace(/\}[^}]*$/, "")];
|
||
|
var blob = new Blob(typedArray, {type: "application/javascript"}); // pass a useful mime type here
|
||
|
var blobUrl = window.URL.createObjectURL(blob);
|
||
|
} catch (e) {
|
||
|
console.error("Could not create worker", e.message);
|
||
|
}
|
||
|
|
||
|
ns.ImageProcessor = function (image, onSuccess, onStep, onError) {
|
||
|
this.image = image;
|
||
|
|
||
|
this.onStep = onStep;
|
||
|
this.onSuccess = onSuccess;
|
||
|
this.onError = onError;
|
||
|
|
||
|
this.worker = new Worker(blobUrl);
|
||
|
this.worker.onmessage = this.onWorkerMessage.bind(this);
|
||
|
};
|
||
|
|
||
|
ns.ImageProcessor.prototype.process = function () {
|
||
|
this.importAll(pskl.utils.FrameUtils, 'pskl.utils.FrameUtils');
|
||
|
this.importAll(pskl.utils.CanvasUtils, 'pskl.utils.CanvasUtils');
|
||
|
|
||
|
var imageData = pskl.utils.FrameUtils.imageToImageData(this.image);
|
||
|
this.worker.postMessage({
|
||
|
imageData : imageData,
|
||
|
width : this.image.width,
|
||
|
height : this.image.height
|
||
|
});
|
||
|
};
|
||
|
|
||
|
ns.ImageProcessor.prototype.createNamespace = function (name) {
|
||
|
var createNamespace = (function () {
|
||
|
var parts = name.split('.');
|
||
|
if (parts.length > 0) {
|
||
|
var node = this;
|
||
|
for (var i = 0 ; i < parts.length ; i++) {
|
||
|
if (!node[parts[i]]) {
|
||
|
node[parts[i]] = {};
|
||
|
}
|
||
|
node = node[parts[i]];
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
var script = createNamespace + "";
|
||
|
script = script.replace(/function \(\) \{/,"").replace(/\}[^}]*$/, "");
|
||
|
script = "var name = '" + name + "';" + script;
|
||
|
|
||
|
this.runScript(script);
|
||
|
};
|
||
|
|
||
|
ns.ImageProcessor.prototype.importAll = function (classToImport, classpath) {
|
||
|
this.createNamespace('pskl.utils.FrameUtils');
|
||
|
for (var key in classToImport) {
|
||
|
if (classToImport.hasOwnProperty(key)) {
|
||
|
this.addMethod(classToImport[key], classpath + '.' + key);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
ns.ImageProcessor.prototype.addMethod = function (method, name) {
|
||
|
this.runScript(name + "=" + method);
|
||
|
};
|
||
|
|
||
|
ns.ImageProcessor.prototype.runScript = function (script) {
|
||
|
this.worker.postMessage({
|
||
|
type : 'RUN_SCRIPT',
|
||
|
script : this.getScriptAsUrl(script)
|
||
|
});
|
||
|
};
|
||
|
|
||
|
ns.ImageProcessor.prototype.getScriptAsUrl = function (script) {
|
||
|
var blob = new Blob([script], {type: "application/javascript"}); // pass a useful mime type here
|
||
|
return window.URL.createObjectURL(blob);
|
||
|
};
|
||
|
|
||
|
ns.ImageProcessor.prototype.onWorkerMessage = function (event) {
|
||
|
if (event.data.type === 'STEP') {
|
||
|
this.onStep(event);
|
||
|
} else if (event.data.type === 'SUCCESS') {
|
||
|
this.onSuccess(event);
|
||
|
this.worker.terminate();
|
||
|
} else if (event.data.type === 'ERROR') {
|
||
|
this.onError(event);
|
||
|
this.worker.terminate();
|
||
|
}
|
||
|
};
|
||
|
})();
|
||
|
|
||
|
|
||
|
|