如何从PHP读取PNG元数据? [英] How can I read PNG Metadata from PHP?

查看:47
本文介绍了如何从PHP读取PNG元数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我到目前为止所拥有的:

This is what I have so far:

<?php

$file = "18201010338AM16390621000846.png";

$test = file_get_contents($file, FILE_BINARY);

echo str_replace("\n","<br>",$test);

?>

输出是我想要的,但我实际上只需要3-7行(包括3-7行).现在的输出如下所示: http://silentnoobs.com/pbss/collector/test. php .我正在尝试将数据从"PunkBuster屏幕截图(±)AAO桥梁穿越"转换为结果:w = 394 X h = 196样本= 2".我认为通读文件并将每行存储在一个数组中是很直接的,line [0]必须是"PunkBuster屏幕截图(±)AAO Bridge Crossing",依此类推.所有这些行都可能发生变化,所以我不能只搜索有限的内容.

The output is sorta what I want, but I really only need lines 3-7 (inclusively). This is what the output looks like now: http://silentnoobs.com/pbss/collector/test.php. I am trying to get the data from "PunkBuster Screenshot (±) AAO Bridge Crossing" to "Resulting: w=394 X h=196 sample=2". I think it'd be fairly straight forward to read through the file, and store each line in an array, line[0] would need to be "PunkBuster Screenshot (±) AAO Bridge Crossing", and so on. All those lines are subject to change, so I can't just search for something finite.

我已经尝试了几天,对我不擅长php并没有多大帮助.

I've tried for a few days now, and it doesn't help much that I'm poor at php.

推荐答案

PNG文件格式定义将PNG文档拆分为多个数据块.因此,您必须将自己的方式导航到所需的块.

The PNG file format defines that a PNG document is split up into multiple chunks of data. You must therefore navigate your way to the chunk you desire.

要提取的数据似乎在tEXt块中定义.我编写了以下课程,让您可以从PNG文件中提取块.

The data you want to extract seem to be defined in a tEXt chunk. I've written the following class to allow you to extract chunks from PNG files.

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块:

You may use it as such to extract your desired tEXt chunk as such:

$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读取PNG元数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