Comment déterminer l’étendue (en octets) de la page 1 dans un fichier PDF linéarisé?

Je sais que je peux «linéariser» un fichier PDF, par exemple à l’aide du SDK Acrobat ou à l’aide d’outils commerciaux. Cela s’appelle également «optimisé pour le Web» et réorganise le PDF pour que la page 1 puisse se charger aussi rapidement que possible. Les PDF ainsi servis sont affichés plus rapidement, car le visualiseur de PDF n’a pas à attendre que tout le PDF soit téléchargé.

Mise à jour: d’ après la réponse ci-dessous, je réalise maintenant qu’un fichier PDF linéarisé n’est pas simplement réorganisé, mais contient également des métadonnées sur sa propre structure, sous la forme du “dictionnaire de linéarisation”.

J’ai une application dans laquelle je veux pré-extraire plusieurs fichiers PDF (résultats d’une requête), de manière à ce que l’utilisateur souhaite en voir un. Ce serait génial si mon client pouvait télécharger la page 1, et uniquement la page 1, pour chacun des résultats de recherche. Lorsque l’utilisateur sélectionne l’un d’entre eux, la page 1 peut être affichée instantanément et le rest peut être téléchargé en arrière-plan.

Je recherche une solution générale pouvant être utilisée côté serveur (Windows ou Linux) pour prétraiter mes PDF, afin de pouvoir stocker et servir la page 1 et le rest séparément. En réalité, tout ce que j’ai besoin de savoir, c’est où se trouve le dernier octet nécessaire dans le fichier PDF pour afficher correctement la page 1. Si je peux avoir ce numéro, tout le rest suit.

J’ai parcouru les spécifications ISO pour les PDF, mais le format de fichier semble trop complexe pour que je puisse simplement parsingr où se termine la page 1. D’autre part, les outils qui linéarisent les fichiers PDF doivent presque certainement savoir où se termine la page 1.

Je ne m’intéresse pas aux complications liées à la dissortingbution de fichiers PDF aux clients. cette partie est déjà résolue puisque le client est une application, pas un navigateur, et que je contrôle tout.

Je ne pense pas non plus que cela m’aidera à scinder le PDF à l’aide d’outils tels que AP Split en un “page 1” PDF et un PDF complet. Si tel est le cas, je ne pourrai pas tromper le lecteur du client en lui faisant croire qu’il s’agit d’un seul fichier PDF. Un scintillement perceptible se produira lorsque je remplace le PDF “page 1” par le PDF complet.

Toute aide ou pointeurs appréciés.

Solution (basée sur la réponse de Bobrovsky ci-dessous):

Un fichier PDF correctement linéarisé commence par une ligne d’en-tête (définie dans la section 7.5.2 de la spécification PDF) telle que “% PDF-1.7” suivie par une ligne de commentaire d’au moins quatre caractères binarys (définis par une valeur d’octet égale ou supérieure à 128) . Par exemple:

%PDF-1.7 %¤¤¤¤ 

Cet en-tête est immédiatement suivi du dictionnaire de linéarisation (défini à l’annexe F de la spécification PDF). Un exemple:

  43 0 obj <> endobj 

Dans cet exemple, la fin de la première page correspond à l’offset 5437. Cette structure de données est assez simple pour être analysée en utilisant à peu près n’importe quel langage. Le paramètre “43 0 obj” donne un identifiant pour ce dictionnaire (43) et un numéro de génération (toujours zéro pour les fichiers linéarisés). Le dictionnaire lui-même est entouré de <>, entre lesquels se trouvent des paires clé-valeur (les clés ont des barres obliques du type “/ E”).

Et voici une méthode C # qui trouve le nombre approprié en utilisant une expression rationnelle:

 public int GetPageOneLength(byte[] data) { // According to ISO PDF spec: "The linearization parameter dictionary shall be entirely contained within the first 1024 bytes of the PDF file" (p. 679) ssortingng preamble = new ssortingng(ASCIIEncoding.ASCII.GetChars(data, 0, 1024)); // Note that the binary section on line 2 of the header will be entirely converted to question martks ('?') var match = Regex.Match(preamble, @"<<\w*/Linearized.+/E\s+(?\d+).+>>"); if (!match.Success) throw new InvalidDataException("PDF does not have a proper linearization dictionary"); return int.Parse(match.Groups["offset"].Value); } 

Remarque Bobrovsky met en garde sur le fait qu’un fichier peut contenir le dictionnaire de linéarisation sans être correctement linéarisé (peut-être à cause d’une modification incrémentielle?). Dans mon cas, ce n’est pas un problème, je vais linéariser moi-même tous les PDF.

Dictionnaire de linéarisation devrait vous aider avec cela.

Le dictionnaire requirejs pour contenir le paramètre E qui est

Le décalage de la fin de la première page (la fin de la partie 6 dans l’exemple F.1) par rapport au début du fichier.

Veuillez noter que tous les fichiers avec un dictionnaire de linéarisation ne sont pas réellement linéarisés (générateurs brisés, modifications après linéarisation, etc.). Il est donc possible que vous ne puissiez pas utiliser l’approche décrite si vos fichiers ne sont pas correctement linéarisés.

Consultez la section F.2.2 Dictionnaire de parameters de linéarisation (partie 2) du document PDF Reference pour plus d’informations sur le dictionnaire de linéarisation.