Comment transformer une image en une chaîne de caractères ?
Auteur
Stéphane Sibué
Date 30 mai 2007

Dans les applications actuelles, nous avons souvent besoin de manipuler des images, et les applications mobiles ne font pas exception à la règle. Il est possible de charger une image depuis un fichier (jpeg, gif, bmp, etc...) mais parfois, il peut être nécessaire de les placer directement dans un fichier xml ou dans un champ de base de données ou encore comme pièce jointe d'un courrier éléctronique.

La solution est le codage Base64

Le principe du codage Base 64 consiste à utiliser des caractères ASCII (caractères non accentués) pour coder tout type de données codé sur 8 bits. Les protocoles de courrier électronique ont été conçus pour transporter que des messages texte. Pour transporter d'autres formats il a bien fallu trouver un moyen. Le codage Base64 est alors utilisé. Il permet de transmettre n'importe quel document binaire sous la forme d'une suite de caractères imprimables. Le seul problème est que ce codage provoque une augmentation d'un tiers du volume des données transmises car le principe de codage Base64 consiste à utiliser 4 caractères pour coder un groupe de 3 octets, il faut donc 32 bits pour coder 24 bits (soit 1/3 de plus).

Le Compact Framework 2 sait convertir un tableau d'octets en une chaîne codée Base64

Pour effectuer cette conversion il suffit d'utiliser les services de la classe System.Convert. Cette classe possède la fonction ToBase64String qui fait le travail. Cette fonction prend en paramètre un tableau d'octets et retourne la chaîne Base64 correspondante, tout simplement.

Dim wBuffer() As Byte = {10, 20, 30, 60, 20, 255, 17, 0, 9, 15}
Dim s As String = System.Convert.ToBase64String(wBuffer)

Au final, la variable s contient la chaîne "ChQePBT/EQAJDw==" qui correspond à la conversion Base64 des octets 10,20,30,60,20,255,17,0,9,15

Pour convertir une image en Base64 il nous faut un tableau d'octets la représentant

Bon, on sait maintenant convertir un tableau d'octets en Base64. Par contre, lorsqu'on a un objet image, comment récupérer le tableau d'octets ? La réponse est dans le fait de pouvoir enregistrer une image directement en mémoire comme si on le faisait avec un fichier.

Pour réaliser cette opération, il faut utiliser la classe System.IO.MemoryStream (très pratique). Il suffit d'enregistrer l'image via ce stream particulier dans le format qui nous convient. Pour enregistrer par exemple un objet Bitmap en jpeg dans un MemoryStream il suffit de faire :

REM wBitmap est un objet de type Bitmap

Dim wStream As New System.IO.MemoryStream()
wBitmap.Save(wStream, System.Drawing.Imaging.ImageFormat.Jpeg)

Il faut ensuite récupérer le contenu du MemoryStream sous la forme d'un tableau d'octets (là on approche du but). L'objet MemoryStream possède une méthode Read qui permet de lire toute ou partie de son contenu sous la forme d'un tableau d'octets. Exactement ce qu'il nous faut. Il ne faut pas oublier que le MemoryStream se comporte comme un fichier, il mémorise donc l'emplacement de son pointeur interne. Lorsqu'on "vide" le Bitmap dans le MemoryStream, le pointeur interne se trouve à la fin du flux d'octets, il ne faut donc surtout pas oublier de replacer lson pointeur interne au début avant d'en récupérer les données, sinon on ne lira que du vent :

REM Déclaration d'un tableau d'octets assez grand (de la taille du MemoryStream)
Dim wBuffer(wStream.Length) As Byte

REM On se replace au début du MemoryStream
wStream.Position = 0

REM Lecture des données du MemoryStream placées dans le tableau d'octets
wStream.Read(wBuffer, 0, wBuffer.Length)

REM On n'oublie surtout pas de fermer le MemoryStream (comme un fichier)
wStream.Close


Nous avons tous les ingrédients pour transformer une image en chaîne Base64

Voici le code complet de notre fonction BitmapToBase64 :

Private Function BitmapToBase64(ByVal wBitmap As Bitmap) As String
    If wBitmap Is Nothing Then
         Return ""
     Else
         Dim wStream As New System.IO.MemoryStream()
         wBitmap.Save(wStream, System.Drawing.Imaging.ImageFormat.Jpeg)
         Dim wBuffer(wStream.Length) As Byte
         wStream.Position = 0
         wStream.Read(wBuffer, 0, wBuffer.Length)
         wStream.Close()
         Return System.Convert.ToBase64String(wBuffer)
     End If
 End Function

Il ne reste plus maintenant qu'à faire l'opération inverse pour récupérer depuis notre chaîne Base64 le bitmap d'origine

Je vous livre le code de Base64ToBitmap directement. C'est exactement l'opération inverse de BitmapToBase64 :

Private Function Base64ToBitmap(ByVal wBase64 As String) As Bitmap         
    If wBase64 = "" Then
        Return Nothing
    Else
         Dim wBuffer() As Byte = Convert.FromBase64String(wBase64)
         Dim wStream As New System.IO.MemoryStream(wBuffer)
         Dim wBitmap As New Bitmap(wStream)
         wStream.Close()
         Return wBitmap
    End If
 End Function

Note : Dans ce code, il serait de bon ton de gérer les erreurs, car on n'est pas à l'abris de passer à cette fonction une chaîne qui ne correspond pas à un bitmap codé en Base64.

 

Et voilà, si vous avez besoin de transformer un bitmap en une chaîne de caractères et ensuite la récupérer, il vous suffit maintenant d'utiliser nos belles fonctions BitmapToBase64 et Base64ToBitmap. Elle est pas belle la vie ?

Stéphane Sibué


Développez pour Windows Mobile
Copyright 2001-2007 - Tous droits réservés
Toutes les marques et produits présents dans ces pages sont la propriété exclusive de leurs sociétés respectives.