Skip to content
This repository was archived by the owner on Apr 18, 2024. It is now read-only.

Commit 4a5f8d9

Browse files
Gondragosmakseqhlomzik
authored
DEV-1367: Image size problems (#411)
## changes - fix the calculation of the stage size on the window resizing at a given image width - add frame to crop the image to the stage size - add height and maxheight params - set max width as 100% by default ## commits * Add shapes ignoring when dragging an image * Add max-height attr * Add test for canvas resize problem on setting custom image width * [fix] Canvas resizing while custom image width is set * Fix tests * Fix tests * Ignore not meaningful error * Make changes accourding to comments - set heuristic maxHeight default value - add comment - remove unused volatile - remove duplicate functionality * test: Fix config according to appearence of maxHeight * test: Fix tests according to changing of default maxWidth value * fix:Add removing default tool on all tools removing * test: Allow to run tests over local start Solved by preventing preserving selected tool * fix: DEV-1367: Fix zooming in while space is available Co-authored-by: Max Tkachenko <[email protected]> Co-authored-by: hlomzik <[email protected]>
1 parent b92d270 commit 4a5f8d9

File tree

12 files changed

+311
-209
lines changed

12 files changed

+311
-209
lines changed

e2e/tests/empty-labels.test.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ examples.forEach(example => {
4545
if (regionsCount) {
4646
const restored = await LabelStudio.serialize();
4747

48-
Asserts.notDeepEqualWithTolerance(result, restored);
49-
for (let i = result.length; i--; ) {
50-
Asserts.deepEqualWithTolerance(Helpers.omitBy(result[i], isLabels), restored[i]);
48+
Asserts.notDeepEqualWithTolerance(result, restored, 1);
49+
for (let i = result.length; i--;) {
50+
Asserts.deepEqualWithTolerance(Helpers.omitBy(result[i], isLabels), restored[i], 1);
5151
}
5252
}
5353
});
@@ -81,11 +81,12 @@ examples.forEach(example => {
8181
if (regionsCount) {
8282
const restored = await LabelStudio.serialize();
8383

84-
Asserts.notDeepEqualWithTolerance(result, restored);
85-
for (let i = result.length; i--; ) {
84+
Asserts.notDeepEqualWithTolerance(result, restored, 1);
85+
for (let i = result.length; i--;) {
8686
Asserts.deepEqualWithTolerance(
8787
Helpers.omitBy(result[i], (val, key) => key === "from_name" || isLabels(val, key)),
8888
Helpers.omitBy(restored[i], (val, key) => key === "from_name" || isLabels(val, key)),
89+
1,
8990
);
9091
}
9192
}
@@ -163,8 +164,8 @@ const MULTIPLE_TYPE = "multiple";
163164

164165
const restored = await LabelStudio.serialize();
165166

166-
Asserts.notDeepEqualWithTolerance(result[0], restored[0]);
167-
Asserts.deepEqualWithTolerance(Helpers.omitBy(result[0], isLabels), Helpers.omitBy(restored[0], isLabels));
167+
Asserts.notDeepEqualWithTolerance(result[0], restored[0], 1);
168+
Asserts.deepEqualWithTolerance(Helpers.omitBy(result[0], isLabels), Helpers.omitBy(restored[0], isLabels), 1);
168169
assert.strictEqual(restored[0].value.labels.length, 0);
169170
await clickLabelWithLengthExpection(2, 1, 1);
170171
switch (type) {
@@ -227,5 +228,6 @@ Scenario(`Consistency of empty labels`, async ({ I, LabelStudio, AtSidebar, AtIm
227228
Asserts.deepEqualWithTolerance(
228229
restored[0].value,
229230
convertToImageSize({ x: 200, y: 200, width: 100, height: 100, rotation: 0, rectanglelabels: [] }),
231+
1,
230232
);
231233
});

e2e/tests/helpers.js

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@
99
* @param {object[]} params.predictions
1010
* @param {function} done
1111
*/
12-
const initLabelStudio = async ({ config, data, annotations = [{ result: [] }], predictions = [] }, done) => {
12+
const initLabelStudio = async ({
13+
config,
14+
data,
15+
annotations = [{ result: [] }],
16+
predictions = [],
17+
settings = {},
18+
}, done) => {
1319
if (window.Konva && window.Konva.stages.length) window.Konva.stages.forEach(stage => stage.destroy());
1420

1521
const interfaces = [
@@ -32,7 +38,7 @@ const initLabelStudio = async ({ config, data, annotations = [{ result: [] }], p
3238
const task = { data, annotations, predictions };
3339

3440
window.LabelStudio.destroyAll();
35-
new window.LabelStudio("label-studio", { interfaces, config, task });
41+
new window.LabelStudio("label-studio", { interfaces, config, task, settings });
3642
done();
3743
};
3844

@@ -54,7 +60,10 @@ const waitForImage = async done => {
5460
const img = document.querySelector("[alt=LS]");
5561

5662
if (!img || img.complete) return done();
57-
img.onload = done;
63+
// this should be rewritten to isReady when it is ready
64+
img.onload = ()=>{
65+
setTimeout(done, 100);
66+
};
5867
};
5968

6069
/**
@@ -82,20 +91,20 @@ const waitForAudio = async done => {
8291
* to same structures but with rounded numbers (int for ints, fixed(2) for floats)
8392
* @param {*} data
8493
*/
85-
const convertToFixed = data => {
94+
const convertToFixed = (data, fractionDigits = 2) => {
8695
if (["string", "number"].includes(typeof data)) {
8796
const n = Number(data);
8897

89-
return Number.isNaN(n) ? data : Number.isInteger(n) ? n : +Number(n).toFixed(2);
98+
return Number.isNaN(n) ? data : Number.isInteger(n) ? n : +Number(n).toFixed(fractionDigits);
9099
}
91100
if (Array.isArray(data)) {
92-
return data.map(n => convertToFixed(n));
101+
return data.map(n => convertToFixed(n, fractionDigits));
93102
}
94103
if (typeof data === "object") {
95104
const result = {};
96105

97106
for (const key in data) {
98-
result[key] = convertToFixed(data[key]);
107+
result[key] = convertToFixed(data[key], fractionDigits);
99108
}
100109
return result;
101110
}

e2e/tests/image.zoom-rotate.test.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,16 +276,40 @@ Data(layoutVariations).Scenario("Rotation in the two columns template", async fu
276276
const params = {
277277
config: resultConfig,
278278
data: { image: IMAGE },
279+
annotations: [{
280+
id: "rotations",
281+
result: [
282+
// The region just for canvas size visually indication
283+
{
284+
from_name: "label",
285+
id: "EUsEHxTyrv",
286+
image_rotation: 0,
287+
origin: "manual",
288+
original_height: 2802,
289+
original_width: 2242,
290+
to_name: "image",
291+
type: "rectanglelabels",
292+
value: {
293+
height: 100,
294+
labels: ["Label 2"],
295+
rotation: 0,
296+
width: 100,
297+
x: 0,
298+
y: 0,
299+
},
300+
},
301+
],
302+
}],
279303
};
280304

281305
I.say(`Two columns [config: ${twoColumnsConfigs.indexOf(config)}] [${direction}]`);
282306

283307
LabelStudio.init(params);
284308
AtImageView.waitForImage();
285-
AtSidebar.seeRegions(0);
309+
AtSidebar.seeRegions(1);
286310

287311
I.click(locate(`[aria-label='rotate-right']`));
288-
I.wait(0.5);
312+
AtSidebar.seeRegions(1);
289313

290314
await compareSize(I, AtImageView, "Dimensions must be equal in landscape", "landscape, rotated");
291315

@@ -297,11 +321,11 @@ Data(layoutVariations).Scenario("Rotation in the two columns template", async fu
297321
});
298322
AtSettings.close();
299323

300-
I.wait(0.5);
324+
AtSidebar.seeRegions(1);
301325
await compareSize(I, AtImageView, "Dimensions must be equal in portrait", "portrait");
302326

303327
I.click(locate(`[aria-label='rotate-right']`));
304328

305-
I.wait(0.5);
329+
AtSidebar.seeRegions(1);
306330
await compareSize(I, AtImageView, "Dimensions must be equal after rotation in portrain", "portrait, rotated");
307331
});

e2e/tests/ocr.test.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,14 @@ const H3_POINTS = [[1.25, 50.887573964497044], [21.875, 50.69033530571992], [22.
2727

2828
Scenario("Basic scenario", async ({ I, LabelStudio, AtImageView, AtSettings, AtLabels, AtSidebar }) => {
2929
I.amOnPage("/");
30-
LabelStudio.init({ config: createConfig({ shapes: ["Polygon"] }), data });
30+
31+
LabelStudio.init({
32+
config: createConfig({ shapes: ["Polygon"] }),
33+
data,
34+
settings: {
35+
preserveSelectedTool: false,
36+
},
37+
});
3138
AtImageView.waitForImage();
3239
AtSettings.open();
3340
AtSettings.setGeneralSettings({

e2e/tests/regression-tests/image-ctrl-drawing.test.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const BLUEVIOLET = {
1414
};
1515
const getConfigWithShapes = (shapes, props = "") => `
1616
<View>
17-
<Image name="img" value="$image" zoom="true" zoomBy="1.5" zoomControl="true" rotateControl="true"></Image>
17+
<Image name="img" value="$image" zoom="true" zoomBy="1.5" zoomControl="true" rotateControl="true" maxWidth="750px" maxHeight="auto"/>
1818
${shapes
1919
.map(
2020
shape => `
@@ -172,6 +172,9 @@ Scenario("How it works without ctrl", async function({ I, LabelStudio, AtSidebar
172172
const params = {
173173
config: getConfigWithShapes(Object.keys(createShape)),
174174
data: { image: IMAGE },
175+
settings: {
176+
preserveSelectedTool: false,
177+
},
175178
};
176179

177180
I.amOnPage("/");
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/* global Feature, Scenario */
2+
const assert = require("assert");
3+
4+
Feature("Image width parameter").tag("@regress");
5+
6+
const IMAGE = "https://user.fm/files/v2-901310d5cb3fa90e0616ca10590bacb3/spacexmoon-800x501.jpg";
7+
8+
const config = `
9+
<View>
10+
<Image name="img" value="$image" width="50%"/>
11+
<Rectangle name="rect" toName="img"/>
12+
</View>`;
13+
14+
Scenario("Setting width 50% shouldn't break canvas size on resize of working area", async ({ I, LabelStudio, AtImageView, AtSidebar }) => {
15+
const params = {
16+
config,
17+
data: { image: IMAGE },
18+
};
19+
20+
I.amOnPage("/");
21+
LabelStudio.init(params);
22+
AtImageView.waitForImage();
23+
AtSidebar.seeRegions(0);
24+
await AtImageView.lookForStage();
25+
let canvasSize = await AtImageView.getCanvasSize();
26+
let imageSize = await AtImageView.getImageSize();
27+
28+
// The sizes of the canvas and image element should be equal (or almost equal)
29+
assert.strictEqual(Math.ceil(imageSize.width), Math.ceil(canvasSize.width));
30+
assert.strictEqual(Math.ceil(imageSize.height), Math.ceil(canvasSize.height));
31+
32+
// Create full-size region
33+
// This step is just for visual identification of the bug
34+
AtImageView.drawByDrag(5, 5, canvasSize.width - 10, canvasSize.height - 10);
35+
36+
I.resizeWindow(800, 900);
37+
I.resizeWindow(1200, 900);
38+
39+
canvasSize = await AtImageView.getCanvasSize();
40+
imageSize = await AtImageView.getImageSize();
41+
42+
// The sizes should still be equal (or almost equal)
43+
assert.strictEqual(Math.ceil(imageSize.width), Math.ceil(canvasSize.width));
44+
assert.strictEqual(Math.ceil(imageSize.height), Math.ceil(canvasSize.height));
45+
});

e2e/utils/asserts.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
const assert = require("assert");
22
const Helpers = require("../tests/helpers");
33

4-
function deepEqualWithTolerance(actual, expected) {
5-
assert.deepStrictEqual(Helpers.convertToFixed(actual), Helpers.convertToFixed(expected));
4+
function deepEqualWithTolerance(actual, expected, fractionDigits = 2) {
5+
assert.deepStrictEqual(Helpers.convertToFixed(actual, fractionDigits), Helpers.convertToFixed(expected, fractionDigits));
66
}
7-
function notDeepEqualWithTolerance(actual, expected) {
8-
assert.notDeepStrictEqual(Helpers.convertToFixed(actual), Helpers.convertToFixed(expected));
7+
function notDeepEqualWithTolerance(actual, expected, fractionDigits = 2) {
8+
assert.notDeepStrictEqual(Helpers.convertToFixed(actual, fractionDigits), Helpers.convertToFixed(expected, fractionDigits));
99
}
1010

1111
module.exports = {

src/components/App/App.module.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
min-width: 320px;
2828
margin: 0 auto;
2929
display: flex;
30-
flex-wrap: wrap;
30+
flex-wrap: nowrap;
3131
align-items: stretch;
3232
flex-direction: column;
3333
background-color: var(--main-bg-color);

0 commit comments

Comments
 (0)