[SOLVED] Bild aus Pipe mit Ghostscript benutzen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
bonaire
User
Beiträge: 13
Registriert: Mittwoch 27. August 2008, 12:27
Wohnort: Karlsruhe

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
Zuletzt geändert von bonaire am Mittwoch 8. Oktober 2008, 15:59, insgesamt 1-mal geändert.
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.
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
bonaire
User
Beiträge: 13
Registriert: Mittwoch 27. August 2008, 12:27
Wohnort: Karlsruhe

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
bonaire
User
Beiträge: 13
Registriert: Mittwoch 27. August 2008, 12:27
Wohnort: Karlsruhe

Danke,

funktioniert wunderprächtig! Tolle Sache :D

cu
Antworten