在PHP中,可以使用 fread()和 fwrite()来完成简单的读写文件。 unpack()和 pack()运算符用于提取二进制信息。
问题是,如何在不使用任何其他PHP扩展/库的情况下在PHP中读写PGM(P5)图像?
答案 0 :(得分: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';
答案 1 :(得分:0)
根据规格: Portable Gray Map
这看起来很简单。
你甚至不需要打包/解包,因为sscanf()
应该处理大部分的ASCII到整数翻译。
将PGM转换为BMP的C program可能会给你一些指示。
答案 2 :(得分:0)
我编写了一个简单的函数将图像资源转换为PGM(便携式灰度图),以便将其提供给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;
}
}
?>