dongnaosuan5407
2018-04-17 11:11
浏览 108
已采纳

将带有ghostscript的PDF从stdin(字符串)转换为jpg到stdout

I'm trying to convert a multipage pdf to jpg with ghostscript in php. The command right now looks something like this:

gs -q -dBATCH -sDEVICE=jpeg -dNOPAUSE -dSAFER -dJPEGQ=100 -dGraphicsAlphaBits=4 -dTextAlphaBits=4 -r72 -sOutputFile=- some.pdf

What I want is to find a way to input the pdf as string wich looks something like this: '%PDF-1.4 %���� 1 0 obj <> endobj 2 0 obj <> endobj, etc.' and output all pages to stdout. Providing an actual pdf file to the command works pretty fine, but it returns a single page. If opting for file writing there is an option p%03d.jpg to get all the pages, but I need it to be dumped to temp/memory. From what I understand you need to use pipes to get this to work. I made something with proc_open() but without any success because I don't know how to pass the string to the pipe.

$args = [
    '-dBATCH',
    '-sDEVICE=jpeg',
    '-dNOPAUSE',
    '-dSAFER',
    '-dJPEGQ=100',
    '-dGraphicsAlphaBits=4',
    '-dTextAlphaBits=4',
    '-r72',
    '-sOutputFile=-',
    $path . '/some.pdf'// this shouold be passed as string stdin
];

$descr = [
    0 => ['pipe', 'r'],
    1 => ['pipe', 'w'],
    2 => ['pipe','w']
];
$pipes = array();
$args = implode(' ', $args);
$commd = "gs -q $args";

$process = proc_open($commd, $descr, $pipes);

$response = '';

if (is_resource($process)) {
    fputs($pipes[0], $pdf);
    fclose($pipes[0]);

    while ($f = fgets($pipes[1])) {
        $response .= $f;
    }

    fclose($pipes[1]);
    fclose($pipes[2]);
    proc_close($process);
}

echo '<img src="data:image/png;base64, ' . base64_encode($response) . '" />';

Update: Found the solution for the input. It'a a dash instead of the last argument representing the input file. The multipage output still remains an issue.

图片转代码服务由CSDN问答提供 功能建议

我正在尝试使用php中的ghostscript将多页pdf转换为jpg。 该命令现在看起来像这样:

  gs -q -dBATCH -sDEVICE = jpeg -dNOPAUSE -dSAFER -dJPEGQ = 100 -dGraphicsAlphaBits = 4 -dTextAlphaBits = 4 -r72  -sOutputFile =  -  some.pdf 
   
 
 

我想要的是找到一种方法来输入pdf字符串,如下所示:'%PDF-1.4% ����10 obj&lt;&gt; endobj 2 0 obj&lt;&gt; endobj,等等' 并将所有页面输出到stdout。 为命令提供一个实际的pdf文件非常好,但它返回一个页面。 如果选择文件写入,则有一个选项p%03d.jpg来获取所有页面,但是我需要将它转储到temp / memory。 根据我的理解,你需要使用管道来实现这一点。 我用proc_open()做了一些事但没有成功,因为我不知道如何将字符串传递给管道。

  $ args = [
'-dBATCH'  ,
'-sDEVICE = jpeg',
'-dNOPAUSE',
'-dSAFER',
'-dJPEGQ = 100',
'-dGraphicsAlphaBits = 4',
'-dTextAlphaBits = 4'  ,
'-r72',
'-sOutputFile =  - ',
 $ path。  '/some.pdf'//这个shouold作为字符串stdin传递
 
]; 
 
 $ descr = [
 0 =&gt;  ['pipe','r'],
 1 =&gt;  ['pipe','w'],
 2 =&gt;  ['pipe','w'] 
]; 
 $ pipes = array(); 
 $ args = implode('',$ args); 
 $ commd =“gs -q $ args”; \  n 
 $ process = proc_open($ commd,$ descr,$ pipes); 
 
 $ response =''; 
 
if(is_resource($ process)){
 fputs($ pipes [0],  $ pdf); 
 fclose($ pipes [0]); 
 
 while($ f = fgets($ pipes [1])){
 $ response。= $ f; 
} 
 
  fclose($ pipes [1]); 
 fclose($ pipes [2]); 
 proc_close($ process); 
} 
 
echo'&lt; img src =“data:image / png; base64,  '.base64_encode($ response)。'“/&gt;'; 
   
 
 

更新: 找出输入的解决方案。 它是一个破折号而不是代表输入文件的最后一个参数。 多页输出仍然是个问题。

  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • douqiao1413 2018-04-17 13:55
    已采纳

    You can't render a PDF file in memory using Ghostscript.

    Ghostscript only processes PDF files from disk. If you pipe the input from stdin all that happens is that Ghostscript creates a temporary file, stores the PDF in that, and then renders the temporary file. This is because PDF files inherently require the ability to seek randomly within the file.

    So in fact by sending the file via stdin you're just moving the creation of the temporary file to being done inside Ghostscript instead of doing it yourself. If you think you are somehow improving performance by doing this, you are mistaken.

    If you specify - (stdout) as the output file then all the output is sent to stdout. If there's more than one page, then both pages are sent to the output (what else could it do ?). Its up to you to figure out where each page ends and split it up.

    If you omit the -q and look at what gets sent to stdout (eg by redirecting it to a file) you will see that the usual Ghostscript boilerplate is sent at the start. If you further omit the -dNOPAUSE (note you will need to press 'return' for each page and you won't be prompted, so just hammer the key a bit) and then look at the output you will see that each page is separated by

    >>showpage, press <return> to continue<<
    

    So you can see that each page is sent, and its up to you to figure out where each JPEG ends.

    I'm not sure what else you were expecting to happen, given that you are sending multiple pages of output to stdout.

    评论
    解决 无用
    打赏 举报
查看更多回答(1条)

相关推荐 更多相似问题