[Résolu][Calc] Export image "intégré en base 64

Discussions et questions sur tout ce qui concerne la programmation tous langages et tous modules confondus.

Modérateur : Vilains modOOs

Règles du forum
:alerte: Balisage obligatoire dans cette section !
Aidez-nous à vous aider au mieux en balisant correctement votre question : reportez-vous sur les règles de cette section avant de poster !
jfjam22150
Fraîchement OOthentifié
Messages : 9
Inscription : 20 nov. 2020 06:43

[Résolu][Calc] Export image "intégré en base 64

Message par jfjam22150 »

Bonjour à tous.
J'aurai besoin d'un petit coup de main pour réaliser une partie d'un projet.
Je cherche à exporter/convertir une objet image préalablement inséré dans une feuille de calcul en base64 pour intégration à du xml.
Pour trouver l'image, pas de problème étant donné qu'elle est insérée par macro et que pendant cette insertion, elle est obligatoirement nommée.
Pour la conversion d'une image (au format png) en Base64, pas de problème non plus grâce à ce thread : https://forum-test.openoffice.org/en/fo ... 46#p169263

Mon problème est que quand je regarder le contenu de MonobjetImage.Bitmap.DIB grâce à xray je n'obtiens pas du tout la même chose que lorsque j'accède directement à la suite de Bytes à partir du fichier png. De plus, l'accès à cette propriété est très long.

Est-il possible d'accéder directement au bytes correspondant à l'image png (celle présente dans la feuille et non celle qui a servi à l'insertion) ?
Est-ce que quelqu'un aurait une idée pour effectuer cette conversion.

Merci d'avance pour vos réponses
Dernière modification par jfjam22150 le 21 nov. 2020 16:51, modifié 1 fois.
Ubuntu 20.04 - Libreoffice 7.0.3.1
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 25181
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Calc] Export image "intégré en base 64

Message par Dude »

Salut,

Pas besoin de macro, tu fais un export de ta feuille en XHTML.
Tes images seront encodées dans ce format.

.
jfjam22150
Fraîchement OOthentifié
Messages : 9
Inscription : 20 nov. 2020 06:43

Re: [Calc] Export image "intégré en base 64

Message par jfjam22150 »

Bonjour Dude et merci pour ta réponse.

Le problème c'est que je veux "insérer" ce code base 64 dans un fichier xml plus gros (contenant d'autres informations) donc à moins de génerer le xhtml et de le redécouper...

De plus comme il peut y avoir plusieurs images, ça risque d'être compliqué.

Cordialement
Jfjam22150
Ubuntu 20.04 - Libreoffice 7.0.3.1
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 25181
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Calc] Export image "intégré en base 64

Message par Dude »

Un .xhtml est comme un .xml, un simple format texte.
Si tu insères, il te faudra de toute façon passer par des fonctions d'entrée/sortie.
Donc, tu peux très bien lire le fichier généré et extraire le contenu avec la balise
<img [...] src="data:image/*;base64
jfjam22150 a écrit :De plus comme il peut y avoir plusieurs images, ça risque d'être compliqué.
Pourquoi ? Les images embarquées dans un ODS n'ont de toute façon pas de nom explicite.
jfjam22150
Fraîchement OOthentifié
Messages : 9
Inscription : 20 nov. 2020 06:43

Re: [Calc] Export image "intégré en base 64

Message par jfjam22150 »

Bonsoir.
Mon idée est de ne pas avoir à "créer" de nouveau fichier sur le disque" car cette macro est destinée à des utilisateurs pour qui tout cela doit être transparent, non invasif et travaillant sur de multiples OS...

Grâce à ce suprême de code : https://forum.openoffice.org/fr/forum/f ... ml#p162973
j'arrive maintenant à accéder à mon image et à la convertir en base 64 mais c'est en ayant découvert le "numéro de série" du fichier en utilisant xray préalablement.
Je m'explique quand je vais chercher dans OFichier.DocumentStorage.GetByName("Pictures").ElementNames je trouve bien la liste "incompréhensible" des mes fichiers suivi de l'extension.

De là en faisant un raccourcis dans le suprême de code, j'arrive à ce que je veux.

maintenant le grande question est : ce nom de fichier incompréhensible a-t-il une signification ? il a l'air écrit en hexadécimal mais je ne vois pas plus
Est-il possible de retrouver ce "numéro de série" à partir de l'objet image en lui même ?

