locked
Problème de conversion d'un type Bitmap en type SQL Image RRS feed

  • Question

  • dans une table d'une base de données je veux stocker une image Bitmap.

    Cette Bitmap est obtenue à partir d'une ressources et du code suivant :

     

    public Bitmap MyImage;

    MyAssembly = Assembly.GetExecutingAssembly();

    MyManagerImage = new ResourceManager("CreateDBSupports.CDBSImages", MyAssembly);

    .

    MyImage = (Bitmap) MyManagerImage.GetObject("Nom de la ressourcesage");

    // "Nom de la ressources" = nom de la ressources dans CDBSImages.resx

    J'ai vérifié que l'image est correcte avec le code suivant :

    pictureBoxTS.Image = MyImage;

    pictureBoxTS.SizeMode = PictureBoxSizeMode.StretchImage;

     

    la table est définie via la procédure stockée suivante :

    public String SqlStatementCreateTableTypeSupports =

    "USE DBSupports" + Environment.NewLine +

    "IF EXISTS (" +

    "SELECT * " +

    "FROM DBSupports.dbo.sysobjects " +

    "WHERE Name = 'TypeSupports' " +

    "AND TYPE = 'u')" + Environment.NewLine +

    "BEGIN" + Environment.NewLine +

    "DROP TABLE DBSupports.dbo.TypeSupports" + Environment.NewLine +

    "END" + Environment.NewLine +

    "CREATE TABLE TypeSuports (" +

    "Type NVarChar(10) NOT NULL PRIMARY KEY," +

    "Libellé NVarChar(60) NOT NULL," +

    "Capacité NVarChar(10) NOT NULL," +

    "ImageSupport image NULL" + ")";

     

    Pour créer une ligne de table j'utilise une autre Procédure Stockée :

    public String SqlStatementCreateProcAddTypeSupport =

    "CREATE PROCEDURE AddTypeSupport" + Environment.NewLine +

    " @newtype NVarChar(10)," +

    " @newLibellé NVarChar(60)," + Environment.NewLine +

    " @newCapacité NVarChar(10)," + Environment.NewLine +

    " @newImageSupport image " + Environment.NewLine +

    "AS" + Environment.NewLine +

    "INSERT INTO TypeSupports (Type, Libellé, Capacité, ImageSupport)" + Environment.NewLine +

    " Values (@newType, @newLibellé, @newCapacité, @newImageSupport)";

     

    Et le code suivant :

     

    try

    {

    // Tentative de connexion à l'instance SQL Server pour la Base de Données "DBSupports".

    ConnectionUseDB.Open();

    // Création d'une instance de référence SqlCommand pointant vers la procédure stockée.

    cmd = new SqlCommand("AddTypeSupport", ConnectionUseDB);

    cmd.CommandType = CommandType.StoredProcedure;

    // Création d'une instance de référence SqlParameter pour pouvoir définir les paramètres.

    prm = new SqlParameter();

    for (int i = 0; i < NbItemsListTypeSupports; i++)

    {

    // Clear des paramètres de la Commande (SqlCommand)

    cmd.Parameters.Clear();

    // Création des différents paramètres avec un SqlDbType pour éliminer tout type de conversion

    cmd.Parameters.Add("@newtype", SqlDbType.NVarChar, 10).Value = "Nom Type Support"];

    cmd.Parameters.Add("@newLibellé", SqlDbType.NVarChar, 60).Value = "Liibellé Type Supports";

    cmd.Parameters.Add("@newCapacité", SqlDbType.NVarChar, 10).Value = "Capacité du TypeSupport";

    MyImage = (Bitmap) MyManagerImage.GetObject("Nom de la ressource");

    pictureBoxTS.Image = MyImage;

    pictureBoxTS.SizeMode = PictureBoxSizeMode.StretchImage;

    cmd.Parameters.Add("@newImageSupport", SqlDbType.Image).Value = MyImage;

    MessageBox.Show(@"Juste pour voir où on en est.", "Fonction Info",

    MessageBoxButtons.OK);

    cmd.ExecuteNonQuery();

    }

    }

    catch (SqlException sqlExc)

    {

    // Impossible d'établir une connexion avec le serveur SQL ou MSDE, erreur SQL

    TextBoxMsg.Text += "SQL Exception Error, message d'erreur : " + Environment.NewLine + " " + sqlExc.Message + Environment.NewLine;

    return false;

    }

    catch (Exception exc)

    {

    // Impossible d'établir une connexion avec le serveur SQL ou MSDE

    TextBoxMsg.Text += "Connection impossible, message d'erreur : " + Environment.NewLine + " " + exc.Message + Environment.NewLine;

    return false;

    }

    ConnectionUseDB.Close();

    return true;

     

    sur l'instruction :

    cmd.Parameters.Add("@newImageSupport", SqlDbType.Image).Value = MyImage;

     

    j'ai le message suivant :

    " Échec de la conversion de la valeur de paramètre d'un Bitmap en un Byte[]."

     

    Voilà merci d'avance si quelqu'un a la solution.

    Bien sûr je pourrais stocker tous simplement le nom de la "resources" mais si le type

    SqlDbType.Image existe pourquoi ne pas l'utiliser !

    lundi 1 décembre 2008 11:25

