Seite 1 von 1

[SOLVED] Bild aus Pipe mit Ghostscript benutzen

Verfasst: Mittwoch 8. Oktober 2008, 13:56
von bonaire
Hallo,


ich möchte für ein Programm eine Vorschau-Funktion für PDF-Dateien basteln. Dazu habe ich mir gedacht, Ghostscript zu nutzen, weil das von mir eigentlich vorgesehene Pil PDFs ja nur zu schreiben können scheint.
Jetzt habe ich dabei leider zwei Probleme.
Zum Einen schaffe ich es anscheinend nicht, den Befehl für Ghostscript richtig zusammen zu basteln, damit das PDF in ein PNG umgewandelt wird, ohne eine temporäre Datei nutzen zu müssen.
Zum Anderen würde ich gerne wissen, ob es möglich ist, das von Ghostscript erzeugte png in ein Pil-Objekt umzuwandeln, und wenn ja, wie ich das machen kann?
Vielleicht kennt jemand auch eine andere Möglichkeit, die nicht auf Ghostscript aufsetzt?


cu

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import wx
from PIL import Image
import subprocess
import sys

class imageActions():
    def __init__(self, file=""datei.pdf""):
        self.preview = self.getPreview(file)

    def getPreview(self, file):
        cmd = "gs-noX11 -q -sDEVICE=png16m -sOutputFile=%stdout " + file
        outfile = subprocess.call(cmd, shell=True)

        pil = Image.open(outfile)
        pil.thumbnail((600, 128))

        wxi = wx.EmptyImage(pil.size[0],pil.size[1])
        wxi.SetData(pil.convert("RGB").tostring())
        wxi.SetAlphaData(pil.convert("RGBA").tostring()[3::4])

        bmp = wx.BitmapFromImage(wxi)
        return bmp

Verfasst: Mittwoch 8. Oktober 2008, 15:14
von lunar
In der Doku steht, dass call nur den Exitcode zurückgibt, und das man subprocess besser mit einer Liste als Argument aufruft.

Code: Alles auswählen

cmd = ['gs-noX11', '-q', '-sDEVICE=png16m', '-sOutputFile=%stdout', file]
process = subprocess.Popen(cmd)
stdout, stderr = process.communicate()

pil = Image.open(StringIO(stdout))
pil.thumbnail((600, 128))

wxi = wx.EmptyImage(pil.size[0],pil.size[1])
wxi.SetData(pil.convert("RGB").tostring())
wxi.SetAlphaData(pil.convert("RGBA").tostring()[3::4])

bmp = wx.BitmapFromImage(wxi)
return bmp
Als zusätzlicher Import ist "from StringIO import StringIO" erforderlich.

Das Übliche noch zum Schluss: Bei der Namensgebung bitte PEP 8 einhalten.

Verfasst: Mittwoch 8. Oktober 2008, 15:43
von BlackJack
Das müsste aber eigentlich "hängen" bleiben, weil ``gs`` ohne `-dBATCH` am Ende in die Interpreterschleife geht und weitere Befehle abwartet.

Code: Alles auswählen

from StringIO import StringIO
from subprocess import Popen, PIPE
from PIL import Image


GHOSTSCRIPT = 'gs'


def get_preview(pdf_name, size):
    arguments = [GHOSTSCRIPT,
                 '-dQUIET',
                 '-dBATCH',
                 '-dNOPAUSE',
                 '-dTextAlphaBits=4',
                 '-dGraphicsAlphaBits=1',
                 '-dFirstPage=1',
                 '-dLastPage=1',
                 '-sDEVICE=ppmraw',
                 '-sOutputFile=%stdout%',
                 pdf_name]
    gs_process = Popen(arguments, stdout=PIPE)
    image_file = StringIO(gs_process.stdout.read())
    if gs_process.wait() != 0:
        raise Exception('Ghostscript error')
    image = Image.open(image_file)
    image.thumbnail(size, Image.BICUBIC)
    return image

Verfasst: Mittwoch 8. Oktober 2008, 15:44
von bonaire
Hallo,

und vielen Dank für die vielen Hinweise! Die Pipe funktioniert endlich: Das ist super. Allerdings stürzt mir am Punkt

Code: Alles auswählen

stdout, stderr = process.communicate()
die komplette Anwendung ab (Lässt sich nur per kill beenden).

Woran könnte das liegen?

cu

Verfasst: Mittwoch 8. Oktober 2008, 15:50
von bonaire
Danke,

funktioniert wunderprächtig! Tolle Sache :D

cu