From de95a5af0b332e023d8eeb974ab5c5b9b214be30 Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Thu, 20 Apr 2017 20:26:42 +0200 Subject: [PATCH 1/3] media/thumbnailer: Better quality for 1-bit / 8-bit color palette images Pillow will use nearest neighbour as the resampling algorithm if the source image is either 1-bit or a color palette using 8 bits. If we convert to RGB before scaling, we'll probably get a better result. --- synapse/rest/media/v1/thumbnailer.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/synapse/rest/media/v1/thumbnailer.py b/synapse/rest/media/v1/thumbnailer.py index 3868d4f65f22..091ef4b9b423 100644 --- a/synapse/rest/media/v1/thumbnailer.py +++ b/synapse/rest/media/v1/thumbnailer.py @@ -50,9 +50,17 @@ def aspect(self, max_width, max_height): else: return ((max_height * self.width) // self.height, max_height) + def _resize(self, width, height): + # 1-bit or 8-bit color palette images need converting to RGB + # otherwise they will be scaled using nearest neighbour which + # looks awful + if self.image.mode in ["1", "P"]: + self.image = self.image.convert("RGB") + return self.image.resize((width, height), Image.ANTIALIAS) + def scale(self, output_path, width, height, output_type): """Rescales the image to the given dimensions""" - scaled = self.image.resize((width, height), Image.ANTIALIAS) + scaled = self._resize(width, height) return self.save_image(scaled, output_type, output_path) def crop(self, output_path, width, height, output_type): @@ -68,17 +76,13 @@ def crop(self, output_path, width, height, output_type): """ if width * self.height > height * self.width: scaled_height = (width * self.height) // self.width - scaled_image = self.image.resize( - (width, scaled_height), Image.ANTIALIAS - ) + scaled_image = self._resize(width, scaled_height) crop_top = (scaled_height - height) // 2 crop_bottom = height + crop_top cropped = scaled_image.crop((0, crop_top, width, crop_bottom)) else: scaled_width = (height * self.width) // self.height - scaled_image = self.image.resize( - (scaled_width, height), Image.ANTIALIAS - ) + scaled_image = self._resize(scaled_width, height) crop_left = (scaled_width - width) // 2 crop_right = width + crop_left cropped = scaled_image.crop((crop_left, 0, crop_right, height)) From 14b7239eee7a0864c0ccc03db3d182a8cf94adc1 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 3 Oct 2019 18:03:37 +0100 Subject: [PATCH 2/3] changelog --- changelog.d/6162.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6162.feature diff --git a/changelog.d/6162.feature b/changelog.d/6162.feature new file mode 100644 index 000000000000..e21e8325e1f9 --- /dev/null +++ b/changelog.d/6162.feature @@ -0,0 +1 @@ +Improve quality of thumbnails for 1-bit/8-bit color palette images. From 6c6726b5c3675e1d4ace18e104593dad870f2a60 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 3 Oct 2019 18:04:47 +0100 Subject: [PATCH 3/3] fix changelog name --- changelog.d/{6162.feature => 2142.feature} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog.d/{6162.feature => 2142.feature} (100%) diff --git a/changelog.d/6162.feature b/changelog.d/2142.feature similarity index 100% rename from changelog.d/6162.feature rename to changelog.d/2142.feature