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);