Skip to content

Commit

Permalink
Merge pull request #61 from DDMAL/revert-56-zipperjob
Browse files Browse the repository at this point in the history
Revert "🎨 Integrated the imagezipper job into pixel and tested successfully"
  • Loading branch information
sabrina0822 authored Jun 23, 2022
2 parents b29d077 + 07bf260 commit cb23188
Show file tree
Hide file tree
Showing 14 changed files with 302 additions and 306 deletions.
22 changes: 0 additions & 22 deletions LICENSE.md

This file was deleted.

3 changes: 2 additions & 1 deletion __init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import rodan
__version__ = "1.1.1"
__version__ = "1.1.0"

import logging
logger = logging.getLogger('rodan')

Expand Down
2 changes: 0 additions & 2 deletions requirements.txt

This file was deleted.

6 changes: 0 additions & 6 deletions resource_types.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
- mimetype: text/plain
description: Plain text
extension: txt
- mimetype: image/rgba+png
description: rgba png image
extension: png
- mimetype: application/zip
description: zip file
extension: zip
169 changes: 115 additions & 54 deletions source/js/plugins/pixel-wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export class PixelWrapper
// string instead of textNode so newlines can be used
tooltipText = "<p>While in the Select Region Layer, use the " +
"rectangle tool to select the regions of the page that you will classify.</p>" +
"<p>Once you select these regions, select another layer and begin classifying! " +
"<p>Once you select these regions, select another layer and begin classifying! " +
"Keep in mind that classification outside these regions will not be utilized.</p>" +
"<p>You can select the entire page by pressing <b>SHIFT + A</b>.</p>" +
"<p>You can deselect the entire page by pressing <b>ESC</b>. This will destroy all selection regions " +
Expand All @@ -84,7 +84,7 @@ export class PixelWrapper
}


createButtons ()
createButtons ()
{
let rodanExportButton = document.createElement("button"),
rodanExportText = document.createTextNode("Submit To Rodan");
Expand All @@ -95,7 +95,7 @@ export class PixelWrapper
rodanExportButton.appendChild(rodanExportText);
rodanExportButton.addEventListener("click", this.exportToRodan);

document.body.insertBefore(rodanExportButton, document.getElementById('imageLoader'));
document.body.insertBefore(rodanExportButton, document.getElementById('imageLoader'));
}

destroyButtons ()
Expand All @@ -107,23 +107,23 @@ export class PixelWrapper

