我如何从PHP读取PNG元数据?
这是我迄今为止:
<?php $file = "18201010338AM16390621000846.png"; $test = file_get_contents($file, FILE_BINARY); echo str_replace("\n","<br>",$test); ?>
输出是什么我想要的,但我真的只需要3-7行(包括)。 这就是现在的输出: http : 我试图从“PunkBuster Screenshot(±)AAO Bridge Crossing”到“结果:w = 394 X h = 196 sample = 2”中获取数据。 我认为读取文件相当直接,并将每行存储在一个数组中,line [0]需要是“PunkBuster Screenshot(±)AAO Bridge Crossing”等等。 所有这些线都可能发生变化,所以我不能只search有限的东西。
我已经尝试了几天,并没有帮助我很穷的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文件。