From ffa83f8e9a775f2f4782872479d4470579e5f286 Mon Sep 17 00:00:00 2001 From: Philipp Lang Date: Fri, 17 Sep 2021 12:22:19 +0000 Subject: [PATCH] Compress original Image of PDF file --- classes/ImageResizer.php | 11 +- compressors/Compressor.php | 8 ++ compressors/Factory.php | 1 + compressors/JpgCompressor.php | 14 ++- compressors/PdfCompressor.php | 62 +++++++++++ compressors/PngCompressor.php | 5 + tests/ResizerTest.php | 14 +++ tests/stub/dummy.pdf | 198 ++++++++++++++++++++++++++++++++++ 8 files changed, 299 insertions(+), 14 deletions(-) create mode 100644 compressors/PdfCompressor.php create mode 100644 tests/stub/dummy.pdf diff --git a/classes/ImageResizer.php b/classes/ImageResizer.php index 45d8441..ec42644 100644 --- a/classes/ImageResizer.php +++ b/classes/ImageResizer.php @@ -36,7 +36,7 @@ class ImageResizer private function dimensions(): Collection { - [$width, $height] = getimagesize($this->file->root()); + [$width, $height] = $this->file->compressor()->originalSize(); return collect(compact('width', 'height')); } @@ -56,19 +56,18 @@ class ImageResizer $ratios = collect(); $ratios->push($this->dimensions()); $ratios = $ratios->merge($this->sizes()); - [$origWidth, $origHeight] = getimagesize($this->file->root()); foreach (collect(Setting::get('breakpoints'))->push($this->dimensions()->get('width'))->unique() as $size) { foreach ($ratios as $ratio) { $width = $size; $height = $size * $ratio->get('height') / $ratio->get('width'); - if ($height > $origHeight) { - $width = $width * $origHeight / $height; - $height = $origHeight; + if ($height > $this->dimensions()->get('height')) { + $width = $width * $this->dimensions()->get('height') / $height; + $height = $this->dimensions()->get('height'); } - if (ceil($width) > $origWidth || ceil($height) > $origHeight) { + if (ceil($width) > $this->dimensions()->get('width') || ceil($height) > $this->dimensions()->get('height')) { continue; } diff --git a/compressors/Compressor.php b/compressors/Compressor.php index 86ef558..2d71ccb 100644 --- a/compressors/Compressor.php +++ b/compressors/Compressor.php @@ -2,15 +2,23 @@ namespace Aweos\Resizer\Compressors; +use Aweos\Resizer\Lib\MediaPath; use Storage; abstract class Compressor { + protected $media; + abstract function make(string $path): array; abstract protected function getExtension(); + public function __construct(MediaPath $media) + { + $this->media = $media; + } + public function tmpPath(): string { return "/tmp/".str_slug(microtime()); diff --git a/compressors/Factory.php b/compressors/Factory.php index 6a1025f..c991c65 100644 --- a/compressors/Factory.php +++ b/compressors/Factory.php @@ -12,6 +12,7 @@ class Factory public array $types = [ 'image/jpeg' => JpgCompressor::class, 'image/png' => PngCompressor::class, + 'application/pdf' => PdfCompressor::class, ]; public function fromMedia(string $mediaPath): Compressor diff --git a/compressors/JpgCompressor.php b/compressors/JpgCompressor.php index 9de7d2b..2a96a85 100644 --- a/compressors/JpgCompressor.php +++ b/compressors/JpgCompressor.php @@ -26,6 +26,11 @@ class JpgCompressor extends Compressor { ]; } + public function originalSize(): array + { + return getimagesize($this->media->root()); + } + public function shouldGenerateVersions(): bool { return true; @@ -42,14 +47,7 @@ class JpgCompressor extends Compressor { list($destWidth, $destHeight) = getimagesize(Storage::path($temp)); - $versionFilename = $destination. - '/'. - pathinfo($source, PATHINFO_FILENAME). - '-'. - $destWidth. - 'x'. - $destHeight. - '.jpg'; + $versionFilename = $destination.'/'.$this->versionFilename($source, $destWidth, $destHeight); $this->moveTo($temp, $versionFilename); } diff --git a/compressors/PdfCompressor.php b/compressors/PdfCompressor.php new file mode 100644 index 0000000..f1185c3 --- /dev/null +++ b/compressors/PdfCompressor.php @@ -0,0 +1,62 @@ +tmpPath(); + $mimetype = mime_content_type($path); + + system('imagemin '.escapeshellarg($path).' --plugin=jpegtran --plugin=mozjpeg --plugin.mozjpeg.quality=70 > '.escapeshellarg($output)); + system("mv ".escapeshellarg($output)." ".escapeshellarg($path)); + + return [ + $path => [$path], + ]; + } + + private function extractImage(string $pdf): string + { + $file = $this->tmpPath().'.jpg'; + + exec('convert -density 150 '.escapeshellarg($pdf.'[0]').' -quality 90 '.escapeshellarg($file), $output, $r); + + return $file; + } + + public function originalSize(): array + { + return getimagesize($this->extractImage($this->media->root())); + } + + public function shouldGenerateVersions(): bool + { + return true; + } + + public function resize(string $source, string $destination, Collection $size): void + { + $temp = $this->extractImage($source); + + $r = app(ImageManager::class)->make($temp) + ->fit($size->get('width'), $size->get('height'), fn ($constraint) => $constraint->upsize()) + ->save($temp); + + list($destWidth, $destHeight) = getimagesize($temp); + $versionFilename = $destination.'/'.$this->versionFilename($source, $destWidth, $destHeight); + + Storage::put($versionFilename, file_get_contents($temp)); + } + +} diff --git a/compressors/PngCompressor.php b/compressors/PngCompressor.php index 9483f2f..96a17e5 100644 --- a/compressors/PngCompressor.php +++ b/compressors/PngCompressor.php @@ -26,6 +26,11 @@ class PngCompressor extends Compressor { ]; } + public function originalSize(): array + { + return getimagesize($this->media->root()); + } + public function shouldGenerateVersions(): bool { return true; diff --git a/tests/ResizerTest.php b/tests/ResizerTest.php index a0d22c4..be0e6c3 100644 --- a/tests/ResizerTest.php +++ b/tests/ResizerTest.php @@ -224,4 +224,18 @@ class ResizerTest extends TestCase $this->assertFileCount(2, 'pages'); } + public function testGeneratePdfImages(): void + { + Setting::set('folders', [['folder' => '/pages']]); + Setting::set('sizes', []); + Setting::set('breakpoints', []); + + $media = MediaLibrary::instance(); + $media->put('/pages/test.pdf', file_get_contents(__DIR__.'/stub/dummy.pdf')); + Event::fire('media.file.upload', [null, '/pages/test.pdf', null]); + + $this->assertHasFile('pages/test-1275x1650.jpg'); + $this->assertFileCount(1, 'pages'); + } + } diff --git a/tests/stub/dummy.pdf b/tests/stub/dummy.pdf new file mode 100644 index 0000000..dbf091d --- /dev/null +++ b/tests/stub/dummy.pdf @@ -0,0 +1,198 @@ +%PDF-1.3 +%âãÏÓ + +1 0 obj +<< +/Type /Catalog +/Outlines 2 0 R +/Pages 3 0 R +>> +endobj + +2 0 obj +<< +/Type /Outlines +/Count 0 +>> +endobj + +3 0 obj +<< +/Type /Pages +/Count 2 +/Kids [ 4 0 R 6 0 R ] +>> +endobj + +4 0 obj +<< +/Type /Page +/Parent 3 0 R +/Resources << +/Font << +/F1 9 0 R +>> +/ProcSet 8 0 R +>> +/MediaBox [0 0 612.0000 792.0000] +/Contents 5 0 R +>> +endobj + +5 0 obj +<< /Length 1074 >> +stream +2 J +BT +0 0 0 rg +/F1 0027 Tf +57.3750 722.2800 Td +( A Simple PDF File ) Tj +ET +BT +/F1 0010 Tf +69.2500 688.6080 Td +( This is a small demonstration .pdf file - ) Tj +ET +BT +/F1 0010 Tf +69.2500 664.7040 Td +( just for use in the Virtual Mechanics tutorials. More text. And more ) Tj +ET +BT +/F1 0010 Tf +69.2500 652.7520 Td +( text. And more text. And more text. And more text. ) Tj +ET +BT +/F1 0010 Tf +69.2500 628.8480 Td +( And more text. And more text. And more text. And more text. And more ) Tj +ET +BT +/F1 0010 Tf +69.2500 616.8960 Td +( text. And more text. Boring, zzzzz. And more text. And more text. And ) Tj +ET +BT +/F1 0010 Tf +69.2500 604.9440 Td +( more text. And more text. And more text. And more text. And more text. ) Tj +ET +BT +/F1 0010 Tf +69.2500 592.9920 Td +( And more text. And more text. ) Tj +ET +BT +/F1 0010 Tf +69.2500 569.0880 Td +( And more text. And more text. And more text. And more text. And more ) Tj +ET +BT +/F1 0010 Tf +69.2500 557.1360 Td +( text. And more text. And more text. Even more. Continued on page 2 ...) Tj +ET +endstream +endobj + +6 0 obj +<< +/Type /Page +/Parent 3 0 R +/Resources << +/Font << +/F1 9 0 R +>> +/ProcSet 8 0 R +>> +/MediaBox [0 0 612.0000 792.0000] +/Contents 7 0 R +>> +endobj + +7 0 obj +<< /Length 676 >> +stream +2 J +BT +0 0 0 rg +/F1 0027 Tf +57.3750 722.2800 Td +( Simple PDF File 2 ) Tj +ET +BT +/F1 0010 Tf +69.2500 688.6080 Td +( ...continued from page 1. Yet more text. And more text. And more text. ) Tj +ET +BT +/F1 0010 Tf +69.2500 676.6560 Td +( And more text. And more text. And more text. And more text. And more ) Tj +ET +BT +/F1 0010 Tf +69.2500 664.7040 Td +( text. Oh, how boring typing this stuff. But not as boring as watching ) Tj +ET +BT +/F1 0010 Tf +69.2500 652.7520 Td +( paint dry. And more text. And more text. And more text. And more text. ) Tj +ET +BT +/F1 0010 Tf +69.2500 640.8000 Td +( Boring. More, a little more text. The end, and just as well. ) Tj +ET +endstream +endobj + +8 0 obj +[/PDF /Text] +endobj + +9 0 obj +<< +/Type /Font +/Subtype /Type1 +/Name /F1 +/BaseFont /Helvetica +/Encoding /WinAnsiEncoding +>> +endobj + +10 0 obj +<< +/Creator (Rave \(http://www.nevrona.com/rave\)) +/Producer (Nevrona Designs) +/CreationDate (D:20060301072826) +>> +endobj + +xref +0 11 +0000000000 65535 f +0000000019 00000 n +0000000093 00000 n +0000000147 00000 n +0000000222 00000 n +0000000390 00000 n +0000001522 00000 n +0000001690 00000 n +0000002423 00000 n +0000002456 00000 n +0000002574 00000 n + +trailer +<< +/Size 11 +/Root 1 0 R +/Info 10 0 R +>> + +startxref +2714 +%%EOF