/**
* Creates the number of required layers based on the number of input ports in the Rodan job.
* The variable numberInputLayers is actually defined in the outermost index.html
* The variable numberInputLayers is actually defined in the outermost index.html
*/
createLayers ()
{
// Set default tool to rectangle (for select region layer)
this.pixelInstance.tools.currentTool = "rectangle";

// Only create default layers once
if (this.layers.length !== 1)
if (this.layers.length !== 1)
return;

let numLayers = numberInputLayers;
let numLayers = numberInputLayers;

// Ask user how many layers to create if there's no input
if (numberInputLayers === 0)
if (numberInputLayers === 0)
{
while (numLayers <= 0 || numLayers > 7)
while (numLayers <= 0 || numLayers > 7)
{
numLayers = parseInt(prompt("How many layers will you classify?\n" +
"This must be two (2) less than the total number of output ports.", 3));
Expand All @@ -133,12 +133,12 @@ export class PixelWrapper
this.selectRegionLayer = new Layer(-1, new Colour(240, 232, 227, 1), "Select Region", this.pixelInstance, 0.3);
this.layers.unshift(this.selectRegionLayer);

// There is 1 active layer already created by default in PixelPlugin with layerId = 1,
// There is 1 active layer already created by default in PixelPlugin with layerId = 1,
// so start at 2, and ignore one input layer which gets assigned to layer 1. Max 7 input
for (var i = 2; i < numLayers + 1; i++)
{
for (var i = 2; i < numLayers + 1; i++)
{
let colour;
switch (i)
switch (i)
{
case 2:
colour = new Colour(255, 51, 102, 1);
Expand All @@ -165,7 +165,7 @@ export class PixelWrapper

this.pixelInstance.layerIdCounter = this.layers.length;

// Refresh UI
// Refresh UI
this.uiManager.destroyPluginElements(this.layers, this.pixelInstance.background);
this.uiManager.createPluginElements(this.layers);
}
Expand All @@ -179,56 +179,45 @@ export class PixelWrapper
let count = this.layers.length;
let urlList = [];

this.layers.forEach((layer) =>
{
this.layers.forEach((layer) =>
{
console.log(layer.layerId + " " + layer.layerName);

let dataURL = layer.getCanvas().toDataURL();
urlList.push(dataURL);
urlList.push(dataURL);
count -= 1;
if (count === 0)
{
console.log(urlList);
console.log("done");

$.ajax({
url: '',
type: 'POST',
data: JSON.stringify({'user_input': urlList}),
contentType: 'application/json',
success: () => {
setTimeout(function(){ alert("Submission successful! Click OK to exit Pixel.js."); }, 1000);
setTimeout(function(){ window.close(); }, 1200);
},
error: (jqXHR, textStatus, errorThrown) => {
console.log(jqXHR);
console.log(textStatus);
console.log(errorThrown);
alert("An error occurred: " + errorThrown);
}
});
$.ajax({url: '', type: 'POST', data: JSON.stringify({'user_input': urlList}), contentType: 'application/json'});
}
});

// Alert and close Pixel after submitting
setTimeout(function(){ alert("Submission successful! Click OK to exit Pixel.js."); }, 1000);
setTimeout(function(){ window.close(); }, 1200);
}

/**
* Generates a background layer by iterating over all the pixel data for each layer within the
* selection regions, and subtracting it from the background layer if the data is
* selection regions, and subtracting it from the background layer if the data is
* non-transparent (alpha != 0). Uses the uiManager progress bar and exports to Rodan when done
*/
createBackgroundLayer ()
createBackgroundLayer ()
{
// Don't export selectRegionLayer to Rodan
this.layers.shift();
this.layersCount = this.layers.length;

// NOTE: this backgroundLayer and the original background (image) both have layerId 0, but
// NOTE: this backgroundLayer and the original background (image) both have layerId 0, but
// this backgroundLayer is only created upon submitting (so no conflicts)
let backgroundLayer = new Layer(0, new Colour(242, 0, 242, 1), "Background Layer",
let backgroundLayer = new Layer(0, new Colour(242, 0, 242, 1), "Background Layer",
this.pixelInstance, 0.5, this.pixelInstance.actions);

// Add select regions to backgroundLayer
this.selectRegionLayer.shapes.forEach((shape) =>
this.selectRegionLayer.shapes.forEach((shape) =>
{
// Get shape dimensions
let x = shape.origin.getCoordsInPage(this.maxZoom).x,
Expand All @@ -237,7 +226,7 @@ export class PixelWrapper
rectHeight = shape.relativeRectHeight * Math.pow(2, this.maxZoom),
rect = new Rectangle(new Point(x, y, this.pageIndex), rectWidth, rectHeight, "add");

if (shape.blendMode === "subtract") {
if (shape.blendMode === "subtract") {
rect.changeBlendModeTo("subtract");
}

Expand All @@ -246,22 +235,17 @@ export class PixelWrapper
backgroundLayer.drawLayer(this.maxZoom, backgroundLayer.getCanvas());

// Alert and return if user hasn't created a selection region
if (this.selectRegionLayer.shapes.length === 0)
if (this.selectRegionLayer.shapes.length === 0)
{
alert("You haven't created any select regions!");
this.layers.unshift(this.selectRegionLayer);
return;
}

// Instantiate progress bar
// this.uiManager.createExportElements(this);
// Draw select region layer on bg layer
this.selectRegionLayer.drawLayerInPageCoords(this.maxZoom, backgroundLayer.getCanvas(), this.pageIndex);
let ctx = backgroundLayer.getCtx();
// Remove parts of user-defined layers from bg
ctx.globalCompositeOperation = "destination-out";
this.uiManager.createExportElements(this);

this.layers.forEach((layer) =>
this.layers.forEach((layer) =>
{
// Create layer canvas and draw (so pixel data can be accessed)
let layerCanvas = document.createElement('canvas');
Expand All @@ -270,18 +254,95 @@ export class PixelWrapper
layerCanvas.setAttribute("style", "position: absolute; top: 0; left: 0;");
layerCanvas.width = this.maxWidth;
layerCanvas.height = this.maxHeight;
layer.drawLayerInPageCoords(this.maxZoom, layerCanvas, this.pageIndex);
layer.drawLayerInPageCoords(this.maxZoom, layerCanvas, this.pageIndex);

if (layer.layerId !== 0) {
ctx.drawImage(layerCanvas, 0, 0);
}
this.subtractLayerFromBackground(backgroundLayer, layerCanvas, this.maxWidth, this.maxHeight);
});
this.layers.unshift(backgroundLayer);
this.exportLayersToRodan();
}

subtractLayerFromBackground (backgroundLayer, layerCanvas, width, height)
{
var chunkSize = width,
chunkNum = 0,
row = 0,
col = 0,
pixelCtx = layerCanvas.getContext('2d');

let doChunk = () =>
{
var cnt = chunkSize;
chunkNum++;
while (cnt--)
{
if (row >= height)
break;
if (col < width)
{
let data = pixelCtx.getImageData(col, row, 1, 1).data;
// data is RGBA for one pixel, data[3] is alpha
if (data[3] !== 0)
{
let currentPixel = new Rectangle(new Point(col, row, this.pageIndex), 1, 1, "subtract");
backgroundLayer.addShapeToLayer(currentPixel);
}
col++;
}
else // Reached end of row, jump to next
{
row++;
col = 0;
}
}
if (this.progress(row, chunkSize, chunkNum, height, backgroundLayer).needsRecall) // recall function
{
setTimeout(doChunk, 1);
}
};
doChunk();
}

progress (row, chunkSize, chunkNum, height, backgroundLayer)
{
if (row === height || this.exportInterrupted)
{
this.layersCount -= 1;
}
if (row < height && !this.exportInterrupted)
{
let percentage = (chunkNum * chunkSize) * 100 / (height * chunkSize),
roundedPercentage = (percentage > 100) ? 100 : Math.round(percentage * 10) / 10;
this.pixelInstance.uiManager.updateProgress(roundedPercentage);
return {
needsRecall: true
};
}
else
{
if (this.exportInterrupted && (this.layersCount === 0))
{
this.exportInterrupted = false;
this.uiManager.destroyExportElements();
this.layers.unshift(this.selectRegionLayer);
}
else if (this.exportInterrupted)
{
// Do nothing and wait until last layer has finished processing to cancel
}
else if (this.layersCount === 0)
{ // Done generating background layer
backgroundLayer.drawLayer(0, backgroundLayer.getCanvas());
this.layers.unshift(backgroundLayer);
this.uiManager.destroyExportElements();
this.exportLayersToRodan();
}
}
return {
needsRecall: false
};
}

/**
* Handles the Rodan input layers and draws them on each layer in Pixel
* Handles the Rodan input layers and draws them on each layer in Pixel
*/
rodanImagesToCanvas ()
{
Expand Down Expand Up @@ -314,4 +375,4 @@ export class PixelWrapper
}
});
}
}
}
6 changes: 3 additions & 3 deletions source/js/plugins/pixel-wrapper.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ describe('Checking Functionality', () => {
expect(await alert.getText()).toBe("You haven't created any select regions!");
await alert.accept();
});
test.skip('drawing select region then submit to rodan creates progress bar', async () => {
test('drawing select region then submit to rodan creates progress bar', async () => {
let canvas = await browser.findElement(By.id('layer--1-canvas'));
const actions = browser.actions();
// select rectangle tool and draw one
Expand All @@ -141,7 +141,7 @@ describe('Checking Functionality', () => {
let progressBar = await browser.findElement(By.id('pbar-inner-div'));
expect(await progressBar.isDisplayed()).toBeTruthy();
});
test.skip('cancel progress bar button removes the progress div', async () => {
test('cancel progress bar button removes the progress div', async () => {
let cancelButton = await browser.findElement(By.id('cancel-export-div'));
const actions = browser.actions();
await actions.click(cancelButton).perform();
Expand All @@ -159,4 +159,4 @@ describe('Checking Functionality', () => {

expect(await layer1Toggle.getAttribute('class')).toBe('layer-deactivated');
});
});
});
2 changes: 1 addition & 1 deletion source/js/plugins/pixel.js
Submodule pixel.js updated 1 files
+17 −17 source/tutorial.js
Loading

0 comments on commit cb23188

Please sign in to comment.