Réponses

  • J'ai largement crapahuté dans les différentes URL que vous m'avez fourni tant françaises qu'américaines (plus fournies d'ailleurs que les françaises) ou j'ai trouvé pas mal d'acticles de personnes qui l'avaient fait y compris avec SQL Express et Visual Studio Express et qui avaient des problèmes de taille, de performance etc.. mais sans j'avais indiquer le code qu'ils utilisaient.

    bref, beaucoup d'articles je trouve : "BLOB's or Not BLOB's" comme ils disent.

    J'ai fini par trouver des morceaux de codes par çi par là que j'ai rassemblé et qui m'ont permis de faire deux routines l'une pour convertir une Image en tableau de Bytes et l'autre pour l'inverse qui permet de convertir le tableau de Bytes en Image.

    J'ai testé la conversion dans les deux sens et l'affichage départ et arrivée est identique.

    L'enregistrement dans la base de données en varbinary(max) se fait sans problème.

    Reste à vérifier pour être sûr à 100% que SQL n'altère pas les données sur la database.  

    Je vous tiendrais au courant.

    pour finir voici le code ci-dessous des routines et un grand merci.

     

    cmd.Parameters.Clear();

    // Création des différents paramètres avec un SqlDbType pour éliminer tout type de conversion

    cmd.Parameters.Add("@newtype", SqlDbType.NVarChar, 10).Value = "Le type Supports"];

    cmd.Parameters.Add("@newLibellé", SqlDbType.NVarChar, 60).Value = "le Libellé du type";

    cmd.Parameters.Add("@newCapacité", SqlDbType.NVarChar, 10).Value = "La capacité du type";

    MyImage = (Bitmap) MyManagerImage.GetObject("Code de la Photo dans resources.resx")

    pictureBoxTS.Image = MyImage;

    pictureBoxTS.SizeMode = PictureBoxSizeMode.StretchImage;

    try

    {

    MyByteImage = ConvertImageToByteArray(MyImage, ImageFormat.Tiff);

    }

    catch (Exception err)

    {

    TextBoxMsg.Text += "Erreur, message d'erreur : " + Environment.NewLine + " " + err.Message + Environment.NewLine;

    return false;

    }

    cmd.Parameters.Add("@newImageSupport", SqlDbType.VarBinary).Value = MyByteImage;

    MessageBox.Show(@"Juste pour voir où on en est.", "Fonction Info",

    MessageBoxButtons.OK,MessageBoxIcon.Information,MessageBoxDefaultButton.Button1,MessageBoxOptions.DefaultDesktopOnly);

    cmd.ExecuteNonQuery();

    try

    {

    MyStoredImage = ConvertByteArrayToImage(MyByteImage);

    }

    catch (Exception err)

    {

    TextBoxMsg.Text += "Erreur, message d'erreur : " + Environment.NewLine + " " + err.Message + Environment.NewLine;

    return false;

    }

    pictureBox1.Image = MyStoredImage;

    pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;

    }

    }

    catch (SqlException sqlExc)

    {

    // Impossible d'établir une connexion avec le serveur SQL ou MSDE, erreur SQL

    TextBoxMsg.Text += "SQL Exception Error, message d'erreur : " + Environment.NewLine + " " + sqlExc.Message + Environment.NewLine;

    return false;

    }

    catch (Exception exc)

    {

    // Impossible d'établir une connexion avec le serveur SQL ou MSDE

    TextBoxMsg.Text += "Connection impossible, message d'erreur : " + Environment.NewLine + " " + exc.Message + Environment.NewLine;

    return false;

    }

    ConnectionUseDB.Close();

    return true;

    }

    private byte[] ConvertImageToByteArray(Image MyImg, ImageFormat IFC)

    // Le but de cette routine (si ça marche) est de convertir

    // un Objet de type System.Drawing.Bitmat en un Objet de type System.Byte[]

    {

    MemoryStream ms = new MemoryStream();

    MyImg.Save(ms, IFC);

    return ms.ToArray();

    }

    private Image ConvertByteArrayToImage(byte[] MyStoredImg)

    // Le but de cette routine (si ça marche) est de convertir

    // un Objet de type System.Drawing.Bitmat en un Objet de type System.Byte[]

    {

    Image NewImage;

    using (MemoryStream MyStream = new MemoryStream(MyStoredImg))

    {

    NewImage = Image.FromStream(MyStream);

    }

    return NewImage;

    }

     

    Dernier détail : y-a-t'il moyen de vous envoyer un fichier Zip du global ?

     

    ET Merci encore !

    mardi 2 décembre 2008 18:09
  • Bonjour,

     

    A cette adresse, j'ai trouvé la définition de BLOB ( binary large objects )

    http://msdn.microsoft.com/en-us/library/ms165911.aspx

    soit

    A piece of binary data that has an exceptionally large size, such as pictures or audio tracks that are stored as digital data, or any variable or table column that is large enough to hold such values

     

    Je vous remercie ( pour moi-même et les autres visiteurs de ce forum ) pour le code que vous avez posté.

    En effet, il est très rare de voir la personne qui a commencé un topic ( je préfère le mot anglais thread car je vais plus souvent sur les sites de MSDN US ) expliquer sa solution, sutout quand il s'agit de code.

    Félicitations pour votre décision et j'espère que vous me pardonnerez si un jour je donne le lien vers ce thread aussi bien sur un forum français que US

     

    Bonne journée

    mardi 2 décembre 2008 20:14
  • Rebonjour,

     

    Un dernier conseil, il y a un excellent forum où vous auriez pu poster votre topic

    http://forums.microsoft.com/MSDN-FR/ShowForum.aspx?ForumID=889&SiteID=12

     

    Malheureusement, beaucoup de "posters" oublient ce forum qui concerne principalement le traitement des données SQL Server par les "namespaces" du .Net Framework ( ADO.Net ) comme System.Data.SqlClient

     

    Bonne journée et encore bravo pour votre excellente prestation sur ce forum

     

    mardi 2 décembre 2008 20:46

