Version imprimable du sujet

Cliquez ici pour voir ce sujet dans son format original

Forums MacBidouille _ La Programmation En Général _ pdf multipage vers png(s), en mode terminal, sous MacOSX

Écrit par : ekdmekdm 24 Feb 2019, 13:09

Bonjour à tous,

Je suis nouveau ici et et en même temps nouveau sous MacOSX.

Je développe une application (nativement sous GNU/Linux) et je l'ai portée sous Windows et tout dernièrement sous MacOSX (car je m'apperçois qu'il y a énormément d'utilisateurs sous ce système ... et que esthétiquement c'est très sympa !).

Pour info je développe en Python (la version 3.x), et l'application utilise entre autre PyQt5, Pillow et Numpy. Je l'ai portée sous MacOSX à l'aide de Py2app (pour la petite histoire les versions pour GNU/Linux et Windows ont été compilées avec PyInstaller, mais celui-ci m'a posé tellement de problèmes avec ma version de Mavericks virtualisée avec VirtualBox sous GNU/Linux que j'ai du me rabattre à Py2app).

L'application utilise en interne pdftoppm (une version portable de pdftoppm sous Windows, et une version installée sous GNU/Linux).
pdftoppm fait partie de Poppler qui peut être installé avec homebrew, mais je ne veux pas imposer l'installation de Poppler utilisant mon application sous MacOSX avec le terminal (pas mal d'utilisateur potentiels semblent complètement alergiques aux install utilisant le terminal).

En fait mon application, à un moment donné du processus, convertit un fichier pdf (de une à plusieurs pages) en images png. J'ai découvert sips dans MacOSX (qui peut convertir les pdf en images), ... mais je n'ai pas trouvé le moyen de convertir un pdf de plusieurs pages en autant d'images png. Voilà comment je convertis le png en image :

Code
sips -s dpiWidth 300 -s dpiHeight 300 -s format png fichier_pdf_source --out fichier_destination-1.png


Si le fichier pdf contient 2 pages, j'aimerais obtenir : fichier_destination-1.png et fichier_destination-2.png (comme on peut l'obtenir avec pdftoppm), je ne sais pas du tout si c'est possible avec sips, j'ai fait des recherches à ce sujet mais pour l'instant je n'ai rien trouvé de probant !
C'est dommage car l'avantage de sips est qu'il est installé nativement sous MacOSX.

N'ayant pas trouvé de version portable de pdftoppm (ou Poppler) sous MacOSX, ni un ImageMagick portable (en utilisant convert), je pense que la seule application qui me permette de convertir des pdf en png en ligne de commande sous MacOSX, c'est sips (je me trompe ?), mais il ne fait pas exactement ce que je veux ...

Quelqu'un sait-il si malgré tout il est possible de dire à sips ... si le fichier pdf comporte plusieurs pages, et bien tu dois le convertir en autant d'images png ?, autrement quelqu'un sait-il ici s'il existe quelque part une version portable (out of the box) de pdftoppm (ou Poppler) pour MacOSX ?, ou ImageMagick ... que je pourrais importer dans mon logiciel comme je le fais sous Windows ?

Pouvez-vous m'aider ?

Je vous remercie d'avance.

a+ wink.gif

Écrit par : KOENIG Yvan 24 Feb 2019, 15:25

Personnellement j'utilise ASObjC pour exécuter cette opération.


CODE
use AppleScript version "2.3.1"
use scripting additions
use framework "Foundation"
use framework "Quartz" -- required for PDF stuff

#===== Handlers

-- Supposed to create a new PDF file and a new TIFF for every page from the passed PDF file.
# Based upon a handler designed by Shane STANLEY

on splitPDF:thePath
set inNSURL to current application's |NSURL|'s fileURLWithPath:thePath

