IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

WinDev Discussion :

Codons nous même une fonction ImageRTFVersHTML ou comment afficher en HTML les images d'un champ RTF


Sujet :

WinDev

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 42
    Points : 26
    Points
    26
    Par défaut Codons nous même une fonction ImageRTFVersHTML ou comment afficher en HTML les images d'un champ RTF
    Bonjour,

    Cela fait quelques jours que je me penche sur la problématique des image RTF qui "disparaissent" à l'utilisation de la fonction RTFVersHTML de WinDev.
    Le code ci-dessous va vous permettre d'y arriver mais avec une sérieuse perte de qualité.
    L'idée de ce topic est de partager ce code avec vous afin de vous permetre de l'améliorer.
    Si on y arrive, on aura enfin une solution à ce problème (car je n'en ai trouvé aucune sur le net pour le moment)

    L'idée est de pouvoir encoder dans un champ RTF Windev un texte avec des image, et de pouvoir les afficher par après dans un champ HTML WebDev.
    Plus simplement, l'idée pourrais être juste de récupérer les image d'un champ RTF en PNG.

    La procédure est la suivante :
    1/ Récuperer la chaine RTF de l'image
    2/ Convertir cette chaine en image
    3/ En web, créer cette image sur le serveur et afficher le lien dans le champ HTML

    Voici le code pour y arriver :

    1/ On récupère les chaines RTF des images présentes dans le champ RTF (grâce la balise RTF "\pict") et on les stocke dans un tableau de chaines (gtabImageRTF)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    sRTF = SAI_IMG_RTF
     
    sDroiteRTF = sRTF
    nPosImage = Position(sRTF,"{\pict",1,SansCasse)
    TANTQUE nPosImage > 0
        sDroiteRTF = Droite(sDroiteRTF,Taille(sDroiteRTF) - nPosImage + 1)
        sImageRTF = ExtraitChaîne(sDroiteRTF,1,"}") + "}"
        Ajoute(gtabImageRTF,sImageRTF)
     
        nPosImage = Position(sDroiteRTF,"{\pict",2,SansCasse)
    FIN
    2/ On substitue dans le champ RTF les chaine image par des balises personnelles qui seront plus tard transformée en URL vers l'image

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SAI_IMG_RTF = ""
    nIndice = 1
    POUR CHAQUE sChaine DE gtabImageRTF
        sRTF = Remplace(sRTF,sChaine,"[[" + nIndice + "]]")
        nIndice++
    FIN
    RTFInsère(SAI_IMG_RTF,sRTF)
    A ce moment là il vous suffit d'enregistrer le contenu de ce champ en DB pour plus tard l'afficher dans le portail web de votre application.
    L'idée est d'utiliser deux tables, une qui contiendra le contenu du champ et une autre qui contiendra les chaines RTF associées à l'ID de la balise personnelle.

    3/ lors de l'affichage du contenu en web, on parcours les images liées et on les crée sur le serveur.
    C'est ici que ça se complique

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    // On récupère la hauteur et la largeur dans les propriété RTF de l'image
    sHeader est une chaîne
    nPosInfo,nPosFinInfo est un entier
    sHauteurHexa, sLargeurHexa sont des chaîne
    nHauteur, nLargeur sont des entiers
     
    sHeader         = ExtraitChaîne(gtabImageRTF[1],1)
    nPosInfo         = Position(sHeader,"\picw",1,SansCasse) + 5
    nPosFinInfo     = Position(sHeader,"\",nPosInfo,SansCasse)
    sLargeurHexa     = Milieu(sHeader,nPosInfo,nPosFinInfo - nPosInfo)
    nLargeur        = Val(sLargeurHexa) / 0n26.45323741007194
     
    sHeader         = ExtraitChaîne(gtabImageRTF[1],1)
    nPosInfo         = Position(sHeader,"\pich",1,SansCasse) + 5
    nPosFinInfo     = Position(sHeader,"\",nPosInfo,SansCasse)
    sHauteurHexa     = Milieu(sHeader,nPosInfo,nPosFinInfo - nPosInfo)
    nHauteur        = Val(sHauteurHexa) / 0n26.45323741007194
     
    Trace(sLargeurHexa,sHauteurHexa)
    Trace(nLargeur,nHauteur)
     
    // Pour convertir l'image on formate corectement la chaine pour en retirer les propriétés RTF
    sDroiteRTF = gtabImageRTF[1]
    nPosImage = Position(sDroiteRTF,RC,1)
    sDroiteRTF = Droite(sDroiteRTF,Taille(sDroiteRTF) - nPosImage)
    sImageRTF = ChaîneFormate(ExtraitChaîne(sDroiteRTF,1,"}"),ccSansEspace)
     
    // On converti la chaine de l'Hexadecimal vers le buffer
    bufImage = HexaVersBuffer(sImageRTF)
     
    // On charge l'image dans une variable image pour pouvoir la retravailler
    iImage = dChargeImage(bufImage,imgConvertir)
     
    // On lui redonne sa taille initiale 
    dRedimensionne(iImage,nLargeur,nHauteur,drEtiré)
     
    // On sauve l'image sur le serveur web
    dSauveImagePNG(iImage,fRepWeb() + "\Images\test.png")
    Et voila ! Il ne vous suffit plus que de remplacer vos balises personnelles par les URL des images générées

    ... si vous avez lu attentivement vous avez remarqué que j'ai dû redimensionner l'image... pourquoi ?
    Et bien c'est là tout le problème !

    Voici à quoi ressemble une chaine d'image RTF (le début en tout cas)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    {\pict\wmetafile8\picw873\pich343\picwgoal495\pichgoal194 
    010009000003c20200000000ac0200000000050000000b0200000000050000000c0257016903ac
    020000430f2000cc0000000d00210000000000570169030000000028000000210000000d000000
    010018000000000014050000c40e0000c40e00000000000000000000ffffffffffffffffffffff
     
    ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
    La première partie () jusqu'à "pichgoal194") contient des information décrivant l'image.
    La suite est la chaine hexadécimale représentant l'image telle quelle.
    Si on exécute mon code tel quel sans redimensionner l'image, celle-ci aura une taille fixe, toujorus la même (genre 640*480, je ne me rappelle plus)
    C'est pour cela que la hauteur et la largeur de l'image sont renseignée dans les propriété sous les balises "picw" et "pich".

    Premier problème, dans ce que j'ai pu lire on dit que la taille est donnée en pixel mais dans le champ RTF Windev cette taille est beaucoup trop grande ! Si on utilise tel quel cette valeur votre image sera surdimensionnée. Première question, est-ce que quelqu’un à une idée de ce que représente cette valeur dans ce cas ?
    Sans aucune piste, j'ai simplement comparé ce nombre avec la taille réelle de l'image pour en sortir un coefficient.
    Je suis tombé sur 0n26.45323741007194 et en divisant par cette valeur on tombe sur la bonne taille.
    (que représente ce coefficient ? Je n'en ai aucune idée).

    Le soucis.... c'est que l'image ne sort pas indemne de cette transformation et sort partiellement dégradée, voir très dégradée dans le cas d'une grande image.

    Est-ce parce que mon coefficient est mauvais ? Est-ce la conversion Hexadecimale qui perd de l'information ? Est-ce parce que j'ai mal récupéré la chaine RTF de l'image ?
    Je compte sur vous pour m'aider à trouver la pièce manquante...

    Merci !

  2. #2
    Expert éminent
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    3 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 3 937
    Points : 9 249
    Points
    9 249
    Par défaut
    hello,
    voici quelques infos supplémentaires concernant les images wmf dans les champs RTF :
    RTF Picture Destination

    The minimum control words used to define a picture or image in an RTF document are "{\pict\wmetafile8\picw[N]\pich[N]\picwgoal[N]\pichgoal[N] [BYTES]}" where ...

    \pict - The starting picture or image tag
    \wmetafile[N] - Indicates that the image type is a Windows Metafile. [N] = 8 specifies that the metafile's axes can be sized independently.
    \picw[N] and \pich[N] - Define the size of the image, where[N] is in units of hundreths of millimeters (0.01)mm.
    \picwgoal[N] and \pichgoal[N] - Define the target size of the image, where [N] is in units of twips.
    [BYTES] - The HEX representation of the image.
    The horizontal and vertical resolutions at which the ExRichTextBox is being displayed are necessary for the above calculations to be made. These values are obtained in the default constructor of ExRichTextBox from a Graphics object and stored as xDpi and yDpi respectively. (On most systems, both these values are 96 Dpi, but why assume?)

    The metafile's dimensions in (0.01)mm are calculated using the following conversion units and formula. (The example below explains how to find the current width, but the same formula is used to find the height by substituting height and vertical resolution for width and horizontal resolution respectively.)

    1 Inch = 2.54 cm
    1 Inch = 25.4 mm
    1 Inch = 2540 (0.01)mm

    [N] = current width of the metafile in hundredths of millimeters (0.01mm)
    = Image Width in Inches * Number of (0.01mm) per inch
    = (Image Width in Pixels / Graphics Context's Horizontal Resolution) * 2540
    = (Image Width in Pixels / Graphics.DpiX) * 2540
    Collapse | Copy Code
    ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      // Calculate the current width of the image in (0.01)mm
      int picw = (int)Math.Round((_image.Width / xDpi) * HMM_PER_INCH);
     
      // Calculate the current height of the image in (0.01)mm
      int pich = (int)Math.Round((_image.Height / yDpi) * HMM_PER_INCH);
    ...
    Twips are screen-independent units used to ensure that the placement and proportion of screen elements in a screen application are the same on all display systems. The metafile's target dimensions in twips are calculated using the following conversion units and formula. (The example below explains how to find the target width, but the same formula is used to find the height by substituting height and vertical resolution for width and horizontal resolution respectively.)

    1 Twip = 1/20 Point
    1 Point = 1/72 Inch
    1 Twip = 1/1440 Inch

    [N] = target width of the metafile in twips
    = Image Width in Inches * Number of twips per inch
    = (Image Width in Pixels / Graphics Context's Horizontal Resolution) * 1440
    = (Image Width in Pixels / Graphics.DpiX) * 1440
    Collapse | Copy Code
    ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      // Calculate the target width of the image in twips
      int picwgoal = (int)Math.Round((_image.Width / xDpi) * TWIPS_PER_INCH);
     
      // Calculate the target height of the image in twips
      int pichgoal = (int)Math.Round((_image.Height / yDpi) * TWIPS_PER_INCH);
    ...
    After the RTF representation of the image is created the image is inserted into the RTF document similarly to how text is inserted. If any text is selected, the image replaces the selected text. If no text is selected, the image is inserted at the location of the caret.
    par exemple si picw vaut 4740 c'est que la taille de l'image en largeur est de 4,74 cm

    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

Discussions similaires

  1. Réponses: 1
    Dernier message: 14/08/2009, 13h19
  2. [MySQL] Fonction de Recherche comment afficher?
    Par silver59 dans le forum PHP & Base de données
    Réponses: 12
    Dernier message: 28/06/2007, 18h12
  3. [MySQL] comment stocker puis recuper les images dans une base de donnée
    Par essono dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 23/11/2006, 00h07
  4. Réponses: 1
    Dernier message: 22/11/2006, 23h49
  5. Appeler une fonction d'un script PHP depuis HTML
    Par barthelv dans le forum Langage
    Réponses: 31
    Dernier message: 27/12/2005, 12h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo