|
@@ -7,7 +7,10 @@ import uuid
|
|
from PIL import Image
|
|
from PIL import Image
|
|
from flask import url_for
|
|
from flask import url_for
|
|
from pathlib import Path
|
|
from pathlib import Path
|
|
|
|
+
|
|
from pycs.database.File import File
|
|
from pycs.database.File import File
|
|
|
|
+from pycs.util.FileOperations import BoundingBox
|
|
|
|
+
|
|
from tests.base import pаtch_tpool_execute
|
|
from tests.base import pаtch_tpool_execute
|
|
from tests.client.label_tests import _BaseLabelTests
|
|
from tests.client.label_tests import _BaseLabelTests
|
|
|
|
|
|
@@ -286,7 +289,7 @@ class FileResizingTests(_BaseFileTests):
|
|
|
|
|
|
self.assertFalse(response.is_json)
|
|
self.assertFalse(response.is_json)
|
|
|
|
|
|
- returned_im = np.asarray(Image.open(io.BytesIO(response.data)))
|
|
|
|
|
|
+ returned_im = _im_from_bytes(response.data)
|
|
|
|
|
|
self.assertEqual(image.shape, returned_im.shape)
|
|
self.assertEqual(image.shape, returned_im.shape)
|
|
self._compare_images(image, returned_im)
|
|
self._compare_images(image, returned_im)
|
|
@@ -294,29 +297,118 @@ class FileResizingTests(_BaseFileTests):
|
|
|
|
|
|
# repeat the last scale two times to get the cached resized image
|
|
# repeat the last scale two times to get the cached resized image
|
|
for downscale in [299, 200, 150, 32, 32]:
|
|
for downscale in [299, 200, 150, 32, 32]:
|
|
- sm_image = np.asarray(Image.fromarray(image).resize((downscale, downscale)))
|
|
|
|
|
|
+ sm_image = _resize(image, downscale)
|
|
|
|
|
|
url = url_for("get_resized_file", file_id=file.id, resolution=downscale)
|
|
url = url_for("get_resized_file", file_id=file.id, resolution=downscale)
|
|
response = self.get(url)
|
|
response = self.get(url)
|
|
|
|
|
|
self.assertFalse(response.is_json)
|
|
self.assertFalse(response.is_json)
|
|
|
|
|
|
- returned_im = np.asarray(Image.open(io.BytesIO(response.data)))
|
|
|
|
|
|
+ returned_im = _im_from_bytes(response.data)
|
|
|
|
|
|
self.assertEqual(sm_image.shape, returned_im.shape)
|
|
self.assertEqual(sm_image.shape, returned_im.shape)
|
|
self._compare_images(sm_image, returned_im)
|
|
self._compare_images(sm_image, returned_im)
|
|
|
|
|
|
del sm_image
|
|
del sm_image
|
|
|
|
|
|
|
|
+ @pаtch_tpool_execute
|
|
|
|
+ def test_resize_image_not_found(self, mocked_execute):
|
|
|
|
+
|
|
|
|
+ file_uuid = str(uuid.uuid1())
|
|
|
|
+ file, is_new = self.project.add_file(
|
|
|
|
+ uuid=file_uuid,
|
|
|
|
+ file_type="image",
|
|
|
|
+ name=f"name",
|
|
|
|
+ filename=f"image",
|
|
|
|
+ extension=".png",
|
|
|
|
+ size=32*1024,
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ self.assertTrue(is_new)
|
|
|
|
+
|
|
|
|
+ image = self._add_image((300, 300), file)
|
|
|
|
|
|
save = file.path
|
|
save = file.path
|
|
file.path = "/some/nonexisting/path"
|
|
file.path = "/some/nonexisting/path"
|
|
file.commit()
|
|
file.commit()
|
|
- url = url_for("get_resized_file", file_id=file.id, resolution=upscale)
|
|
|
|
|
|
+ url = url_for("get_resized_file", file_id=file.id, resolution=300)
|
|
response = self.get(url, status_code=404)
|
|
response = self.get(url, status_code=404)
|
|
|
|
|
|
file.path = save
|
|
file.path = save
|
|
file.commit()
|
|
file.commit()
|
|
|
|
|
|
|
|
+ @pаtch_tpool_execute
|
|
|
|
+ def test_crop_image_not_found(self, mocked_execute):
|
|
|
|
+
|
|
|
|
+ file_uuid = str(uuid.uuid1())
|
|
|
|
+ file, is_new = self.project.add_file(
|
|
|
|
+ uuid=file_uuid,
|
|
|
|
+ file_type="image",
|
|
|
|
+ name=f"name",
|
|
|
|
+ filename=f"image",
|
|
|
|
+ extension=".png",
|
|
|
|
+ size=32*1024,
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ self.assertTrue(is_new)
|
|
|
|
+
|
|
|
|
+ image = self._add_image((300, 300), file)
|
|
|
|
+
|
|
|
|
+ save = file.path
|
|
|
|
+ file.path = "/some/nonexisting/path"
|
|
|
|
+ file.commit()
|
|
|
|
+ url = url_for("get_cropped_file", file_id=file.id,
|
|
|
|
+ resolution=300, crop_box="0x0x1x1")
|
|
|
|
+ response = self.get(url, status_code=404)
|
|
|
|
+
|
|
|
|
+ file.path = save
|
|
|
|
+ file.commit()
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ @pаtch_tpool_execute
|
|
|
|
+ def test_crop_image(self, mocked_execute):
|
|
|
|
+
|
|
|
|
+ file_uuid = str(uuid.uuid1())
|
|
|
|
+ file, is_new = self.project.add_file(
|
|
|
|
+ uuid=file_uuid,
|
|
|
|
+ file_type="image",
|
|
|
|
+ name=f"name",
|
|
|
|
+ filename=f"image",
|
|
|
|
+ extension=".png",
|
|
|
|
+ size=32*1024,
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ self.assertTrue(is_new)
|
|
|
|
+
|
|
|
|
+ image = self._add_image((300, 300), file)
|
|
|
|
+
|
|
|
|
+ for box in [(0,0,1,1), (0,0,1/2,1/2), (1/2,1/2, 1, 1), (1/3,1/2,3/4, 1), ]:
|
|
|
|
+ url = url_for("get_cropped_file", file_id=file.id,
|
|
|
|
+ resolution=300, crop_box="x".join(map(str, box)))
|
|
|
|
+ response = self.get(url)
|
|
|
|
+
|
|
|
|
+ self.assertFalse(response.is_json)
|
|
|
|
+
|
|
|
|
+ returned_im = _im_from_bytes(response.data)
|
|
|
|
+
|
|
|
|
+ crop = _crop(image, BoundingBox(*box))
|
|
|
|
+ self.assertEqual(crop.shape, returned_im.shape)
|
|
|
|
+ self._compare_images(crop, returned_im)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def _im_from_bytes(data: bytes) -> np.ndarray:
|
|
|
|
+ return np.asarray(Image.open(io.BytesIO(data)))
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def _resize(image: np.ndarray, size: int) -> np.ndarray:
|
|
|
|
+ return np.asarray(Image.fromarray(image).resize((size, size)))
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def _crop(image: np.ndarray, box: BoundingBox) -> np.ndarray:
|
|
|
|
+ h, w, *c = image.shape
|
|
|
|
|
|
|
|
+ x0, y0 = int(w * box.x), int(h * box.y)
|
|
|
|
+ crop_w, crop_h = int(w * box.w), int(h * box.h)
|
|
|
|
+ x1, y1 = x0 + crop_w, y0 + crop_h
|
|
|
|
|
|
|
|
+ return image[y0:y1, x0:x1]
|