diff --git a/build/fpm/Dockerfile b/build/fpm/Dockerfile
index 5e76157af67de1c82a49eee952062729fdeb8f5d..f2ce8577469d17a28d3d3fca9f7777bc9a78e057 100644
--- a/build/fpm/Dockerfile
+++ b/build/fpm/Dockerfile
@@ -17,18 +17,19 @@ RUN groupadd -g ${GID} metager && \
     chown ${UID}:${GID} /home/metager
 
 # Install required php modules
-RUN apt update && apt install -y \
+RUN apt update && apt install --no-install-recommends -y \
     libzip-dev \
     libpng-dev \
     libfreetype-dev \
     libjpeg62-turbo-dev \
     libzstd-dev \
-    libpq-dev
+    libpq-dev \
+    libmagickwand-dev
 
 RUN docker-php-ext-configure gd --with-freetype --with-jpeg
 RUN docker-php-ext-install zip gd pcntl pdo_mysql pdo_pgsql
-RUN yes 'y' | pecl install xdebug-3.2.2 igbinary-3.2.14 redis-5.3.7
-RUN docker-php-ext-enable igbinary redis
+RUN yes 'y' | pecl install xdebug-3.2.2 igbinary-3.2.14 redis-5.3.7 imagick
+RUN docker-php-ext-enable igbinary redis imagick
 RUN docker-php-ext-enable --ini-name=xdebug.ini xdebug
 
 # Add working dir for the code base
diff --git a/metager/app/Http/Controllers/Pictureproxy.php b/metager/app/Http/Controllers/Pictureproxy.php
index 8dc2ed41a3ed000333ff8d3231025e46af1b7e5e..6a96fc77dda7c0c69376922a31540f0126c83360 100644
--- a/metager/app/Http/Controllers/Pictureproxy.php
+++ b/metager/app/Http/Controllers/Pictureproxy.php
@@ -21,6 +21,8 @@ class Pictureproxy extends Controller
             'data' => 'required',
         ]);
 
+        $thumbnail_width = $request->input("thumbnail_width", null);
+
         if ($validator->fails()) {
             abort(404);
         }
@@ -33,38 +35,42 @@ class Pictureproxy extends Controller
 
         $validator = Validator::make($input_data, [
             'expires' => 'required|after_or_equal:now',
-            'url' => 'required|url',
+            'url'     => 'required|url',
         ]);
         if ($validator->fails()) {
             abort(404);
         }
 
-        $image_hash = md5($input_data["url"]);
+        $image_hash = md5($input_data["url"] . $thumbnail_width);
         if (Cache::has($image_hash)) {
             $response = Cache::get($image_hash);
         } else {
             try {
                 $url = $input_data["url"];
 
-                $file = file_get_contents($url, false);
+                $file         = file_get_contents($url, false);
                 $responseCode = explode(" ", $http_response_header[0])[1];
-                $contentType = "";
+                $contentType  = "";
                 foreach ($http_response_header as $header) {
                     if (strpos($header, "Content-Type:") === 0) {
-                        $tmp = explode(": ", $header);
+                        $tmp         = explode(": ", $header);
                         $contentType = $tmp[1];
                     }
                 }
                 if (stripos($contentType, "image/") === false) {
-                    $finfo = new \finfo(FILEINFO_MIME_TYPE);
+                    $finfo       = new \finfo(FILEINFO_MIME_TYPE);
                     $contentType = $finfo->buffer($file);
                 }
                 if (stripos($contentType, "image/") === false) {
                     abort(404);
                 }
-                
+
+                if ($contentType === "image/jpeg") {
+                    $file = $this->processJPEG($file, $thumbnail_width);
+                }
+
                 $response = Response::make($file, $responseCode, [
-                    'Content-Type' => $contentType,
+                    'Content-Type'  => $contentType,
                     "Cache-Control" => "max-age=3600, must-revalidate, public",
                     "Last-Modified" => gmdate("D, d M Y H:i:s T"),
                 ]);
@@ -76,11 +82,25 @@ class Pictureproxy extends Controller
         return $response;
     }
 
+    private function processJPEG(string $jpeg, $thumbnail_width)
+    {
+        $src_image = new \Imagick();
+        $src_image->readImageBlob($jpeg);
+
+        $src_width = $src_image->getImageWidth();
+        if ($thumbnail_width !== null && $src_width > $thumbnail_width) {
+            $src_image->thumbnailImage($thumbnail_width, 0);
+        }
+
+        $src_image->setInterlaceScheme(\Imagick::INTERLACE_PLANE);
+        return $src_image->getImageBlob();
+    }
+
     public static function generateUrl($link)
     {
         $params = [
-            "url" => $link,
-            "expires" => now()->addDay()
+            "url"     => $link,
+            "expires" => now()->addDay(),
         ];
 
         $params = Crypt::encrypt($params);