FPDF - 无法打开 eps 文件?

FPDF - failing to open eps file?

我无法在 FPDF 中使用 EPS 文件(但在这里可以打开 EPS http://www.fpdf.org/en/script/script84.php)。我的代码有什么问题?

错误:

Fatal error: Uncaught Exception: FPDF error: File was saved with wrong Illustrator version: nato.eps in eps/fpdf/fpdf.php:271 Stack trace: #0 eps/fpdf_eps.php(42): FPDF->Error('File was saved ...') #1 eps/test.php(7): PDF_EPS->ImageEps('test.eps', 30, 20, 150, 0, 1) #2 {main} thrown in eps/fpdf/fpdf.php on line 271

test.php:

require('fpdf_eps.php');
$pdf=new PDF_EPS();
$pdf->AddPage();
$lnk = $pdf->AddLink();
$pdf->ImageEps('test.eps', 30, 20, 150, 0, $lnk);
$pdf->Output();

fpdf_eps.php:

/*
* Software: FPDF_EPS
* Version:  1.6
* Date:     2008-02-06
* Author:   Valentin Schmidt       */

require('fpdf/fpdf.php');

class PDF_EPS extends FPDF{

function ImageEps ($file, $x, $y, $w=0, $h=0, $link='', $useBoundingBox=true){

    $data = file_get_contents($file);
    if ($data===false) $this->Error('EPS file not found: '.$file);

    $regs = array();

    # EPS/AI compatibility check (only checks files created by Adobe Illustrator!)
    preg_match ('/%%Creator:([^\r\n]+)/', $data, $regs); # find Creator
    if (count($regs)>1){
        $version_str = trim($regs[1]); # e.g. "Adobe Illustrator(R) 8.0"
        if (strpos($version_str, 'Adobe Illustrator')!==false){
            $a = explode(' ', $version_str);
            $version = (float)array_pop($a);
            if ($version>=9)
                $this->Error('File was saved with wrong Illustrator version: '.$file);
                #return false; # wrong version, only 1.x, 3.x or 8.x are supported
        }#else
        #$this->Error('EPS wasn\'t created with Illustrator: '.$file);
    }

    # strip binary bytes in front of PS-header
    $start = strpos($data, '%!PS-Adobe');
    if ($start>0) $data = substr($data, $start);

    # find BoundingBox params
    preg_match ("/%%BoundingBox:([^\r\n]+)/", $data, $regs);
    if (count($regs)>1){
        list($x1,$y1,$x2,$y2) = explode(' ', trim($regs[1]));
    }
    else $this->Error('No BoundingBox found in EPS file: '.$file);

    $start = strpos($data, '%%EndSetup');
    if ($start===false) $start = strpos($data, '%%EndProlog');
    if ($start===false) $start = strpos($data, '%%BoundingBox');

    $data = substr($data, $start);

    $end = strpos($data, '%%PageTrailer');
    if ($end===false) $end = strpos($data, 'showpage');
    if ($end) $data = substr($data, 0, $end);

    # save the current graphic state
    $this->_out('q');

    $k = $this->k;

    if ($useBoundingBox){
        $dx = $x*$k-$x1;
        $dy = $y*$k-$y1;
    }else{
        $dx = $x*$k;
        $dy = $y*$k;
    }

    # translate
    $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', 1,0,0,1,$dx,$dy+($this->hPt - 2*$y*$k - ($y2-$y1))));

    if ($w>0){
        $scale_x = $w/(($x2-$x1)/$k);
        if ($h>0){
            $scale_y = $h/(($y2-$y1)/$k);
        }else{
            $scale_y = $scale_x;
            $h = ($y2-$y1)/$k * $scale_y;
        }
    }else{
        if ($h>0){
            $scale_y = $h/(($y2-$y1)/$k);
            $scale_x = $scale_y;
            $w = ($x2-$x1)/$k * $scale_x;
        }else{
            $w = ($x2-$x1)/$k;
            $h = ($y2-$y1)/$k;
        }
    }

    # scale
    if (isset($scale_x))
        $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', $scale_x,0,0,$scale_y, $x1*(1-$scale_x), $y2*(1-$scale_y)));

    # handle pc/unix/mac line endings
    $lines = preg_split ("/\r\n|[\r\n]/", $data);

    $u = 0;
    $cnt = count($lines);
    for ($i=0;$i<$cnt;$i++){
        $line = $lines[$i];
        if ($line=='' || $line[0]=='%') continue;

        $len = strlen($line);

        $chunks = explode(' ', $line);
        $cmd = array_pop($chunks);

        # RGB
        if ($cmd=='Xa'||$cmd=='XA'){
            $b = array_pop($chunks); $g = array_pop($chunks); $r = array_pop($chunks);
            $this->_out("$r $g $b ". ($cmd=='Xa'?'rg':'RG') ); #substr($line, 0, -2).'rg' -> in EPS (AI8): c m y k r g b rg!
            continue;
        }

        switch ($cmd){
            case 'm':
            case 'l':
            case 'v':
            case 'y':
            case 'c':

            case 'k':
            case 'K':
            case 'g':
            case 'G':

            case 's':
            case 'S':

            case 'J':
            case 'j':
            case 'w':
            case 'M':
            case 'd' :

            case 'n' :
            case 'v' :
                $this->_out($line);
                break;

            case 'x': # custom fill color
                list($c,$m,$y,$k) = $chunks;
                $this->_out("$c $m $y $k k");
                break;

            case 'X': # custom stroke color
                list($c,$m,$y,$k) = $chunks;
                $this->_out("$c $m $y $k K");
                break;

            case 'Y':
            case 'N':
            case 'V':
            case 'L':
            case 'C':
                $line[$len-1] = strtolower($cmd);
                $this->_out($line);
                break;

            case 'b':
            case 'B':
                $this->_out($cmd . '*');
                break;

            case 'f':
            case 'F':
                if ($u>0){
                    $isU = false;
                    $max = min($i+5,$cnt);
                    for ($j=$i+1;$j<$max;$j++)
                        $isU = ($isU || ($lines[$j]=='U' || $lines[$j]=='*U'));
                    if ($isU) $this->_out("f*");
                }else
                    $this->_out("f*");
                break;

            case '*u':
                $u++;
                break;

            case '*U':
                $u--;
                break;

            #default: echo "$cmd<br>"; #just for debugging
        }

    }

    # restore previous graphic state
    $this->_out('Q');
    if ($link)
        $this->Link($x,$y,$w,$h,$link);

    return true;
}

}# END CLASS

我认为问题在于您将专门处理由 Adob​​e Illustrator 版本 9 创建的 EPS 文件的脚本与可以处理一般 EPS 文件的脚本混淆了。

EPS 代表 Encapsulated PostScript,PostScript 是一种编程语言。所以 EPS 文件中的是 PostScript 程序。

现在机器生成的 PostScript,例如 Adob​​e Illustrator 生成的,当然总是相同的通用格式,并且可以(如此处)编写一些可以以有限方式处理其内容的代码。但是,不同的应用程序生成的程序会有所不同,可能非常不同。

能够读取一般 EPS(或 PostScript 文件)的唯一方法是使用完整的 PostScript 解释器,例如 Ghostscript。

您上面的脚本能够读取特定版本的 Adob​​e Illustrator 生成的 EPS 的标记内容一些 并从中渲染 PDF 文件,它是不是通用的 PostScript 解释器,因此不能解释任意 EPS 文件。作者在您问题中链接到的页面中说了很多。

Only vector drawing is supported, not text or bitmap

现在请注意,异常恰好出现在脚本的开头,它会检查 %%Creator 注释以查看 Illustrator 的版本是否正确。这就是你失败的地方,无疑是因为你的 EPS(你没有共享)不包含正确的评论。

简而言之,您不能使用此脚本来解释一般的 PostScript 或 EPS 程序。如果你想这样做,你需要像 Ghostscript 或 Adob​​e Acrobat Distiller 这样的东西。