瀏覽代碼

added file crop tests and fixed some bugs

Dimitri Korsch 3 年之前
父節點
當前提交
9141e7411e
共有 3 個文件被更改,包括 100 次插入7 次删除
  1. 1 1
      pycs/frontend/WebServer.py
  2. 3 2
      pycs/frontend/endpoints/data/GetCroppedFile.py
  3. 96 4
      tests/client/file_tests.py

+ 1 - 1
pycs/frontend/WebServer.py

@@ -228,7 +228,7 @@ class WebServer:
         )
         self.app.add_url_rule(
             '/data/<int:file_id>/<resolution>/<crop_box>',
-            view_func=GetCroppedFile.as_view('crop_result')
+            view_func=GetCroppedFile.as_view('get_cropped_file')
         )
         self.app.add_url_rule(
             '/data/<int:file_id>/previous_next',

+ 3 - 2
pycs/frontend/endpoints/data/GetCroppedFile.py

@@ -7,6 +7,7 @@ from flask import send_from_directory
 from flask.views import View
 
 from pycs.database.File import File
+from pycs.util.FileOperations import BoundingBox
 from pycs.util.FileOperations import crop_file
 
 
@@ -38,10 +39,10 @@ class GetCroppedFile(View):
         crop_w = float(crop_box[2]) if len(crop_box) > 2 else 1 - crop_x
         crop_h = float(crop_box[3]) if len(crop_box) > 3 else 1 - crop_y
 
+        box = BoundingBox(x=crop_x, y=crop_y, w=crop_w, h=crop_h)
         # crop file
         file_directory, file_name = tpool.execute(crop_file, file, project.root_folder,
-                                                  crop_x, crop_y, crop_w, crop_h,
-                                                  max_width, max_height)
+                                                  box, max_width, max_height)
 
         # send to client
         return send_from_directory(file_directory, file_name)

+ 96 - 4
tests/client/file_tests.py

@@ -7,7 +7,10 @@ import uuid
 from PIL import Image
 from flask import url_for
 from pathlib import Path
+
 from pycs.database.File import File
+from pycs.util.FileOperations import BoundingBox
+
 from tests.base import pаtch_tpool_execute
 from tests.client.label_tests import _BaseLabelTests
 
@@ -286,7 +289,7 @@ class FileResizingTests(_BaseFileTests):
 
             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._compare_images(image, returned_im)
@@ -294,29 +297,118 @@ class FileResizingTests(_BaseFileTests):
 
         # repeat the last scale two times to get the cached resized image
         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)
             response = self.get(url)
 
             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._compare_images(sm_image, returned_im)
 
             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
         file.path = "/some/nonexisting/path"
         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)
 
         file.path = save
         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]