Cette donnée est importante pour moi, car le nom (name) de l'image permet de déterminer sa position dans le xml par la suite et pour l'instant, je suis pas en mesure de faire le lien entre les numéros de série cités ci-dessus et mon élément image nommé.

En espérant avoir été suffisamment clair pour trouver encore un peu d'aide.

NB : j'ai regardé au niveau de GraphicURL mais je n'ai rien trouvé de probant (sinon je ne vous aurai pas encore ennuyé)

prenez soin de vous
jfjam22150
Ubuntu 20.04 - Libreoffice 7.0.3.1
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 25181
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Calc] Export image "intégré en base 64

Message par Dude »

jfjam22150 a écrit :En espérant avoir été suffisamment clair pour trouver encore un peu d'aide.
Non pas vraiment, joins donc un document ODS avec la macro.
Avatar de l’utilisateur
Jurassic Pork
PassiOOnné
PassiOOnné
Messages : 629
Inscription : 09 août 2017 22:15

Re: [Calc] Export image "intégré en base 64

Message par Jurassic Pork »

hello,
le souci c'est que depuis LibreOffice 6.1 la propriété GraphicUrl qui donnait le nom de l'image dans le répertoire Pictures du fichier odt n'est plus disponible (toujours disponible dans openOffice).
Je ne sais pas s'il y a une autre propriété qui permet d'avoir cette information. En tout cas dans le fichier content.xml du fichier odt il y a l'information. Donc une solution consiste à lire ce fichier.

Code : Tout sélectionner

<draw:frame draw:style-name="fr1" draw:name="Image1" text:anchor-type="char" svg:width="0.974cm" svg:height="0.974cm" draw:z-index="0"><draw:image xlink:href="Pictures/100000000000002E0000002EB960DEB05B3873E1.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" loext:mime-type="image/jpeg"/></draw:frame>
La solution proposée par Dude concernant l'export en xhtml est intéressante car dans ce cas le xml image est formaté avec toutes les propriétés et est en format base64..

Ami calmant, J.P
LibreOffice 7.6.2.1 et OpenOffice 4.1.15 sous windows 11
LibreOffice 24.2.0 et OpenOffice 4.1.15 sous Ubuntu 20.04
jfjam22150
Fraîchement OOthentifié
Messages : 9
Inscription : 20 nov. 2020 06:43

Re: [Calc] Export image "intégré en base 64

Message par jfjam22150 »

Bonjour.
Voici l'exemple demandé par Dude.

En fait il s'agit d'un générateur de questions pouvant optionnellement contenir une image.
Pour insérer une image, il suffit de sélectionner la cellule de la colonne C et de cliquer sur "Insérer image". Ça marche ...

Comme je l'ai dit, le but est, une fois que l'utilisateur a saisi toutes ses questions et insérer toutes ses images, de "générer" un fichier xml du type :

Code : Tout sélectionner

<question>
  <identifiant> id1  </identifiant>
  <intitulé> Question fictive  </intitulé>
  <image> le base 64  </image>
</quetion>
ne prenez pas ce modèle xml pour argent comptant, c'est juste pour que vous compreniez l'idée.
La génération de tout cela est "facile" sauf pour l'histoire de mon image.
Le problème est qu'il faut absolument que l'image soit au bon endroit dans le xml, sinon cela risquerait de rendre les utilisateurs mécontents ;)

@Jurassic Pork : est-il possible d'accéder au contenu du fichier content.xml sans dézipper le fichier ?

Merci d'avance pour vos contributions
jfjam22150
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
Ubuntu 20.04 - Libreoffice 7.0.3.1
Avatar de l’utilisateur
Jurassic Pork
PassiOOnné
PassiOOnné
Messages : 629
Inscription : 09 août 2017 22:15

Re: [Calc] Export image "intégré en base 64

Message par Jurassic Pork »

oui c'est possible .
voici un exemple avec ton fichier et qui en plus va utiliser le sax parser de libreoffice pour explorer le xml. Cela est un peu complexe car cela se fait par événements. Mais en finalité on aboutit à ce que tu recherches c'est à dire la correspondance entre le nom de l'image et le fichier image contenu dans le Pictures de l'ods :

Code : Tout sélectionner

Dim TabImage As New Collection
Dim oNomImage 

 Type Img
   Nom As String
   Fichier As String
 End Type


