lucajackal85 /
ImageMerge
| 1 | <?php |
||||
| 2 | |||||
| 3 | namespace Jackal\ImageMerge\Metadata\Parser; |
||||
| 4 | |||||
| 5 | use Jackal\ImageMerge\Exception\ModuleNotFoundException; |
||||
| 6 | use Jackal\ImageMerge\Model\File\FileObjectInterface; |
||||
| 7 | |||||
| 8 | /** |
||||
| 9 | * Class ExifParser |
||||
| 10 | * @package Jackal\ImageMerge\Metadata\Parser |
||||
| 11 | */ |
||||
| 12 | class ExifParser extends AbstractParser |
||||
| 13 | { |
||||
| 14 | /** |
||||
| 15 | * ExifParser constructor. |
||||
| 16 | * @param FileObjectInterface $file |
||||
| 17 | * @throws ModuleNotFoundException |
||||
| 18 | */ |
||||
| 19 | public function __construct(FileObjectInterface $file) |
||||
| 20 | { |
||||
| 21 | if (!function_exists('exif_read_data')) { |
||||
| 22 | throw new ModuleNotFoundException('function exif_read_data not installed'); |
||||
| 23 | } |
||||
| 24 | $this->data = @exif_read_data($file->getPathname()); |
||||
| 25 | } |
||||
| 26 | |||||
| 27 | /** |
||||
| 28 | * @return null|string |
||||
| 29 | */ |
||||
| 30 | public function getMake() |
||||
| 31 | { |
||||
| 32 | return $this->getSingleValue('Make'); |
||||
| 33 | } |
||||
| 34 | |||||
| 35 | /** |
||||
| 36 | * @return null|string |
||||
| 37 | */ |
||||
| 38 | public function getModel() |
||||
| 39 | { |
||||
| 40 | return $this->getSingleValue('Model'); |
||||
| 41 | } |
||||
| 42 | |||||
| 43 | /** |
||||
| 44 | * @return null|string |
||||
| 45 | */ |
||||
| 46 | public function getExposure() |
||||
| 47 | { |
||||
| 48 | return $this->getSingleValue('ExposureTime'); |
||||
| 49 | } |
||||
| 50 | |||||
| 51 | /** |
||||
| 52 | * @return bool|null |
||||
| 53 | */ |
||||
| 54 | public function getFlash() |
||||
| 55 | { |
||||
| 56 | return $this->getBooleanValue('Flash'); |
||||
| 57 | } |
||||
| 58 | |||||
| 59 | /** |
||||
| 60 | * @return null|string |
||||
| 61 | */ |
||||
| 62 | public function getISO() |
||||
| 63 | { |
||||
| 64 | return $this->getSingleValue('ISOSpeedRatings'); |
||||
| 65 | } |
||||
| 66 | |||||
| 67 | /** |
||||
| 68 | * @return int|string |
||||
| 69 | */ |
||||
| 70 | public function getResolutionX() |
||||
| 71 | { |
||||
| 72 | return $this->getDivisionValue('XResolution'); |
||||
| 73 | } |
||||
| 74 | |||||
| 75 | /** |
||||
| 76 | * @return int|string |
||||
| 77 | */ |
||||
| 78 | public function getResolutionY() |
||||
| 79 | { |
||||
| 80 | return $this->getDivisionValue('YResolution'); |
||||
| 81 | } |
||||
| 82 | |||||
| 83 | /** |
||||
| 84 | * @return int|string |
||||
| 85 | */ |
||||
| 86 | public function getFocalLength() |
||||
| 87 | { |
||||
| 88 | return $this->getDivisionValue('FocalLength'); |
||||
| 89 | } |
||||
| 90 | |||||
| 91 | /** |
||||
| 92 | * @return null|string |
||||
| 93 | */ |
||||
| 94 | public function getSoftware() |
||||
| 95 | { |
||||
| 96 | return $this->getSingleValue('Software'); |
||||
| 97 | } |
||||
| 98 | |||||
| 99 | /** |
||||
| 100 | * @return null|string |
||||
| 101 | */ |
||||
| 102 | public function getLensModel() |
||||
| 103 | { |
||||
| 104 | return $this->getSingleValue('UndefinedTag:0xA434'); |
||||
| 105 | } |
||||
| 106 | |||||
| 107 | /** |
||||
| 108 | * @return null|string |
||||
| 109 | */ |
||||
| 110 | public function getCameraSerialNumber() |
||||
| 111 | { |
||||
| 112 | return $this->getSingleValue('UndefinedTag:0xA431'); |
||||
| 113 | } |
||||
| 114 | |||||
| 115 | /** |
||||
| 116 | * @return null|string |
||||
| 117 | */ |
||||
| 118 | public function getLensSerialNumber() |
||||
| 119 | { |
||||
| 120 | return $this->getSingleValue('UndefinedTag:0xA435'); |
||||
| 121 | } |
||||
| 122 | |||||
| 123 | /** |
||||
| 124 | * @return null|string |
||||
| 125 | */ |
||||
| 126 | public function getCameraOwnerName() |
||||
| 127 | { |
||||
| 128 | return $this->getSingleValue('UndefinedTag:0xA430'); |
||||
| 129 | } |
||||
| 130 | |||||
| 131 | /** |
||||
| 132 | * @return null|string |
||||
| 133 | */ |
||||
| 134 | public function getLensSpecification() |
||||
| 135 | { |
||||
| 136 | return $this->getValue('UndefinedTag:0xA432'); |
||||
|
0 ignored issues
–
show
Bug
Best Practice
introduced
by
Loading history...
|
|||||
| 137 | } |
||||
| 138 | |||||
| 139 | /** |
||||
| 140 | * @return null|string |
||||
| 141 | */ |
||||
| 142 | public function getExposureCompensation() |
||||
| 143 | { |
||||
| 144 | return $this->getSingleValue('ExposureBiasValue'); |
||||
| 145 | } |
||||
| 146 | |||||
| 147 | /** |
||||
| 148 | * @return int|string |
||||
| 149 | */ |
||||
| 150 | public function getApertureValue() |
||||
| 151 | { |
||||
| 152 | return $this->getDivisionValue('FNumber'); |
||||
| 153 | } |
||||
| 154 | |||||
| 155 | /** |
||||
| 156 | * @return null|string |
||||
| 157 | */ |
||||
| 158 | public function getMeteringMode() |
||||
| 159 | { |
||||
| 160 | return $this->getSingleValue('MeteringMode'); |
||||
| 161 | } |
||||
| 162 | |||||
| 163 | /** |
||||
| 164 | * @return null|string |
||||
| 165 | */ |
||||
| 166 | public function getShutterSpeed() |
||||
| 167 | { |
||||
| 168 | return $this->getSingleValue('ExposureTime'); |
||||
| 169 | } |
||||
| 170 | |||||
| 171 | public function getGPS() |
||||
| 172 | { |
||||
| 173 | |||||
| 174 | /** |
||||
| 175 | * Taken from https://www.codexworld.com/get-geolocation-latitude-longitude-from-image-php/ |
||||
| 176 | */ |
||||
| 177 | $GPSLatitudeRef = $this->getValue('GPSLatitudeRef'); |
||||
| 178 | $GPSLatitude = $this->getValue('GPSLatitude') ? $this->getValue('GPSLatitude') : []; |
||||
| 179 | $GPSLongitudeRef = $this->getValue('GPSLongitudeRef'); |
||||
| 180 | $GPSLongitude = $this->getValue('GPSLongitude') ? $this->getValue('GPSLongitude') : []; |
||||
| 181 | |||||
| 182 | $lat_degrees = count($GPSLatitude) > 0 ? $this->gps2Num($GPSLatitude[0]) : 0; |
||||
|
0 ignored issues
–
show
It seems like
$GPSLatitude can also be of type string; however, parameter $var of count() does only seem to accept Countable|array, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 183 | $lat_minutes = count($GPSLatitude) > 1 ? $this->gps2Num($GPSLatitude[1]) : 0; |
||||
| 184 | $lat_seconds = count($GPSLatitude) > 2 ? $this->gps2Num($GPSLatitude[2]) : 0; |
||||
| 185 | |||||
| 186 | $lon_degrees = count($GPSLongitude) > 0 ? $this->gps2Num($GPSLongitude[0]) : 0; |
||||
| 187 | $lon_minutes = count($GPSLongitude) > 1 ? $this->gps2Num($GPSLongitude[1]) : 0; |
||||
| 188 | $lon_seconds = count($GPSLongitude) > 2 ? $this->gps2Num($GPSLongitude[2]) : 0; |
||||
| 189 | |||||
| 190 | $lat_direction = ($GPSLatitudeRef == 'W' or $GPSLatitudeRef == 'S') ? -1 : 1; |
||||
| 191 | $lon_direction = ($GPSLongitudeRef == 'W' or $GPSLongitudeRef == 'S') ? -1 : 1; |
||||
| 192 | |||||
| 193 | $latitude = $lat_direction * ($lat_degrees + ($lat_minutes / 60) + ($lat_seconds / (60 * 60))); |
||||
| 194 | $longitude = $lon_direction * ($lon_degrees + ($lon_minutes / 60) + ($lon_seconds / (60 * 60))); |
||||
| 195 | |||||
| 196 | $latitude_deg = sprintf('%s°%s\'%s" %s', $lat_degrees, $lat_minutes, $lat_seconds, $lat_direction == 1 ? 'N':'S'); |
||||
| 197 | $longitude_deg = sprintf('%s°%s\'%s" %s', $lon_degrees, $lon_minutes, $lon_seconds, $lon_direction == 1 ? 'E':'W'); |
||||
| 198 | |||||
| 199 | return [ |
||||
| 200 | 'lat' => $latitude, |
||||
| 201 | 'lon' => $longitude, |
||||
| 202 | 'lat_deg' => $latitude_deg, |
||||
| 203 | 'lon_deg' => $longitude_deg, |
||||
| 204 | ]; |
||||
| 205 | } |
||||
| 206 | |||||
| 207 | private function gps2Num($coordPart) |
||||
| 208 | { |
||||
| 209 | $parts = explode('/', $coordPart); |
||||
| 210 | if (count($parts) <= 0) { |
||||
| 211 | return 0; |
||||
| 212 | } |
||||
| 213 | if (count($parts) == 1) { |
||||
| 214 | return $parts[0]; |
||||
| 215 | } |
||||
| 216 | |||||
| 217 | return floatval($parts[0]) / floatval($parts[1]); |
||||
| 218 | } |
||||
| 219 | |||||
| 220 | /** |
||||
| 221 | * @return array |
||||
| 222 | */ |
||||
| 223 | public function toArray() |
||||
| 224 | { |
||||
| 225 | return [ |
||||
| 226 | 'gps' => $this->getGPS(), |
||||
| 227 | 'camera' => [ |
||||
| 228 | 'make' => $this->getMake(), |
||||
| 229 | 'model' => $this->getModel(), |
||||
| 230 | 'serial_number' => $this->getCameraSerialNumber(), |
||||
| 231 | 'owner' => $this->getCameraOwnerName(), |
||||
| 232 | ], |
||||
| 233 | 'exposure' => $this->getExposure(), |
||||
| 234 | 'exposure_compensation' => $this->getExposureCompensation(), |
||||
| 235 | 'flash' => $this->getFlash(), |
||||
| 236 | 'iso' => $this->getISO(), |
||||
| 237 | 'resolution' => [ |
||||
| 238 | 'x' => $this->getResolutionX(), |
||||
| 239 | 'y' => $this->getResolutionY(), |
||||
| 240 | ], |
||||
| 241 | 'focal_length' => $this->getFocalLength(), |
||||
| 242 | 'software' => $this->getSoftware(), |
||||
| 243 | 'lens' => [ |
||||
| 244 | 'model' => $this->getLensModel(), |
||||
| 245 | 'serial_number' => $this->getLensSerialNumber(), |
||||
| 246 | 'specification' => $this->getLensSpecification(), |
||||
| 247 | ], |
||||
| 248 | 'aperture' => $this->getApertureValue(), |
||||
| 249 | 'metering' => $this->getMeteringMode(), |
||||
| 250 | 'shutter' => $this->getShutterSpeed(), |
||||
| 251 | ]; |
||||
| 252 | } |
||||
| 253 | } |
||||
| 254 |