Skip to content

Commit e044f03

Browse files
committed
fix(blurhash): Use preview API to generate the previews
This allows to benefit from all the checks done by the preview API. This also use the newly introduced `cacheResult` argument to limit disk usage. Signed-off-by: Louis Chemineau <louis@chmn.me>
1 parent 59cf60b commit e044f03

File tree

4 files changed

+22
-74
lines changed

4 files changed

+22
-74
lines changed

build/psalm-baseline.xml

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2562,24 +2562,9 @@
25622562
</InvalidReturnStatement>
25632563
</file>
25642564
<file src="lib/private/Preview/Generator.php">
2565-
<InvalidArgument>
2566-
<code><![CDATA[$maxPreviewImage]]></code>
2567-
</InvalidArgument>
25682565
<LessSpecificReturnType>
25692566
<code><![CDATA[null|string]]></code>
25702567
</LessSpecificReturnType>
2571-
<MismatchingDocblockParamType>
2572-
<code><![CDATA[ISimpleFile]]></code>
2573-
</MismatchingDocblockParamType>
2574-
<UndefinedInterfaceMethod>
2575-
<code><![CDATA[height]]></code>
2576-
<code><![CDATA[height]]></code>
2577-
<code><![CDATA[preciseResizeCopy]]></code>
2578-
<code><![CDATA[resizeCopy]]></code>
2579-
<code><![CDATA[valid]]></code>
2580-
<code><![CDATA[width]]></code>
2581-
<code><![CDATA[width]]></code>
2582-
</UndefinedInterfaceMethod>
25832568
</file>
25842569
<file src="lib/private/Preview/ProviderV1Adapter.php">
25852570
<InvalidReturnStatement>

lib/private/Blurhash/Listener/GenerateBlurhashMetadata.php

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
use OCP\FilesMetadata\AMetadataEvent;
3737
use OCP\FilesMetadata\Event\MetadataBackgroundEvent;
3838
use OCP\FilesMetadata\Event\MetadataLiveEvent;
39+
use OCP\IPreview;
3940
use OCP\Lock\LockedException;
4041