set thePDFDocument to current application's PDFDocument's alloc()'s initWithURL:inNSURL
# CAUTION. theList contain indexes of pages numbered starting from 1, but ASObjC number them starting from 0
set theCount to thePDFDocument's pageCount() as integer
repeat with i from 1 to theCount
set pathNSString to (current application's NSString's stringWithString:thePath)
set bareSString to current application's NSString's stringWithFormat_("%@%@", pathNSString's stringByDeletingPathExtension(), ("-page " & text -2 thru -1 of ((100 + i) as text)))

set newPDFPath to (bareSString's stringByAppendingPathExtension:"pdf")
set outNSURL to (current application's |NSURL|'s fileURLWithPath:newPDFPath)

set newTiffNSString to (bareSString's stringByAppendingPathExtension:"tiff")
set tiffPath to newTiffNSString as text

set thePDFPage to (thePDFDocument's pageAtIndex:(i - 1))
set newPDFDoc to current application's PDFDocument's alloc()'s init()
(newPDFDoc's insertPage:thePDFPage atIndex:0)
(newPDFDoc's writeToURL:outNSURL)

set theImage to (current application's NSImage's alloc()'s initWithContentsOfURL:outNSURL)
set theData to theImage's TIFFRepresentation()
-- make imagerep from data
set newRep to (current application's NSBitmapImageRep's imageRepWithData:theData)
set theData to (newRep's representationUsingType:(current application's NSTIFFFileType) |properties|:{NSTIFFCompressionNone:1})
set theResult to (theData's writeToFile:tiffPath atomically:true)
end repeat
end splitPDF:


#===== Caller

set thePath to POSIX path of (choose file with prompt "Choose a PDF file." of type {"PDF"})
its splitPDF:thePath

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 24 février 2019 15:25:32

Écrit par : audionuma 24 Feb 2019, 16:07

Il semble qu'il y tout ce qu'il faut dans automator, notamment une tâche "rendre comme images les pages de documents pdf".
Par contre, je n'ai aucune idée de la manière (si c'est possible) dont on peut interfacer cela avec du code Python. Notamment, je n'ai pas trouvé comment, une fois que l'on a créé un nouveau Processus automator, lui passer des paramètres (fichier pdf en entrée par exemple) par la ligne de commande.

Écrit par : KOENIG Yvan 24 Feb 2019, 17:58

Oops, je n'ai pas posté la bonne version.

Pour générer des Png il faut utiliser :



CODE
use AppleScript version "2.3.1"
use scripting additions
use framework "Foundation"
use framework "Quartz" -- required for PDF stuff

#===== Handlers

-- Supposed to create a new PDF file and a new PNG for every page from the passed PDF file.
# Based upon a handler designed by Shane STANLEY

on splitPDF:thePath
set inNSURL to current application's |NSURL|'s fileURLWithPath:thePath

set thePDFDocument to current application's PDFDocument's alloc()'s initWithURL:inNSURL
# CAUTION. theList contain indexes of pages numbered starting from 1, but ASObjC number them starting from 0
set theCount to thePDFDocument's pageCount() as integer

# Build three descriptors only once
set pathNSString to (current application's NSString's stringWithString:thePath)
set tempPDFPath to POSIX path of ((path to temporary items as text) & "temp_pmet.pdf")
set tempNSURL to (current application's |NSURL|'s fileURLWithPath:tempPDFPath)

repeat with i from 1 to theCount
set newPngNSString to current application's NSString's stringWithFormat_("%@%@.%@", pathNSString's stringByDeletingPathExtension(), ("-page " & text -2 thru -1 of ((100 + i) as text)), "png")
set pngPath to newPngNSString as text

set thePDFPage to (thePDFDocument's pageAtIndex:(i - 1))
set newPDFDoc to current application's PDFDocument's alloc()'s init()
(newPDFDoc's insertPage:thePDFPage atIndex:0)
(newPDFDoc's writeToURL:tempNSURL)

set theImage to (current application's NSImage's alloc()'s initWithContentsOfURL:tempNSURL)
set theData to theImage's TIFFRepresentation()
-- make imagerep from data
set newRep to (current application's NSBitmapImageRep's imageRepWithData:theData)
set theData to (newRep's representationUsingType:(current application's NSPNGFileType) |properties|:{NSTIFFCompressionNone:1})
set theResult to (theData's writeToFile:pngPath atomically:true)
end repeat
end splitPDF:


#===== Caller

set thePath to POSIX path of (choose file with prompt "Choose a PDF file." of type {"PDF"})
its splitPDF:thePath


Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 24 février 2019 17:58:09

Écrit par : KOENIG Yvan 28 Feb 2019, 16:54

Merci pour les balises.

Shane Stanley vient de me passer une version qui ajoute un arrière-plan blanc. Le code original, générait des fichiers transparents.

CODE

(*

split PDF into TIFF or PNG

*)

use AppleScript version "2.3.1"
use scripting additions
use framework "Foundation"
use framework "Quartz" -- required for PDF stuff
--global theData, newImage

my Germaine()

#===== Handlers

# Create a new TIFF/PNG for every page from the passed PDF file.
# Based upon a handler designed by Shane STANLEY

on splitPDF:thePath

set createTIFF to false # true would create TIFFs
if createTIFF then
set theExt to "tiff"
set NSBitmapImageFileType to a reference to 0
else
set theExt to "png"
set NSBitmapImageFileType to a reference to 4
end if

set inNSURL to current application's |NSURL|'s fileURLWithPath:thePath

set thePDFDocument to current application's PDFDocument's alloc()'s initWithURL:inNSURL
# CAUTION. theList contain indexes of pages numbered starting from 1, but ASObjC number them starting from 0

set theCount to thePDFDocument's pageCount() as integer

# Build this descriptor only once
set pathNSString to current application's NSString's stringWithString:thePath

repeat with i from 1 to theCount
set newTiffNSString to current application's NSString's stringWithFormat_("%@%@.%@", pathNSString's stringByDeletingPathExtension(), ("-page " & text -2 thru -1 of ((100 + i) as text)), theExt)
set tiffPath to newTiffNSString as text

set thePDFPage to (thePDFDocument's pageAtIndex:(i - 1))

set theData to thePDFPage's dataRepresentation()

set theImage to (current application's NSImage's alloc()'s initWithData:theData)

set {theWidth, theHeight} to (theImage's |size|() as list)

set newRep to (current application's NSBitmapImageRep's alloc()'s initWithBitmapDataPlanes:(missing value) pixelsWide:theWidth pixelsHigh:theHeight bitsPerSample:8 samplesPerPixel:4 hasAlpha:true isPlanar:false colorSpaceName:(current application's NSDeviceRGBColorSpace) bitmapFormat:(current application's NSAlphaFirstBitmapFormat) bytesPerRow:0 bitsPerPixel:32)

set theContext to current application's NSGraphicsContext's currentContext()
(current application's NSGraphicsContext's setCurrentContext:(current application's NSGraphicsContext's graphicsContextWithBitmapImageRep:newRep))
--set the active color to white
current application's NSColor's whiteColor()'s |set|()
-- fill the bitmapImageRep with white
current application's NSRectFill({origin:{x:0, y:0}, |size|:{width:theWidth, height:theHeight}})
-- draw from original to new
(theImage's drawInRect:{origin:{x:0, y:0}, |size|:{width:theWidth, height:theHeight}} fromRect:{origin:{x:0, y:0}, |size|:{width:theWidth, height:theHeight}} operation:(current application's NSCompositeSourceOver) fraction:1.0)
-- restore context
(current application's NSGraphicsContext's setCurrentContext:theContext)

set theData to (newRep's representationUsingType:NSBitmapImageFileType |properties|:{NSTIFFCompressionNone:1})
set theResult to (theData's writeToFile:tiffPath atomically:true)
end repeat
end splitPDF:


#===== Caller

on Germaine()
set thePath to POSIX path of (choose file with prompt "Choose a PDF file." of type {"PDF"})
its splitPDF:thePath
end Germaine


Yvan KOENIG (VALLAURIS, France) jeudi 28 février 2019 16:53:05

Propulsé par Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)