class OsUtilsTestCase(TestCase):
    dirname = 'OsUtilsTestCase'
    photos_dir = Path.to_src_photos_dir(dirname)

    def setUp(self) -> None:
        if os.path.exists(self.photos_dir):
            shutil.rmtree(self.photos_dir)

    def test_that_ensure_empty_dir_creates_dir(self):
        self.assertFalse(os.path.exists(self.photos_dir))
        ensure_empty_dir(self.photos_dir)
        self.assertTrue(os.path.exists(self.photos_dir))

    def test_that_ensure_empty_dir_empties_dir(self):
        # Place a file in the directory to be emptied
        os.mkdir(self.photos_dir)
        src_full_path = Path.to_testphoto('wolf_low_res.jpg')
        dst_full_path = os.path.join(self.photos_dir, 'wolf.jpg')
        shutil.copyfile(src_full_path, dst_full_path)
        present_files = [entry.name for entry in os.scandir(self.photos_dir)]
        self.assertListEqual(['wolf.jpg'], present_files)

        ensure_empty_dir(self.photos_dir)
        present_files = [entry.name for entry in os.scandir(self.photos_dir)]
        self.assertListEqual([], present_files)
Beispiel #2
0
    def __init__(self, dirname: str) -> None:
        """
        :param dirname: Directory within the `raw` directory to collect photos from
                        Photos will be collected in this dirname in the `photos` directory
        """

        self.raw_dir = Path.to_raw_photos_dir(dirname)
        self.photos_dir = Path.to_src_photos_dir(dirname)
        :param nr_boxes: Total number of boxes to distribute over
        :return: List of tuples containing the box borders, e.g.
                [(0, 77), (77, 155), (155, 232), (232, 310), (310, 387),
                 (387, 464), (464, 542), (542, 619), (619, 697), (697, 774)]
        """

        nr_pixels_per_box: float = total_nr_pixels / nr_boxes
        return [(round(nr_pixels_per_box * index),
                 round(nr_pixels_per_box * (index + 1)))
                for index in range(nr_boxes)]


if __name__ == '__main__':
    c = MosaicCreator(Path.to_photo('wolf_high_res'), max_output_size=774)
    cheat_parameter = 50
    img = c.photo_pixelate(Path.to_src_photos_dir('cats'),
                           nr_pixels_in_x=40,
                           nr_pixels_in_y=40)
    img.show()
    img.save('wolf_photo_pixelated.jpg')
    import sys
    sys.exit()

    max_output_size = 12500
    src_photo = 'papmam1'
    c = MosaicCreator(Path.to_photo(src_photo),
                      max_output_size=max_output_size,
                      cheat_parameter=cheat_parameter)
    # img = c.pixelate(nr_pixels_in_x=18, nr_pixels_in_y=24)
    src_photos_dir = os.path.join('pap', 'mosaic')
    # TODO: Write a method that calculates this desired ratio automatically, instead of using Excel like I did now.
class PhotoCollectorTestCase(TestCase):
    dirname = 'PhotoCollectorTestCase'
    photos_dir = Path.to_src_photos_dir(dirname)
    raw_dir = Path.to_raw_photos_dir(dirname)

    def setUp(self) -> None:
        """
        Ensure that dirs photos/PhotoCollectorTestCase and raw/PhotoCollectorTestCase do not exist before tests start
        """

        for test_dir in (self.photos_dir, self.raw_dir):
            if os.path.exists(test_dir):
                shutil.rmtree(test_dir)

    def tearDown(self) -> None:
        """
        Ensure that dirs photos/PhotoCollectorTestCase and raw/PhotoCollectorTestCase do not exist after tests are done
        """

        for test_dir in (self.photos_dir, self.raw_dir):
            if os.path.exists(test_dir):
                shutil.rmtree(test_dir)

    def test_that_collect_files_gathers_files_from_single_directory(self):
        self.setup_raw_dir_structure()
        collector = PhotoCollector(self.dirname)
        collector._clean_photos_dir()
        collector._collect_files()
        present_files = sorted(entry.name for entry in os.scandir(self.photos_dir))
        self.assertListEqual(['00000001.jpg', '00000002.jpg', '00000003.jpg',
                              '00000004.jpg', '00000005.jpg', '00000006.jpg'], present_files)

    def test_that_split_by_size_ratio_results_in_correct_folder_structure(self):
        self.setup_photo_dir_structure()
        collector = PhotoCollector(self.dirname)
        most_common_resolution = collector._split_by_size_ratio()

        # Five photos are 455x455 (1:1), one photo is 474x296 (1:1.601)
        self.assertEqual(100, most_common_resolution)
        dirname = os.path.join(self.photos_dir, '100')
        nr_files_in_dir = sum(1 for _ in os.scandir(dirname))
        self.assertEqual(5, nr_files_in_dir)
        dirname = os.path.join(self.photos_dir, '160')
        nr_files_in_dir = sum(1 for _ in os.scandir(dirname))
        self.assertEqual(1, nr_files_in_dir)

    def test_that_select_images_selects_all_correct_images(self):
        self.setup_photo_dir_structure()
        collector = PhotoCollector(self.dirname)
        collector._split_by_size_ratio()

        mosaic_dir = os.path.join(self.photos_dir, 'mosaic')
        self.assertFalse(os.path.exists(mosaic_dir))
        collector._select_images(desired_size_ratio=100)

        self.assertTrue(os.path.exists(mosaic_dir))
        nr_files_in_dir = sum(1 for _ in os.scandir(mosaic_dir))
        self.assertEqual(5, nr_files_in_dir)

    def test_that_resize_images_resizes_all_images(self):
        self.setup_photo_dir_structure()
        collector = PhotoCollector(self.dirname)
        collector._split_by_size_ratio()
        collector._select_images(desired_size_ratio=100)

        # Crop the first image, such that the original is not square anymore
        mosaic_dir = os.path.join(self.photos_dir, 'mosaic')
        first_cat = os.path.join(mosaic_dir, '00000001.jpg')
        img = Photo.open(first_cat)
        img = img.crop((0, 0, 400, 200))
        img.save(first_cat)

        collector._resize_images(desired_size_ratio=100, desired_width=100)

        for file in os.scandir(mosaic_dir):
            img = Photo.open(file.path)
            desired_size = (100, 100)
            self.assertTupleEqual(desired_size, img.size)

    def setup_raw_dir_structure(self):
        """
        Create the following directory structure and files inside `raw/PhotoCollectorTestCase`:

          cat_even/
            cat002.JPG
            cat004.JPG
          cat_odd/
            first_cat/
              cat001.JPG
            cat003.JPG
            cat005.JPG
        """

        cat_even = os.path.join(self.raw_dir, 'cat_even')
        cat_odd = os.path.join(self.raw_dir, 'cat_odd')
        first_cat = os.path.join(cat_odd, 'first_cat')
        for raw_dir in (self.raw_dir, cat_even, cat_odd, first_cat):
            os.mkdir(raw_dir)

        cat002 = os.path.join(cat_even, 'cat002.JPG')
        cat004 = os.path.join(cat_even, 'cat004.JPG')
        cat006 = os.path.join(cat_even, 'cat006.JPG')
        cat001 = os.path.join(first_cat, 'cat001.JPG')
        cat003 = os.path.join(cat_odd, 'cat003.JPG')
        cat005 = os.path.join(cat_odd, 'cat005.JPG')
        src_dir = os.path.join(Path.testdata, 'cats')
        shutil.copyfile(os.path.join(src_dir, 'cat001.jpg'), cat001)
        shutil.copyfile(os.path.join(src_dir, 'cat002.jpg'), cat002)
        shutil.copyfile(os.path.join(src_dir, 'cat003.jpg'), cat003)
        shutil.copyfile(os.path.join(src_dir, 'cat004.jpg'), cat004)
        shutil.copyfile(os.path.join(src_dir, 'cat005.jpg'), cat005)
        shutil.copyfile(os.path.join(src_dir, 'cat006.jpg'), cat006)

        with open(os.path.join(self.raw_dir, 'info.txt'), 'w') as f:
            f.write('We now have 5 cat pictures in this directory')

    def setup_photo_dir_structure(self):
        self.setup_raw_dir_structure()
        collector = PhotoCollector(self.dirname)
        collector._clean_photos_dir()
        collector._collect_files()