Page 1 sur 1

[Résolu] [Impress] MàJ DocumentStorage après ajout d'image

Publié : 01 mai 2018 14:48
par Michel Saint-Briant

La modération vous a écrit: Titre modifié pour plus de clarté : veillez à éviter les anglicismes !

Bonjour,

j'ai réalisé une macro qui permet de convertir les pages d'un fichier de présentation Odp en autant de pages Html en utilisant un codage SVG qui permet une conservation rigoureusement exacte au pixel près des pages Impress (Par exemple tous les diaporamas du site h**p://etc-etc.fr sont en html/SVG réalisés à partir de présentations Impress grâce à cette macro). J'ai appelé ce projet SSS (SVG Slide Show).

Le résultat avec SSS est totalement différent de l'exportation Html de LibreOffice/OpenOffice qui ne fait que réaliser des images .jpg des pages du diaporama. SSS permet d'utiliser des liens, de réaliser des animations, de sélectionner des images ou du texte : les pages obtenues sont de véritables pages Html respectant au pixel près le rendu sous Impress.

Les principales difficultés ont été résolues, tout est maintenant presque terminé et je souhaiterais pouvoir diffuser mon travail qui pourrait, je pense, intéresser des utilisateurs de LibreOffice/OpenOffice désireux de réaliser un diaporama diffusable sur internet sans passer par la solution PDF ; il reste cependant un problème qui ne doit pas être insoluble mais qui me tient tête malgré toutes les recherches et les tentatives effectuées !

J'ai besoin de pouvoir accéder aux différents fichiers-images utilisés dans le diaporama pour les extraire ; à priori, rien de bien compliqué, il suffit de les chercher dans le DocumentStorage du document :

Code : Tout sélectionner

Dim Document As Object, Pictures As Object
Dim a As String, i As Integer
Document = ThisComponent
Pictures = Document.GetDocumentStorage().getByName("Pictures")
For i = 0 To UBound(Pictures.ElementNames)
	a = a & Pictures.ElementNames(i) & Chr(10)
Next
MsgBox a
Les images utilisées apparaissent alors en vrac sous cette forme :

Code : Tout sélectionner

10000200000000100000001028D3E9853668BCDE.gif
100006A20000018D0000018DB3B6DC61F342ADE9.svg
... etc...
La propriété GraphicURL de l'image utilisée dans un élément de la page est de la forme :

Code : Tout sélectionner

vnd.sun.star.GraphicObject:10000200000000100000001028D3E9853668BCDE
Dès lors, il ne reste qu'à identifier la bonne entrée dans la liste du DocumentStorage pour les "pictures" et on peut alors copier le fichier ...

Sauf que ... tout ceci n'est valable que si un enregistrement du document a été réalisé dans sa totalité au préalable !

En effet, si on modifie une page en ajoutant une image ou si on modifie des puces de texte en utilisant une puce graphique de type "carré" ou "flèche" ou si on modifie un fond de page ou d'élément en utilisant un nouveau bitmap ... etc ... alors les bitmaps ajoutés restent inconnus dans le DocumentStorage tant qu'un enregistrement complet du document n'a pas été réalisé.

Ceci impose, lorsqu'on veut faire un test SSS sur une page modifiée, de devoir tout enregistrer avant de pouvoir effectuer le test. Pour un document d'une centaine de pages, c'est un peu frustrant de devoir perdre quelques dizaines de secondes pour pouvoir effectuer un test de SSS sur une page alors que les images responsables sont visibles, donc ont été chargées et doivent donc bien exister quelque part dans le document... mais où ?

J'ai essayé des fonctions peu ou pas documentées et j'ai abouti au mieux à rien et au pire à des plantages : Document.StoreToStorage(), Document.SwitchToStorage etc ...

Quelle est la solution à ce problème qui permette de réaliser une mise à jour du Document.DocumentStorage pour la partie "Pictures" après l'ajout d'une nouvelle image sans devoir tout enregistrer ? Car cette solution doit bien exister !

Merci d'avance pour toute suggestion à ce sujet ...

Re: [Impress]Updater DocumentStorage après ajout d'une image

Publié : 02 mai 2018 07:04
par Hubert Lambert
Bonjour,

Tu peux peut-être essayer le service GraphicExportFilter.
Un exemple :

Code : Tout sélectionner

    doc = thiscomponent

    dim props(1) as new com.sun.star.beans.PropertyValue
    props(0).Name = "URL"
    props(1).Name = "MediaType"
    props(1).Value = "image/svg+xml"

    exporter = createUnoService("com.sun.star.drawing.GraphicExportFilter")
    drawpages = doc.DrawPages
    for n = 0 to drawpages.Count -1
        drawpage = drawpages(n)
        for m = 0 to drawpage.Count -1
            shape = drawpage(m)
            if shape.supportsService("com.sun.star.drawing.GraphicObjectShape") then
            	nom = replace(shape.GraphicURL, "vnd.sun.star.GraphicObject:", "")
                props(0).Value = convertToURL("chemin/vers/fichier/" & nom & ".svg")
                exporter.setSourceDocument(shape)
                exporter.filter(props())
            end if
        next m
    next n
    msgbox "Terminé"
Cordialement.

Re: [Impress]Updater DocumentStorage après ajout d'une image

Publié : 02 mai 2018 16:53
par Michel Saint-Briant
Bonjour Hubert et merci pour ta réponse rapide ; l'idée est effectivement bonne mais cela nécessite un transcodage des données reçues car le fichier obtenu est de la forme :

Code : Tout sélectionner

<xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="143mm" height="108mm" viewBox="0 0 14300 10800" version="1.1" xmlns="http://www.w3.org/2000/svg" stroke-width="28.222" stroke-linejoin="round" xml:space="preserve">
 <image x="0" y="0" width="14335" height="10752" xlink:href="data:image/png;base64,iVBORw0KG...
... (données écrites en Base64) ...
... goAAAANSUhEUg+zvNIyosokNZMp4vZnrf/P06KP09BQ/2mAAAAAElFTkSuQmCC"/>
</svg>
Techniquement c'est faisable mais traiter ainsi les centaines de photos d'un gros diaporama risque de ralentir pas mal la macro. Je retiens l'idée et je la testerai sur un gros fichier pour voir mais j'attends une idée encore plus géniale qui me permettrait un enregistrement direct. Mais c'est déjà une avancée qui prouve bien que des données sont accessibles sans le DocumentStorage. Merci encore.

Re: [Impress] MàJ DocumentStorage après ajout d'image

Publié : 02 mai 2018 17:50
par Hubert Lambert
La demande initiale visait à extraire les images non encore enregistrées, ce que le code proposé permet de faire.
Pour l'exemple, je proposais de les extraire directement au format svg mais, si cela ne convient pas, tu peux toujours les extraire au format jpg et appliquer le même traitement que tu appliquais aux images enregistrées...

Re: [Impress] MàJ DocumentStorage après ajout d'image

Publié : 03 mai 2018 08:12
par Michel Saint-Briant
Bonjour Hubert,

Super ! C'est exactement ce que je cherchais depuis pas mal de temps ; je connaissais bien drawing.GraphicExportFilter que j'utilise pour récupérer les parties "texte" en SVG, en revanche j'ignorais qu'on pouvait l'appliquer à une Shape pour en extraire l'image avec le MediaType "image/jpeg" ; je m'en veux de ne pas y avoir pensé !

Ca marche bien sur une Shape "image" avec une différence : l'image enregistrée est adaptée au format d'Impress, alors qu'avec une extraction depuis le DocumentStorage elle reste au format original ; ainsi une image JPEG de 2210 ko est-elle passée à 926 ko, elle est restée en 2560 x 1920 mais la résolution est passée de 72 ppp à 453 ppp, ce qui finalement est un plus car cela permettra de faire une réduction automatique. Je vais ensuite essayer sur des bitmaps de puces ; ça risque d'être un peu plus compliqué (Shape "text") ... j'ai d'autres choses à faire avant, je te tiens au courant.

Merci encore

Re: [Impress] MàJ DocumentStorage après ajout d'image

Publié : 03 mai 2018 17:08
par Hubert Lambert
Je ne sais pas si ça peut servir, mais le bout de code ci-dessous (enregistrement du dispatcher) exporte la diapositive courante dans un format svg quelque peu différent de celui généré par le service GraphicExportFilter :

Code : Tout sélectionner

frame = thiscomponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
dim args1(1) as new com.sun.star.beans.PropertyValue
args1(0).Name = "URL"
args1(0).Value = "file:///home/user/test-svg.svg"
args1(1).Name = "FilterName"
args1(1).Value = "impress_svg_Export"
dispatcher.executeDispatch(frame, ".uno:ExportTo", "", 0, args1())

Re: [Impress] MàJ DocumentStorage après ajout d'image

Publié : 03 mai 2018 17:26
par Michel Saint-Briant
Suite de ma réponse de ce matin :
Après divers tests, tout est OK. Pour les puces, j'utilise une petite routine qui crée un élément "Shape" sur la première page et qui affecte son GraphicURL de celui de la puce. J'exporte l'image avec son MimeType et j'efface la Shape créée pour la circonstance.

Code : Tout sélectionner

Sub ExporterImage(GraphicURL As String, NewURL As String)
Dim Page As Object, Shape As Object
Dim MimeType As String, Extension As String
Page = ThisComponent.Drawpages.getByIndex(0)
Shape = ThisComponent.createInstance("com.sun.star.drawing.GraphicObjectShape")
Shape.GraphicURL = GraphicURL
Page.Add(Shape)
MimeType = Shape.Graphic.MimeType
Extension = Right(MimeType, 3)
If Extension = "peg" Then Extension = "jpg"
If Extension = "iff" Then Extension = "tif"
Dim props(1) as new com.sun.star.beans.PropertyValue
props(0).Name = "URL"
props(1).Name = "MediaType"
props(1).Value = MimeType
Dim Exporter As Object
Exporter = createUnoService("com.sun.star.drawing.GraphicExportFilter")
props(0).Value = convertToURL(NewURL & "." & Extension)
Exporter.setSourceDocument(Shape)
Exporter.filter(props())
Page.remove(Shape)
End Sub
Tout est OK, j'oublie le DocumentStorage sur lequel je m'étais focalisé et dont je pensais qu'il était la seule solution. Celà dit, c'est quand même bizarre qu'aucune fonction ne permette de le mettre à jour après adjonction d'une image comme le fait un enregistrement complet !...

On peut donc considérer que le problème est résolu. Merci au forum et à Hubert en particulier.