Toutes les réponses

  • Re,

     

    Vous devriez demander à un moderateur de fusionner ce topic avec la partie de

    http://forums.microsoft.com/MSDN-FR/ShowPost.aspx?PostID=4161396&SiteID=12

    qui traite du même sujet

     

    Bonne soirée

     

    lundi 1 décembre 2008 21:09
  • Moi je veux bien, mais c'est une manips que je ne connais pas !

     

    mardi 2 décembre 2008 10:48
  • J'ai largement crapahuté dans les différentes URL que vous m'avez fourni tant françaises qu'américaines (plus fournies d'ailleurs que les françaises) ou j'ai trouvé pas mal d'acticles de personnes qui l'avaient fait y compris avec SQL Express et Visual Studio Express et qui avaient des problèmes de taille, de performance etc.. mais sans j'avais indiquer le code qu'ils utilisaient.

    bref, beaucoup d'articles je trouve : "BLOB's or Not BLOB's" comme ils disent.

    J'ai fini par trouver des morceaux de codes par çi par là que j'ai rassemblé et qui m'ont permis de faire deux routines l'une pour convertir une Image en tableau de Bytes et l'autre pour l'inverse qui permet de convertir le tableau de Bytes en Image.

    J'ai testé la conversion dans les deux sens et l'affichage départ et arrivée est identique.

    L'enregistrement dans la base de données en varbinary(max) se fait sans problème.

    Reste à vérifier pour être sûr à 100% que SQL n'altère pas les données sur la database.  

    Je vous tiendrais au courant.

    pour finir voici le code ci-dessous des routines et un grand merci.

     

    cmd.Parameters.Clear();

    // Création des différents paramètres avec un SqlDbType pour éliminer tout type de conversion

    cmd.Parameters.Add("@newtype", SqlDbType.NVarChar, 10).Value = "Le type Supports"];

    cmd.Parameters.Add("@newLibellé", SqlDbType.NVarChar, 60).Value = "le Libellé du type";

    cmd.Parameters.Add("@newCapacité", SqlDbType.NVarChar, 10).Value = "La capacité du type";

    MyImage = (Bitmap) MyManagerImage.GetObject("Code de la Photo dans resources.resx")

    pictureBoxTS.Image = MyImage;

    pictureBoxTS.SizeMode = PictureBoxSizeMode.StretchImage;

    try

    {

    MyByteImage = ConvertImageToByteArray(MyImage, ImageFormat.Tiff);

    }

    catch (Exception err)

    {

    TextBoxMsg.Text += "Erreur, message d'erreur : " + Environment.NewLine + " " + err.Message + Environment.NewLine;

    return false;

    }

    cmd.Parameters.Add("@newImageSupport", SqlDbType.VarBinary).Value = MyByteImage;

    MessageBox.Show(@"Juste pour voir où on en est.", "Fonction Info",

    MessageBoxButtons.OK,MessageBoxIcon.Information,MessageBoxDefaultButton.Button1,MessageBoxOptions.DefaultDesktopOnly);

    cmd.ExecuteNonQuery();

    try

    {

    MyStoredImage = ConvertByteArrayToImage(MyByteImage);

    }

    catch (Exception err)

    {

    TextBoxMsg.Text += "Erreur, message d'erreur : " + Environment.NewLine + " " + err.Message + Environment.NewLine;

    return false;

    }

    pictureBox1.Image = MyStoredImage;

    pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;

    }

    }

    catch (SqlException sqlExc)

    {

    // Impossible d'établir une connexion avec le serveur SQL ou MSDE, erreur SQL

    TextBoxMsg.Text += "SQL Exception Error, message d'erreur : " + Environment.NewLine + " " + sqlExc.Message + Environment.NewLine;

    return false;

    }

    catch (Exception exc)

    {

    // Impossible d'établir une connexion avec le serveur SQL ou MSDE

    TextBoxMsg.Text += "Connection impossible, message d'erreur : " + Environment.NewLine + " " + exc.Message + Environment.NewLine;

    return false;

    }

    ConnectionUseDB.Close();

    return true;

    }

    private byte[] ConvertImageToByteArray(Image MyImg, ImageFormat IFC)

    // Le but de cette routine (si ça marche) est de convertir

    // un Objet de type System.Drawing.Bitmat en un Objet de type System.Byte[]

    {

    MemoryStream ms = new MemoryStream();

    MyImg.Save(ms, IFC);

    return ms.ToArray();

    }

    private Image ConvertByteArrayToImage(byte[] MyStoredImg)

    // Le but de cette routine (si ça marche) est de convertir

    // un Objet de type System.Drawing.Bitmat en un Objet de type System.Byte[]

    {

    Image NewImage;

    using (MemoryStream MyStream = new MemoryStream(MyStoredImg))

    {

    NewImage = Image.FromStream(MyStream);

    }

    return NewImage;

    }

     

    Dernier détail : y-a-t'il moyen de vous envoyer un fichier Zip du global ?

     

    ET Merci encore !

    mardi 2 décembre 2008 18:09
  • Bonjour,

     

    A cette adresse, j'ai trouvé la définition de BLOB ( binary large objects )

    http://msdn.microsoft.com/en-us/library/ms165911.aspx

    soit

    A piece of binary data that has an exceptionally large size, such as pictures or audio tracks that are stored as digital data, or any variable or table column that is large enough to hold such values

     

    Je vous remercie ( pour moi-même et les autres visiteurs de ce forum ) pour le code que vous avez posté.

    En effet, il est très rare de voir la personne qui a commencé un topic ( je préfère le mot anglais thread car je vais plus souvent sur les sites de MSDN US ) expliquer sa solution, sutout quand il s'agit de code.

    Félicitations pour votre décision et j'espère que vous me pardonnerez si un jour je donne le lien vers ce thread aussi bien sur un forum français que US

     

    Bonne journée

    mardi 2 décembre 2008 20:14
  • Rebonjour,

     

    Un dernier conseil, il y a un excellent forum où vous auriez pu poster votre topic

    http://forums.microsoft.com/MSDN-FR/ShowForum.aspx?ForumID=889&SiteID=12

     

    Malheureusement, beaucoup de "posters" oublient ce forum qui concerne principalement le traitement des données SQL Server par les "namespaces" du .Net Framework ( ADO.Net ) comme System.Data.SqlClient

     

    Bonne journée et encore bravo pour votre excellente prestation sur ce forum

     

    mardi 2 décembre 2008 20:46
  • Merci pour vos derniers messages, cela fait plaisir et c'est encouragent.

    Un grand merci pour votre aide.

    A+ ... peut-être sur un autre sujet.

    mercredi 3 décembre 2008 09:06