Skip to content

Commit 4ef4c6c

Browse files
committed
Add suport of reading PNG JPEG Exif metadata
1 parent 5c7c959 commit 4ef4c6c

File tree

6 files changed

+177
-52
lines changed

6 files changed

+177
-52
lines changed

app/code/Magento/MediaGalleryMetadata/Model/Jpeg/Segment/ReadExif.php

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,44 @@ public function __construct(
4141
*/
4242
public function execute(FileInterface $file): MetadataInterface
4343
{
44-
$title = null;
45-
$description = null;
46-
$keywords = [];
44+
if (!is_callable('exif_read_data')) {
45+
throw new LocalizedException(
46+
__('exif_read_data() must be enabled in php configuration')
47+
);
48+
}
4749

4850
foreach ($file->getSegments() as $segment) {
4951
if ($this->isExifSegment($segment)) {
52+
return $this->getExifData($file->getPath());
5053
}
5154
}
55+
56+
return $this->metadataFactory->create([
57+
'title' => null,
58+
'description' => null,
59+
'keywords' => null
60+
]);
61+
}
62+
63+
/**
64+
* Parese exif data from segment
65+
*
66+
* @param string $filePath
67+
*/
68+
private function getExifData(string $filePath): MetadataInterface
69+
{
70+
$title = null;
71+
$description = null;
72+
$keywords = [];
73+
74+
$data = exif_read_data($filePath);
75+
76+
if ($data) {
77+
$title = isset($data['DocumentName']) ? $data['DocumentName'] : null;
78+
$description = isset($data['ImageDescription']) ? $data['ImageDescription'] : null;
79+
$keywords = '';
80+
}
81+
5282
return $this->metadataFactory->create([
5383
'title' => $title,
5484
'description' => $description,
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\MediaGalleryMetadata\Model\Png\Segment;
9+
10+
use Magento\MediaGalleryMetadataApi\Api\Data\MetadataInterface;
11+
use Magento\MediaGalleryMetadataApi\Api\Data\MetadataInterfaceFactory;
12+
use Magento\MediaGalleryMetadataApi\Model\FileInterface;
13+
use Magento\MediaGalleryMetadataApi\Model\ReadMetadataInterface;
14+
use Magento\MediaGalleryMetadataApi\Model\SegmentInterface;
15+
16+
/**
17+
* Jpeg EXIF Reader
18+
*/
19+
class ReadExif implements ReadMetadataInterface
20+
{
21+
private const EXIF_SEGMENT_NAME = 'eXIf';
22+
23+
/**
24+
* @var MetadataInterfaceFactory
25+
*/
26+
private $metadataFactory;
27+
28+
/**
29+
* @param MetadataInterfaceFactory $metadataFactory
30+
*/
31+
public function __construct(
32+
MetadataInterfaceFactory $metadataFactory
33+
) {
34+
$this->metadataFactory = $metadataFactory;
35+
}
36+
37+
/**
38+
* @inheritdoc
39+
*/
40+
public function execute(FileInterface $file): MetadataInterface
41+
{
42+
foreach ($file->getSegments() as $segment) {
43+
if ($this->isExifSegment($segment)) {
44+
return $this->getExifData($segment);
45+
}
46+
}
47+
48+
return $this->metadataFactory->create([
49+
'title' => null,
50+
'description' => null,
51+
'keywords' => null
52+
]);
53+
}
54+
55+
/**
56+
* Parese exif data from segment
57+
*
58+
* @param FileInterface $filePath
59+
*/
60+
private function getExifData(SegmentInterface $segment): MetadataInterface
61+
{
62+
$title = null;
63+
$description = null;
64+
$keywords = [];
65+
66+
$data = exif_read_data('data://image/jpeg;base64,' . base64_encode($segment->getData()));
67+
68+
if ($data) {
69+
$title = isset($data['DocumentName']) ? $data['DocumentName'] : null;
70+
$description = isset($data['ImageDescription']) ? $data['ImageDescription'] : null;
71+
$keywords = '';
72+
}
73+
74+
return $this->metadataFactory->create([
75+
'title' => $title,
76+
'description' => $description,
77+
'keywords' => !empty($keywords) ? $keywords : null
78+
]);
79+
}
80+
81+
/**
82+
* Does segment contain Exif data
83+
*
84+
* @param SegmentInterface $segment
85+
* @return bool
86+
*/
87+
private function isExifSegment(SegmentInterface $segment): bool
88+
{
89+
return $segment->getName() === self::EXIF_SEGMENT_NAME;
90+
}
91+
}

app/code/Magento/MediaGalleryMetadata/Test/Integration/Model/ExtractMetadataTest.php

Lines changed: 52 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ protected function setUp(): void
3737
* @param string $fileName
3838
* @param string $title
3939
* @param string $description
40-
* @param array $keywords
40+
* @param null|array $keywords
4141
* @throws LocalizedException
4242
*/
4343
public function testExecute(
4444
string $fileName,
4545
string $title,
4646
string $description,
47-
array $keywords
47+
?array $keywords
4848
): void {
4949
$path = realpath(__DIR__ . '/../../_files/' . $fileName);
5050
$metadata = $this->extractMetadata->execute($path);
@@ -62,60 +62,63 @@ public function testExecute(
6262
public function filesProvider(): array
6363
{
6464
return [
65+
[
66+
'exif_image.png',
67+
'Exif title png imge',
68+
'Exif description png imge',
69+
null
70+
],
6571
[
6672
'exif-image.jpeg',
73+
'Exif Magento title',
74+
'Exif description metadata',
75+
null
76+
],
77+
[
78+
'macos-photos.jpeg',
79+
'Title of the magento image',
80+
'Description of the magento image',
81+
[
82+
'magento',
83+
'mediagallerymetadata'
84+
]
85+
],
86+
[
87+
'macos-preview.png',
88+
'Title of the magento image',
89+
'Description of the magento image',
90+
[
91+
'magento',
92+
'mediagallerymetadata'
93+
]
94+
],
95+
[
96+
'iptc_only.jpeg',
97+
'Title of the magento image',
98+
'Description of the magento image',
99+
[
100+
'magento',
101+
'mediagallerymetadata'
102+
]
103+
],
104+
[
105+
'exiftool.gif',
106+
'Title of the magento image',
107+
'Description of the magento image',
108+
[
109+
'magento',
110+
'mediagallerymetadata'
111+
]
112+
],
113+
[
114+
'iptc_only.png',
67115
'Title of the magento image',
68-
'exif fromat title',
116+
'PNG format is awesome',
69117
[
70-
'exif',
118+
'png',
71119
'awesome'
72120
]
73121
],
74-
//[
75-
// 'macos-photos.jpeg',
76-
// 'Title of the magento image',
77-
// 'Description of the magento image',
78-
// [
79-
// 'magento',
80-
// 'mediagallerymetadata'
81-
// ]
82-
//],
83-
// [
84-
// 'macos-preview.png',
85-
// 'Title of the magento image',
86-
// 'Description of the magento image',
87-
// [
88-
// 'magento',
89-
// 'mediagallerymetadata'
90-
/// ]
91-
// ],
92-
// [
93-
// 'iptc_only.jpeg',
94-
/// 'Title of the magento image',
95-
// 'Description of the magento image',
96-
// [
97-
// 'magento',
98-
// 'mediagallerymetadata'
99-
// ]
100-
//],
101-
//[
102-
// 'exiftool.gif',
103-
// 'Title of the magento image',
104-
// 'Description of the magento image',
105-
// [
106-
// 'magento',
107-
// 'mediagallerymetadata'
108-
// ]
109-
// ],
110-
//[
111-
// 'iptc_only.png',
112-
// 'Title of the magento image',
113-
// 'PNG format is awesome',
114-
// [
115-
// 'png',
116-
// 'awesome'
117-
// ]
118-
///],
119122
];
120123
}
121124
}
Loading
Loading

app/code/Magento/MediaGalleryMetadata/etc/di.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
<argument name="segmentReaders" xsi:type="array">
113113
<item name="xmp" xsi:type="object">Magento\MediaGalleryMetadata\Model\Png\Segment\ReadXmp</item>
114114
<item name="iptc" xsi:type="object">Magento\MediaGalleryMetadata\Model\Png\Segment\ReadIptc</item>
115+
<item name="exif" xsi:type="object">Magento\MediaGalleryMetadata\Model\Png\Segment\ReadExif</item>
115116
</argument>
116117
</arguments>
117118
</virtualType>

0 commit comments

Comments
 (0)