4142
/**
@@ -44,11 +45,14 @@
4445
* @template-implements IEventListener<AMetadataEvent>
4546
*/
4647
class GenerateBlurhashMetadata implements IEventListener {
47-
private const RESIZE_BOXSIZE = 30;
48-
4948
private const COMPONENTS_X = 4;
5049
private const COMPONENTS_Y = 3;
5150

51+
public function __construct(
52+
private IPreview $preview,
53+
) {
54+
}
55+
5256
/**
5357
* @throws NotPermittedException
5458
* @throws GenericFileException
@@ -81,7 +85,9 @@ public function handle(Event $event): void {
8185
return;
8286
}
8387

84-
$image = $this->resizedImageFromFile($file);
88+
$preview = $this->preview->getPreview($file, 64, 64, cacheResult: false);
89+
$image = @imagecreatefromstring($preview->getContent());
90+
8591
if (!$image) {
8692
return;
8793
}
@@ -90,35 +96,6 @@ public function handle(Event $event): void {
9096
->setEtag('blurhash', $currentEtag);
9197
}
9298

93-
/**
94-
* @param File $file
95-
*
96-
* @return GdImage|false
97-
* @throws GenericFileException
98-
* @throws NotPermittedException
99-
* @throws LockedException
100-
*/
101-
private function resizedImageFromFile(File $file): GdImage|false {
102-
$image = @imagecreatefromstring($file->getContent());
103-
if ($image === false) {
104-
return false;
105-
}
106-
107-
$currX = imagesx($image);
108-
$currY = imagesy($image);
109-
110-
if ($currX > $currY) {
111-
$newX = self::RESIZE_BOXSIZE;
112-
$newY = intval($currY * $newX / $currX);
113-
} else {
114-
$newY = self::RESIZE_BOXSIZE;
115-
$newX = intval($currX * $newY / $currY);
116-
}
117-
118-
$newImage = @imagescale($image, $newX, $newY);
119-
return ($newImage !== false) ? $newImage : $image;
120-
}
121-
12299
/**
123100
* @param GdImage $image
124101
*

lib/private/Preview/Generator.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ public function generatePreviews(File $file, array $specifications, ?string $mim
189189
$maxPreviewImage = $this->helper->getImage($maxPreview);
190190
}
191191

192-
$preview = $this->generatePreview($previewFolder, $maxPreviewImage, $width, $height, $crop, $maxWidth, $maxHeight, $previewVersion);
192+
$preview = $this->generatePreview($previewFolder, $maxPreviewImage, $width, $height, $crop, $maxWidth, $maxHeight, $previewVersion, $cacheResult);
193193
// New file, augment our array
194194
$previewFiles[] = $preview;
195195
}
@@ -368,11 +368,10 @@ private function generateProviderPreview(ISimpleFolder $previewFolder, File $fil
368368

369369
$path = $this->generatePath($preview->width(), $preview->height(), $crop, $max, $preview->dataMimeType(), $prefix);
370370
try {
371-
$file = $previewFolder->newFile($path);
372371
if ($preview instanceof IStreamImage) {
373-
$file->putContent($preview->resource());
372+
return $previewFolder->newFile($path, $preview->resource());
374373
} else {
375-
$file->putContent($preview->data());
374+
return $previewFolder->newFile($path, $preview->data());
376375
}
377376
} catch (NotPermittedException $e) {
378377
throw new NotFoundException();
@@ -558,14 +557,13 @@ private function generatePreview(
558557
$path = $this->generatePath($width, $height, $crop, false, $preview->dataMimeType(), $prefix);
559558
try {
560559
if ($cacheResult) {
561-
$file = $previewFolder->newFile($path, $preview->data());
560+
return $previewFolder->newFile($path, $preview->data());
562561
} else {
563562
return new InMemoryFile($path, $preview->data());
564563
}
565564
} catch (NotPermittedException $e) {
566565
throw new NotFoundException();
567566
}
568-
569567
return $file;
570568
}
571569

tests/lib/Preview/GeneratorTest.php

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,19 @@
3737
use OCP\Preview\IProviderV2;
3838

3939
class GeneratorTest extends \Test\TestCase {
40-
/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
40+
/** @var IConfig&\PHPUnit\Framework\MockObject\MockObject */
4141
private $config;
4242

43-
/** @var IPreview|\PHPUnit\Framework\MockObject\MockObject */
43+
/** @var IPreview&\PHPUnit\Framework\MockObject\MockObject */
4444
private $previewManager;
4545

46-
/** @var IAppData|\PHPUnit\Framework\MockObject\MockObject */
46+
/** @var IAppData&\PHPUnit\Framework\MockObject\MockObject */
4747
private $appData;
4848

49-
/** @var GeneratorHelper|\PHPUnit\Framework\MockObject\MockObject */
49+
/** @var GeneratorHelper&\PHPUnit\Framework\MockObject\MockObject */
5050
private $helper;
5151

52-
/** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */
52+
/** @var IEventDispatcher&\PHPUnit\Framework\MockObject\MockObject */
5353
private $eventDispatcher;
5454

5555
/** @var Generator */
@@ -207,18 +207,10 @@ public function testGetNewPreview() {
207207
$previewFolder->method('getDirectoryListing')
208208
->willReturn([]);
209209
$previewFolder->method('newFile')
210-
->willReturnCallback(function ($filename) use ($maxPreview, $previewFile) {
211-
if ($filename === '2048-2048-max.png') {
212-
return $maxPreview;
213-
} elseif ($filename === '256-256.png') {
214-
return $previewFile;
215-
}
216-
$this->fail('Unexpected file');
217-
});
218-
219-
$maxPreview->expects($this->once())
220-
->method('putContent')
221-
->with($this->equalTo('my data'));
210+
->willReturnMap([
211+
['2048-2048-max.png', 'my data', $maxPreview],
212+
['256-256.png', 'my resized data', $previewFile],
213+
]);
222214

223215
$previewFolder->method('getFile')
224216
->with($this->equalTo('256-256.png'))
@@ -229,10 +221,6 @@ public function testGetNewPreview() {
229221
->with($this->equalTo($maxPreview))
230222
->willReturn($image);
231223

232-
$previewFile->expects($this->once())
233-
->method('putContent')
234-
->with('my resized data');
235-
236224
$this->eventDispatcher->expects($this->once())
237225
->method('dispatchTyped')
238226
->with(new BeforePreviewFetchedEvent($file, 100, 100, false, IPreview::MODE_FILL));

0 commit comments

Comments
 (0)