def photo_pixelate(self, src_dir: str, nr_pixels_in_x: int, nr_pixels_in_y: int) -> Photo: """ Pixelate the given photo by chopping it up in rectangles, and replace every square by its most matching photo """ result = Photo.new(mode='RGB', size=self.output_size) analyzer = PhotoAnalyzer(src_dir, nr_photo_pixels=nr_pixels_in_x * nr_pixels_in_y) for original_box, output_box in self._get_boxes( nr_pixels_in_x, nr_pixels_in_y): sub_img = Photo(self.original_photo.crop(original_box)) output_img_size = (output_box[2] - output_box[0], output_box[3] - output_box[1]) best_photo = analyzer.select_best_photo( sub_img.avg_color, desired_size=output_img_size) best_photo = best_photo.convert('RGBA') colored_box = Image.new(mode='RGB', size=best_photo.size, color=sub_img.avg_color) mask = Image.new(mode='RGBA', size=best_photo.size, color=(0, 0, 0, cheat_parameter)) best_photo.paste(colored_box, mask=mask) result.paste(best_photo, box=output_box) return result
def pixelate(self, nr_pixels_in_x: int, nr_pixels_in_y: int) -> Photo: """ Pixelate the given photo by chopping it up in rectangles, and replace every square by its average color """ # TODO: Instead of calculating the average color of a box, resize the source image # to the amount of pixels you need, then this resizing takes care of calculating # the average color. The result is not identical, but you can't say with the # human eye which one is better. We now do resize the original photo, but we # didn't remove the calculation yet and just take the one pixel value. self.original_size = (nr_pixels_in_x, nr_pixels_in_y) self.original_photo = self.original_photo.resize(self.original_size) result = Photo.new(mode='RGB', size=self.output_size) for original_box, output_box in self._get_boxes( nr_pixels_in_x, nr_pixels_in_y): print(original_box) sub_img = Photo(self.original_photo.crop(original_box)) output_img_size = (output_box[2] - output_box[0], output_box[3] - output_box[1]) colored_box = Image.new(mode='RGB', size=output_img_size, color=sub_img.avg_color) result.paste(colored_box, box=output_box) return result
def equal_rgb_image(self) -> Photo: photo = Photo.new(size=(120, 40), mode='RGB') red_box = Image.new(size=(40, 40), color=(255, 0, 0), mode='RGB') green_box = Image.new(size=(40, 40), color=(0, 255, 0), mode='RGB') blue_box = Image.new(size=(40, 40), color=(0, 0, 255), mode='RGB') photo.paste(red_box, (0, 0)) photo.paste(green_box, (40, 0)) photo.paste(blue_box, (80, 0)) return photo
def test_that_two_photos_are_not_equal_if_one_pixel_different(self): photo_1 = Photo.new(size=(10, 10), color=(0, 0, 0), mode='RGB') photo_2 = Photo.new(size=(10, 10), color=(0, 0, 0), mode='RGB') self.assertEqual(photo_1, photo_2) photo_2.img.putpixel((5, 5), (1, 0, 0)) self.assertNotEqual(photo_1, photo_2)
def test_that_two_photos_are_not_equal_if_not_equal_in_size(self): photo_1 = Photo.new(size=(10, 10), color=(0, 0, 0), mode='RGB') photo_2 = Photo.new(size=(10, 10), color=(0, 0, 0), mode='RGB') self.assertEqual(photo_1, photo_2) photo_3 = Photo(photo_1.resize((5, 5))) self.assertNotEqual(photo_3, photo_2)
def test_that_uniform_image_returns_that_color(self): for color in [(0, 0, 0), (255, 255, 255), (255, 0, 0)]: photo = Photo.new(size=(100, 50), color=color, mode='RGB') self.assertTupleEqual(color, photo.avg_color)