Recherche sur le blog

samedi 21 juillet 2018

[JS] Afficher un PDF en image avec pdf.js

Il existe plusieurs méthodes en Java pour transformer un PDF (ou une partie seulement) en image côté serveur, afin de renvoyer le résultat au client, pour qu'il ne lui reste plus qu'à l'afficher. La première qui vient à l'esprit est Apache PDFBox. D'autres comme IcePDF ou JPedal font bien le job aussi, mais sont souvent payantes. De plus, le traitement peut évidemment vite devenir lourd pour le serveur si de nombreuses requêtes sont effectuées par plusieurs utilisateurs.

On peut imaginer laisser le client faire le boulot, en utilisant la librairie pdf.js, qui est sous licence Apache. Elle permet de visualiser des documents PDF dans une page web mais aussi de les transformer en image ce qui nous intéresse ici.

L'idée de l'exemple qui suit est de transformer une page donnée en image. Après ajout du script principal dans l'élément head, on va créer une fonction qui recevra plusieurs paramètres tels que les données du fichier PDF (sous forme de chaine encodée en Base64), le numéro de page à transformer, un ID pour la création du canvas, une valeur pour l'échelle du rendu, et l'identifiant de l'élément img qui recevra le résultat.
PDFJS.getDocument({data : atob(ao_pdfData)})
    .then(function(ao_pdf) 
{
 ao_pdf.getPage(ai_num).then(function(ao_page) 
 {
  var lo_canvas = document.createElement('canvas');
  lo_canvas.id = as_idd + '-page-' + ai_num;
  lo_canvas.className = 'f-canvas';

  var lo_context = lo_canvas.getContext('2d');
  var lo_viewport = ao_page.getViewport(af_scale2);
  lo_canvas.height = lo_viewport.height;
  lo_canvas.width = lo_viewport.width;
  
  var lo_renderContext = {
   canvasContext: lo_context,
   viewport: lo_viewport
  };

  ao_page.render(lo_renderContext).then(function()
  {
   $('#' + as_imageId)
     .attr("src", lo_canvas.toDataURL());
  });
 });
});
La fonction PDFJS.getDocument() reçoit en paramètre les données, décodées par la fonction JavaScript atob().

Une fois le document chargé, on va demander à récupérer la page dont le numéro est passé en paramètre. Une fois que cela est fait on exécute une fonction pour traiter les données de cette fameuse page. On crée un élément canvas temporaire, qu'on pourra stocker - ou pas - dans la page. On récupère aussi le contexte de dessin de ce canvas.

On récupère le viewport en indiquant l'échelle (ex : 1.5f). On définit ensuite la hauteur et la largeur du canvas avec les valeurs du viewport.

On crée ensuite un objet qui contiendra le contexte de dessin et le viewport. Ceux-ci seront passés à la fonction render() qui est une fonction de l'objet page. Lorsque le rendu est terminé, on peut récupérer la source de l'image depuis le canvas, grâce à la fonction toDataURL() de ce dernier.

vendredi 20 juillet 2018

[Système] Photos : Erreur système -2147219196

Si vous avez installé la mise à jour cumulative 17134.167 sur votre PC, il est possible que vous obteniez des erreurs en lançant l'application Photos, dont "Erreur du système de fichiers -2147219196" lorsque une photo est ouverte. D'autres applications peuvent également poser problème dont Skype ou même Calculatrice.

En lançant l'application Photos, vous pouvez également obtenir l'entrée suivante dans l'observateur d'événements : 

Nom de l’application défaillante Microsoft.Photos.exe, version : 2018.18051.17710.0, horodatage : 0x5b4c53ea
Nom du module défaillant : Windows.UI.Xaml.dll, version : 10.0.17134.81, horodatage : 0x4f4899f8
Code d’exception : 0xc000027b
Décalage d’erreur : 0x00000000006a4e02
ID du processus défaillant : 0x2b28
Heure de début de l’application défaillante : 0x01d4205da541b39a
Chemin d’accès de l’application défaillante : C:\Program Files\WindowsApps\Microsoft.Windows.Photos_2018.18051.17710.0_x64__8wekyb3d8bbwe\Microsoft.Photos.exe
Chemin d’accès du module défaillant: C:\Windows\System32\Windows.UI.Xaml.dll
ID de rapport : 08b2e8a9-e42d-46cf-9af2-24c466df7349
Nom complet du package défaillant : Microsoft.Windows.Photos_2018.18051.17710.0_x64__8wekyb3d8bbwe
ID de l’application relative au package défaillant : App

Visiblement réinstaller l'application ou la réinitialiser ne sert à rien : c'est en tout cas la première chose que j'ai voulu faire et ça n'a eu aucun effet. Utiliser l'utilitaire de résolution des problèmes est aussi inutile. De même que lancer la fameuse commande de déploiement via Powershell, ou l'utilitaire SFC pour vérifier s'il existe une corruption des fichiers système.

C'est en fait un problème de permissions : les droits du groupe Utilisateurs ont en fait été corrompues d'une manière ou d'une autre. Erreur dans la mise à jour ? Corruption complètement aléatoire et pas forcément liée ? Impossible d'en être réellement sûr.

Voici comment résoudre le problème :
  • Allez dans le dossier C:\Program Files\WindowsApps : Windows vous indiquera qu'il n'est pas possible d'accéder au dossier tant que vous n'aurez pas redéfini les droits d'accès. Cliquez sur le lien qu'il propose pour accéder à l'onglet Sécurité.
  • Dans cet onglet, cliquez sur Avancé. Vous devriez voir apparaitre la fenêtre suivante.

  • Changez le propriétaire en cliquant sur "Modifier", sélectionnez votre utilisateur, puis cochez la case "Remplacer le propriétaire des sous conteneurs et objets", ensuite choisissez Appliquer.
  • Supprimez les permissions du groupe Utilisateurs et appliquez. 
  • Ajoutez à nouveau les permissions pour le groupe Utilisateurs, cochez Lecture, écriture, exécution. Appliquez à nouveau.
Essayez d'ouvrir une image pour voir si vous obtenez toujours le message d'erreur. Si c'est le cas alors procédez aux étapes suivantes sinon fermez simplement en cliquant deux fois sur OK.
  • Fermez la fenêtre en cliquant sur OK. Faites de même une fois de retour à l'onglet de Sécurité.
  • Ouvrez une ligne de commande en mode administrateur.
  • Exécutez la commande "icacls "D:\Program Files\WindowsApps" /q /c /t /reset" sans prendre en compte les guillemets.
  • A la fin du traitement, il faut qu'il y ait 0 erreur si possible.
  • Retournez dans le dossier C:\Program Files\WindowsApps, faites un clic droit dans le dossier, puis choisissez Propriétés dans le menu contextuel.
  • Allez dans l'onglet Sécurité : vous devriez voir de nouveaux droits d'accès (notamment "Tous les packages d'applications"). Cliquez sur Avancé.
  • Changez le propriétaire par NT SERVICE\TrustedInstaller, cochez de nouveau la case pour remplacer le propriétaire des sous-objets, puis appliquez. 
  • Fermez les deux fenêtres avec OK.
  • Vous devriez avoir accès à l'application Photos et les autres applications qui posaient problème.