В PHP простой файл чтения и записи может быть выполнен с помощью fread () и fwrite () . Операторы unpack () и pack () используются для извлечения двоичной информации.
Вопрос в том, как я могу читать и писать изображение PGM (P5) в PHP без использования каких-либо дополнительных расширений PHP / библиотеки?
В зависимости от максимального значения для серого вам нужно будет использовать C*
для значений до 255 и n*
для больших значений.
Пример класса для чтения / записи всего пикселя из массива:
class PGM{ public $magicNumber = '', $pixelArray = array(), $width = 0, $height = 0, $grayMax = 0, $createdBy = ''; public function loadPGM($filename){ $this->grayMax = $this->height = $this->width = $this->magicNumber = 0; $this->pixelArray = array(); $fh = fopen($filename, 'rb'); while($line = fgets($fh)){ if(strpos($line, '#') === 0){ continue; } if(!$this->grayMax){ $arr = preg_split('/\s+/', trim($line)); if($arr && !$this->magicNumber){ $this->magicNumber = array_shift($arr); if($this->magicNumber != 'P5'){ throw new Exception("Unsupported PGM version"); } } if($arr && !$this->width) $this->width = array_shift($arr); if($arr && !$this->height) $this->height = array_shift($arr); if($arr && !$this->grayMax) $this->grayMax = array_shift($arr); }else{ $unpackMethod = ($this->grayMax > 255)?'n*':'C*'; foreach(unpack($unpackMethod, $line) as $pixel){ $this->pixelArray[] = $pixel; } } } fclose($fh); } public function savePGM($filename){ $fh = fopen($filename, 'wb'); $this->magicNumber = 'P5'; fwrite($fh, "{$this->magicNumber}\n"); if($this->createdBy){ fwrite($fh, "# {$this->createdBy}\n"); } fwrite($fh, "{$this->width} {$this->height}\n"); fwrite($fh, "{$this->grayMax}\n"); $packMethod = ($this->grayMax > 255)?'n*':'C*'; fwrite($fh, call_user_func_array('pack', array_merge(array($packMethod), $this->pixelArray))); fclose($fh); } }
Тестовый файл для вашего файла:
$pgm = new PGM; $pgm->loadPGM('a.pgm'); $pgm->createdBy = 'Created by IrfanView'; $pgm->savePGM('b.pgm'); echo (md5_file('a.pgm') == md5_file('b.pgm'))?'Images are identical':'Images are different';
Согласно спецификации: Portable Grey Map
Это выглядит довольно просто.
Вам даже не нужен пакет / распаковка, поскольку sscanf()
должен справляться с большей частью ASCII для целочисленного перевода.
Эта программа C, которая преобразует PGM в BMP, может дать вам несколько указателей.
Я написал простую функцию для преобразования ресурса изображения в PGM (переносимый graymap), чтобы передать его программе OCR. Он работает так же, как и остальные функции вывода изображения, и преобразует в оттенки серого для вас:
<?php function imagepgm($image, $filename = null) { $pgm = "P5 ".imagesx($image)." ".imagesy($image)." 255\n"; for($y = 0; $y < imagesy($image); $y++) { for($x = 0; $x < imagesx($image); $x++) { $colors = imagecolorsforindex($image, imagecolorat($image, $x, $y)); $pgm .= chr(0.3 * $colors["red"] + 0.59 * $colors["green"] + 0.11 * $colors["blue"]); } } if($filename != null) { $fp = fopen($filename, "w"); fwrite($fp, $pgm); fclose($fp); } else { return $pgm; } } ?>