Nasıl PNG Meta PHP okuyabilir?

3 Cevap php

Bu ben bugüne kadar ne var:

<?php

$file = "18201010338AM16390621000846.png";

$test = file_get_contents($file, FILE_BINARY);

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

?>

Çıktı ne istiyorum sorta, ama ben gerçekten sadece 3-7 (kapsayıcılık) satır gerekir. Bu çıktı şimdi neye benzediğini: http://silentnoobs.com/pbss/collector/test.php. Ben ": w = 394 X h = 196 numune = 2 Ortaya çıkan" için "PunkBuster görüntüsü (±) AAO Köprü Geçişi" den veri almak için çalışıyorum. Ben dosyası aracılığıyla okumak ve [0] böylece "PunkBuster görüntüsü (±) AAO Köprü Geçişi" olması gerekir, ve olacak bir dizi, çizgi her satırı depolamak için oldukça yalındır olacağını düşünüyorum. Tüm bu hatlar değişebilir, bu yüzden sadece sonlu bir şey için arama yapamazsınız.

Ben şimdi bir kaç gün boyunca denedim, ve ben php kötü olduğumu çok yardımcı olmuyor.

3 Cevap

PNG file format, bir PNG belge birden çok veri parçalar halinde bölünmüş olduğunu tanımlar. Bu nedenle arzu yığın yol gitmek gerekir.

Ayıklamak istediğiniz verileri tEXt öbekte tanımlanmış gibi görünüyor. Ben PNG dosyalarından parçalar ayıklamak için izin aşağıdaki sınıf yazdık.

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;
    }
}

Sen gibi istediğiniz tEXt yığın ayıklamak için gibi kullanabilirsiniz:

$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);
?>

Bu temelde de oluşmuş PNG dosyası varsayar.