Sub NomImageURL()
Dim OFic,OFlux,oSaxParser,oDocHandler,oInputSource
Dim Nom
oFic = ThisComponent.DocumentStorage.getByName("content.xml")
oFlux = oFic.InputStream
 ' Creation Sax parser Xml
                oSaxParser = createUnoService( "com.sun.star.xml.sax.Parser" )
                oDocHandler = CreateUnoListener( "DocHandler_", "com.sun.star.xml.sax.XDocumentHandler" )
                oSaxParser.setDocumentHandler( oDocHandler )
                   
                ' Creation de la structure cf.:
                ' http://api.libreoffice.org/common/ref/com/sun/star/xml/sax/InputSource.html

                oInputSource = createUnoStruct( "com.sun.star.xml.sax.InputSource" )
                oInputSource.aInputStream = oFlux
        
                ' Demarrer l'analyse syntaxique (parser) qui va lire le content.xml
                ' Les méthodes - cf. procedures DocHandler_ - seront appelées selon l'evenement correspondant
                oSaxParser.parseStream( oInputSource )
                For each m in TabImage
                print m.Nom & " : " & m.Fichier
                Next m
                oFlux.closeInput()
                        
                MsgBox "Fin du traitement" , 64, "Traitement"
      
End Sub     


Sub DocHandler_startDocument()
End Sub

Sub DocHandler_endDocument()
End Sub

Sub DocHandler_startElement( cName As String, oAttributes As com.sun.star.xml.sax.XAttributeList )
    Dim oFichierImage 
    Dim MonImage
    Dim UneImage as Img
    
    ' Si l'element est une image mémoriser son nom
    If cName = "draw:frame" Then
        oNomImage = oAttributes.getValueByName("draw:name")
        
    End If   
    If cName = "draw:image" Then
        oFichierImage = oAttributes.getValueByName("xlink:href")
        UneImage.Nom = oNomImage
        UneImage.Fichier = oFichierImage
        MonImage = UneImage
        TabImage.Add(MonImage,oNomImage) 
    End If   
    
End Sub ' DocHandler_startElement


Sub DocHandler_endElement( cName As String )
End Sub

Sub DocHandler_characters( cChars As String )
End Sub

Sub DocHandler_ignorableWhitespace( cWhitespace As String )
End Sub

Sub DocHandler_processingInstruction( cTarget As String, cData As String )
End Sub

Sub DocHandler_setDocumentLocator( oLocator As com.sun.star.xml.sax.XLocator )
End Sub

et voici le résultat :
ParseContentxml.PNG
Il doit y avoir plus simple !

Ami calmant, J.P
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibreOffice 7.6.2.1 et OpenOffice 4.1.15 sous windows 11
LibreOffice 24.2.0 et OpenOffice 4.1.15 sous Ubuntu 20.04
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 25181
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Calc] Export image "intégré en base 64

Message par Dude »

Code : Tout sélectionner

REM  *****  BASIC  *****

Sub Add_image
	Dim myDoc as Object 'le classeur
	Dim myFeuille as Object 'la feuille contenant les questins
	Dim myPage as Object 'la partie graphique de la feuille
	Dim myImg as Object 'une image
	Dim gp as Object
	Dim positionImg as New com.sun.star.awt.Point
	Dim props(0) as  New com.sun.star.beans.PropertyValue
	Dim ImgInfo as Object
	Dim PropImg as Double
	Dim PropCell as Double
	Dim ImgSize as Object
	
	Dim IDcol as integer
	Dim IMGQcol as integer
	IDcol = 0 
	IMGQcol = 2

	
	myDoc = ThisComponent
	myFeuille = myDoc.Sheets.getByName("Questions")
	myPage = myFeuille.DrawPage
	selection = myDoc.CurrentSelection
	IDrow = selection.CellAddress.Row
	
	If selection.CellAddress.Column <> IMGQcol then
		MsgBox("Avant de pouvoir insérer une image, il faut sélection une cellule de la colonne C")
		Stop
	End If	
	If selection.CellAddress.Column = IMGQcol and myFeuille.getCellByPosition(IDcol,IDrow).String = "" then
		MsgBox("Pour insérer une image dans un question, il faut préalablement sélectionner la cellule de cette colonne se trouvant sur la même ligne que l'identifiant de la question")
		Stop
	End If
	sfa = createUnoService("com.sun.star.ui.dialogs.FilePicker")
	sfa.Title = "Sélection image"
	if sfa.execute() Then
		myFiles = sfa.Files
		
		'selection.setString(myFiles(0))
		gp = createUnoservice("com.sun.star.graphic.GraphicProvider")
		props(0).Name = "URL"
		props(0).Value = ConvertToURL(myFiles(0))
		myImg = myDoc.createInstance("com.sun.star.drawing.GraphicObjectShape")
		myImg.Graphic = gp.queryGraphic(props())
		myImg.Position = selection.Position
		
		myImg.Name = myFeuille.getCellByPosition(IDcol,selection.CellAddress.Row).String
	
		myPage.add(myImg)
	
		ImgInfo = myImg.Graphic
		ImgSize = ImgInfo.SizePixel

		PropImg = ImgSize.Width / ImgSize.Height
		PropCell = selection.Size.Width / selection.Size.Height

		if PropImg > PropCell then
			ImgSize.Width = selection.Size.Width
			ImgSize.Height = ImgSize.Width/PropImg
		else 
			ImgSize.Height = selection.Size.Height
			ImgSize.Width = ImgSize.Height*PropImg
		End if

		myImg.Size = ImgSize
	
		'resizeImage(myImg,selection)
		myImg.Anchor = myFeuille.getCellByPosition(selection.CellAddress.Column,selection.CellAddress.Row)
		myImg.ResizeWithCell=True
	End If
