r = $r; $this->g = $g; $this->b = $b; $this->rgb = ['r' => $r, 'g' => $g, 'b' => $b]; } } class Image { public string $filename = 'UNKNOWN'; public string $extension = 'UNKNOWN'; public string $type = 'UNSUPPORTED'; public string $size = '0 B'; public int $bytes = 0; public \stdClass $fullInfo; private array $supported = [ 'image/gif' => Gif::class, 'image/jpeg' => Jpeg::class, 'image/png' => Png::class, 'image/x-tga' => Targa::class, ]; public function __construct(string $file) { $file = ROOT.$file; // $file = ROOT.'/public/static/article/mock-screenshot.tga'; if (!file_exists($file)) return; $fp = fopen($file, 'rb'); if (!$fp) return; $extBytes = fread($fp, 15); fclose($fp); $this->bytes = filesize($file); $this->size = $this->formatBytes($this->bytes); $this->extension = pathinfo($file, PATHINFO_EXTENSION); $this->filename = str_replace('.'.$this->extension, '', array_last(explode('/', $file))); if (substr($extBytes, 0, 3) === "\xff\xd8\xff") $this->type = 'image/jpeg'; else if (substr($extBytes, 0, 15) === "\x52\x49\x46\x46\x1a\x28\x00\x00\x57\x45\x42\x50\x56\x50\x38") $this->type = 'image/webp'; else if (substr($extBytes, 0, 3) === "\x42\x4d\x36") $this->type = 'image/bmp'; else if (substr($extBytes, 0, 6) === "\x89\x50\x4e\x47\x0d\x0a") $this->type = 'image/png'; else if (substr($extBytes, 0, 6) === "\x47\x49\x46\x38\x37\x61" || substr($extBytes, 0, 6) === "\x47\x49\x46\x38\x39\x61") $this->type = 'image/gif'; else if (str_ends_with($file, '.tga')) $this->type = 'image/x-tga'; $this->fullInfo = $this->createHandler($this->type)->parse($file); $this->fullInfo->type = $this->type; $this->fullInfo->size = $this->size; $this->fullInfo->bytes = $this->bytes; } /////////////// private function createHandler(string $ext): ImageInterface { $class = $this->supported[$ext] ?? null; if (!$class) throw new \RuntimeException("形式のハンドルが存在しない: {$ext}"); return new $class(); } private function formatBytes(int $size, int $precision = 2): string { $units = ['B', 'KiB', 'MiB', 'GiB', 'TiB']; for ($i = 0; $size > 1024 && $i < count($units) - 1; ++$i) $size /= 1024; return round($size, $precision).' '.$units[$i]; } }