Как я могу прочитать метаданные PNG из PHP?

Это то, что у меня есть до сих пор:

<?php $file = "18201010338AM16390621000846.png"; $test = file_get_contents($file, FILE_BINARY); echo str_replace("\n","<br>",$test); ?> 

Результат – это то, что я хочу, но мне действительно нужны строки 3-7 (включительно). Вот как выглядит результат: http://silentnoobs.com/pbss/collector/test.php . Я пытаюсь получить данные из «Скриншот PunkBuster (±) AAO Bridge Crossing» на «Результат: w = 394 X h = 196 sample = 2». Я думаю, что было бы довольно просто прочитать файл и сохранить каждую строку в массиве, строка [0] должна быть «Скриншот PunkBuster (±) AAO Bridge Crossing» и т. Д.). Все эти строки могут быть изменены, поэтому я не могу просто найти что-то конечное.

Я пробовал в течение нескольких дней, и это не очень помогает, что я беден на php.

Формат PNG-файла определяет, что PNG-документ разбивается на несколько фрагментов данных. Поэтому вы должны перейти к своему желаемому куску.

Данные, которые вы хотите извлечь, по-видимому, определены в tEXt . Я написал следующий класс, чтобы вы могли извлекать куски из файлов PNG.

 class PNG_Reader { private $_chunks; private $_fp; function __construct($file) { if (!file_exists($file)) { throw new Exception('File does not exist'); } $this->_chunks = array (); // Open the file $this->_fp = fopen($file, 'r'); if (!$this->_fp) throw new Exception('Unable to open file'); // Read the magic bytes and verify $header = fread($this->_fp, 8); if ($header != "\x89PNG\x0d\x0a\x1a\x0a") throw new Exception('Is not a valid PNG image'); // Loop through the chunks. Byte 0-3 is length, Byte 4-7 is type $chunkHeader = fread($this->_fp, 8); while ($chunkHeader) { // Extract length and type from binary data $chunk = @unpack('Nsize/a4type', $chunkHeader); // Store position into internal array if ($this->_chunks[$chunk['type']] === null) $this->_chunks[$chunk['type']] = array (); $this->_chunks[$chunk['type']][] = array ( 'offset' => ftell($this->_fp), 'size' => $chunk['size'] ); // Skip to next chunk (over body and CRC) fseek($this->_fp, $chunk['size'] + 4, SEEK_CUR); // Read next chunk header $chunkHeader = fread($this->_fp, 8); } } function __destruct() { fclose($this->_fp); } // Returns all chunks of said type public function get_chunks($type) { if ($this->_chunks[$type] === null) return null; $chunks = array (); foreach ($this->_chunks[$type] as $chunk) { if ($chunk['size'] > 0) { fseek($this->_fp, $chunk['offset'], SEEK_SET); $chunks[] = fread($this->_fp, $chunk['size']); } else { $chunks[] = ''; } } return $chunks; } } 

Вы можете использовать его как таковой, чтобы извлечь желаемый фрагмент tEXt как таковой:

 $file = '18201010338AM16390621000846.png'; $png = new PNG_Reader($file); $rawTextData = $png->get_chunks('tEXt'); $metadata = array(); foreach($rawTextData as $data) { $sections = explode("\0", $data); if($sections > 1) { $key = array_shift($sections); $metadata[$key] = implode("\0", $sections); } else { $metadata[] = $data; } } 
 <?php $fp = fopen('18201010338AM16390621000846.png', 'rb'); $sig = fread($fp, 8); if ($sig != "\x89PNG\x0d\x0a\x1a\x0a") { print "Not a PNG image"; fclose($fp); die(); } while (!feof($fp)) { $data = unpack('Nlength/a4type', fread($fp, 8)); if ($data['type'] == 'IEND') break; if ($data['type'] == 'tEXt') { list($key, $val) = explode("\0", fread($fp, $data['length'])); echo "<h1>$key</h1>"; echo nl2br($val); fseek($fp, 4, SEEK_CUR); } else { fseek($fp, $data['length'] + 4, SEEK_CUR); } } fclose($fp); ?> 

Он предполагает в основном хорошо сформированный PNG-файл.