1

PHP では、 fread()fwrite( )を使用して、単純なファイルの読み取りと書き込みを行うことができます。unpack()およびpack()演算子は、バイナリ情報を抽出するために使用されます。

問題は、追加の PHP 拡張機能/ライブラリを使用せずに、PHP で PGM (P5) イメージを読み書きするにはどうすればよいかということです。

4

3 に答える 3

6

グレーの最大値に応じて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';
于 2011-12-10T11:48:19.823 に答える
0

仕様によると: Portable Gray Map

これはかなり単純に見えます。

sscanf()ASCII から整数への変換のほとんどに対処する必要があるため、pack/unpack も必要ありません。

PGM を BMP に変換するこのC プログラムから、いくつかのヒントが得られるかもしれません。

于 2011-12-07T06:11:44.303 に答える
0

OCR プログラムに供給するために、画像リソースを PGM (ポータブル グレーマップ) に変換する簡単な関数を作成しました。他の画像出力関数と同じように機能し、グレースケールに変換されます。

<?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;
        }
    }
?>
于 2011-12-13T10:35:00.733 に答える