End Sub
La macro montre que tu nommes l'image au moment de son insertion.
Tu peux dans ce cas utiliser le service GraphicExportFilter.
Un export dans un répertoire temporaire au format SVG permettra de récupérer la chaîne en base64.
jfjam22150
Fraîchement OOthentifié
Messages : 9
Inscription : 20 nov. 2020 06:43

Re: [Calc] Export image "intégré en base 64

Message par jfjam22150 »

Bon
Merci Dude pour ton idée mais j'avoue que je n'aime pas trop l'idée des créations / effacement de fichiers, surtout que tout cela se fera sur l'ordi d'un utilisateur final qui ne sera pas à moi..

Merci à Jurassic Pork : ton idée est pour l'instant superbe et semble fonctionner. Par contre, pourquoi a-t-on besoin d'autant de définition de procédure vide ? je pense que cela vient de l'utilisation de sax parser. J'essaie de comprendre comment cela fonctionne mais j'avoue que j'ai un peu de mal.. Aurais-tu une doc à me recommander sur cette méthode de parsing ?

Le code de Jurassic Pork étant ce que je souhaitais, je passe ce fil en résolu

Cordialement
jfjam22150
Ubuntu 20.04 - Libreoffice 7.0.3.1
Avatar de l’utilisateur
Jurassic Pork
PassiOOnné
PassiOOnné
Messages : 629
Inscription : 09 août 2017 22:15

Re: [Calc] Export image "intégré en base 64

Message par Jurassic Pork »

jfjam22150 a écrit :Par contre, pourquoi a-t-on besoin d'autant de définition de procédure vide ? je pense que cela vient de l'utilisation de sax parser. J'essaie de comprendre comment cela fonctionne mais j'avoue que j'ai un peu de mal.. Aurais-tu une doc à me recommander sur cette méthode de parsing ?
heu non j'ai découvert cette méthode aujourd'hui. Moi personnellement j'aurais utilisé une macro en python parce qu'il y a des bibliothèques pour parser les xml (ex : lxml) . Pour le sax parser xml je ne sais pas si il faut déclarer toutes les procédures, j'ai pris le code sur un site web et j'ai modifié la partie de traitement de début d'élément (de noeud xml).

Ami calmant, J.P
LibreOffice 7.6.2.1 et OpenOffice 4.1.15 sous windows 11
LibreOffice 24.2.0 et OpenOffice 4.1.15 sous Ubuntu 20.04
jfjam22150
Fraîchement OOthentifié
Messages : 9
Inscription : 20 nov. 2020 06:43

Re: [Résolu][Calc] Export image "intégré en base 64

Message par jfjam22150 »

@jurassic Pork
Peux-tu mettre le lien du site web dont tu parles en lien stp ?
Ubuntu 20.04 - Libreoffice 7.0.3.1
Avatar de l’utilisateur
Jurassic Pork
PassiOOnné
PassiOOnné
Messages : 629
Inscription : 09 août 2017 22:15

Re: [Résolu][Calc] Export image "intégré en base 64

Message par Jurassic Pork »

c'est ici ou ici par exemple
LibreOffice 7.6.2.1 et OpenOffice 4.1.15 sous windows 11
LibreOffice 24.2.0 et OpenOffice 4.1.15 sous Ubuntu 20.04