none
problème manipulation des images avec la base donnée RRS feed

  • Discussion générale

  • bonjour,

    j'ai une base donnée Microsoft SQL Server CE 3.5

    j'ai table qui contient une colonne de type "varbinary" pour enregistrer dessus des images.

    après des recherches sur internet, je suis tombé sur ce lien qui explique comment faire :

    Storing and Retrieving Images from SQL Server

    mais je tombe sur un problème que je ne comprend même pas

    je vous met mon code pour que vous sachiez ce que j'ai fait. et me dire si j'ai fait une erreur

    {
                    if (mac.machine_Image != null)
                    {
                        sauvgarderImageTemporairement(ref cheminDuFichierImageTemporaire, mac);
                        changerImageDuBoutonAvecUnFichier(cheminDuFichierImageTemporaire, bouton);
                    }
    }
    
    
    
            private void changerImageDuBoutonAvecUnFichier(string cheminDelImage, Button leBoutton)
            {
                Image imageCapturer= new Image();
                imageCapturer.Source = new BitmapImage(new Uri(cheminDelImage));// l'exception se déclenche a l’exécution de cette ligne
                var imageCapturerDuFichier = insererImage(imageCapturer);
                var imagePersonnaliser = new ControlTemplate(typeof(Button));
                imagePersonnaliser.VisualTree = imageCapturerDuFichier;
                leBoutton.Template = imagePersonnaliser;
                cheminDelImage = "";
            }
    
            void sauvgarderImageTemporairement(ref string cheminDuFichierTemporaire, machine mac)
            {
                cheminDuFichierTemporaire = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) +"\\"+
                                            DateTime.Now.ToFileTime().ToString();
                FileStream fs = new FileStream(cheminDuFichierTemporaire,
                                  FileMode.CreateNew, FileAccess.Write);
                fs.Write(mac.machine_Image, 0, mac.machine_Image.Length);
                fs.Flush();
                fs.Close();
                string a = "";
                MessageBox.Show(mac.machine_Image.ToList().ToString()+(char)13+cheminDuFichierTemporaire);
            }
    
    
    // pour enregistrer l'image j'utilise cette fonction :
            protected void sauvegarderLImage(machine mac)
            {
                try
                {
                    var m_barrImg = new byte[Convert.ToInt32(imageCapturer.Source)];
                    mac.machine_Image = m_barrImg;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
    
    /*
    - la fonction "insererImage" marche parfaitement parce que je l'utilise dans plusieurs endroits et elle retourne un FrameworkElementFactory pour personnaliser le bouton
    - j'utilise Entity Framework de vs 2010
    - l'exception généré est : 
    L'exception System.NotSupportedException n'a pas été gérée
    et son message :
    Impossible de trouver un composant d'image adapté pour terminer l'opération*/
    en espérant que j'ai fournis toutes les donnée pour que vous comprendriez le programme.

    merci d'avance :)


    dimanche 24 février 2013 13:34

Toutes les réponses

  • Bonjour,

    Que contient de CheminDeLimage ? Je dirais que le chemin ou le format est incorrect et pour l'instant cela ne semble avoir aucun rapport avec EF.

    Si cela ne marche pas, voir aussi ce que donnerait l'ajout du contrôle dans le formulaire avant de lui affecter une image (au cas où le contrôle ne supporterait pas de lui affecter une image sans qu'il dispose d'une destination où effectuer le rendu de cette image).

    Egalement j'ai changé cette "discussion" en "question".


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".


    lundi 25 février 2013 09:26
    Modérateur
  • Bonjour,

    CheminDeLimage contient le chemin du fichier temporaire créé comme indiqué sur cette ligne

    sauvgarderImageTemporairement(ref cheminDuFichierImageTemporaire, mac);
    //cette ligne crée le fichier temporaire et enregistre le chemin de ce même fichier dans la variable string référencé

    le formulaire marche sans aucune erreur même quand j'ajoute une image d'un fichier.

    En fait quand j'ajoute n'importe quelle image (sans la créé moi même) au bouton le formulaire marche sans faute, mais quand j’intègre une image dynamique (enregistrer dans la base de donnée), une exception se lève.

    En fait, je crois que l'erreur viens soit dans l'enregistrement de l'image dans la base de donnée, soit dans la génération du fichier temporaire.

    après tous ce n'ai qu'une supposition.

    merci encore pour ton aide :)

    lundi 25 février 2013 12:32
  • Ah oui, déjà la fonction SauvegarderLimage me parait bizarre. Je dirais que l'on convertit l'adresse de l'objet (?) en entier 32 bits et que l'on crée un tableau d'octets à 0 avec l'adresse de l'object comme longueur ?

    Un premier test simple serait de voir la taille du fichier original et la taille du fichier temporaire extrait de la base. Si déjà les 2 tailles ne sont pas identiques c'est bien que les données ne sont pas bien restituées.

    On veut sauver un fichier (ou une image déjà présente dans un contrôle ?) et la restituer plus tard sans nécessaire passer par un fichier temporairement (BitmapImage.StreamSource devrait permetttre de définir un MemoryStream basé sur le tableau d'octets retourné par EF).


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    lundi 25 février 2013 13:16
    Modérateur
  • merci beaucoup je testerai toutes tes recommandations je vous ferez un retour.

    merci encore :)


    • Modifié ahmedmahdi mardi 26 février 2013 07:58 orthographe :p
    lundi 25 février 2013 13:33
  • J'ai fait un petit essai (Datas étant mon DbSet de Data avec ImageFile un tableau d'octets).

    Pour charger le fichier dans la base je me suis contenté de :

    img.ImageFile = System.IO.File.ReadAllBytes(fileName);

    Pour afficher l'image dans un contrôle Image "img" qq chose comme ci-dessous fonctionne :

         using (var db = new Db())
                {
                    var item = db.Datas.First();
                    var bmp = new BitmapImage();
                    bmp.BeginInit();
                    bmp.StreamSource = new System.IO.MemoryStream(item.ImageFile);
                    bmp.EndInit();
                    img.Source = bmp;
                }
    Donc je récupère mon item de test, et j'alimente un "BitmapImage" en lui passant le tableau d'octets de l'image via son StreamSource. Ce BitmapImage est ensuite utilisé comme source du contrôle...


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    lundi 25 février 2013 19:36
    Modérateur
  • merci pour ton aide

    mais une question svp :

    "item" est de quel type parce que j'ai mis l'image de type "varbinary" et don je ne retrouve pas la propriété "item.ImageFile"

    mardi 26 février 2013 08:08
  • j'ai fait un nouveau petit projet pour tester un peu de tout sur ce sujet.

    Apparemment le problème commence dès l'enregistrement dans la base de donnée.

    je vous montre ce que j'ai fait et vous me direz vos avis :

            protected void sauvegarderLImage()
            {
                try
                {
                    BitmapImage imageBitmap = (BitmapImage)image1.Source;
                    MemoryStream memoire = (MemoryStream)imageBitmap.StreamSource;
                    mac.machine_Image = memoire.ToArray();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
    la il me dit que l'objet "memoire" de type "MemoryStream" est null

    et ça aussi :

            protected void sauvegarderLImage()
            {
                try
                {
                    var m_barrImg = new byte[Convert.ToInt32(image1.Source)];
                    mac.machine_Image = m_barrImg;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
    et celle la me dit la conversion est impossible
    mardi 26 février 2013 09:02
  • J'utilise "Entity Framework" et item est donc un objet de type Data (avec juste un Id et donc ImageFile qui est un tableau d'octets). Le code doit pouvoir être transposé sans problème car il fonctionne essentiellement à partir d'un tableau d'octets quel que soit la façon dont le tableau est lu ou écrit dans la base.

    Pour la sauvegarde quel est le principe ? Comment l'image est-elle choisie par l'utilisateur ? Si par exemple on utilise un dialogue de sélection de fichiers et que l'on utilise ensuite le chemin sélectionné par l'utilisateur pour définir la source de l'image, il me semblerait plus simple de récupérer le chemin de ce fichier et d'utiliser File.ReadAllBytes pour lire le fichier.


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    mardi 26 février 2013 11:49
    Modérateur
  • je viens de comprendre ce que vous voulez dire.

    je crois que je ne me suis pas bien exprimé.

    en faite l'utilisateur a le choix d’enregistrer ses images de la webcam ou d'un fichier choisi.

    j'espère que vous me comprenez mieux maintenant


    • Modifié ahmedmahdi mardi 26 février 2013 12:03
    mardi 26 février 2013 12:03
  • personne n'a d'idée
    mercredi 27 février 2013 12:19
  • pour la sauvegarde d'un objet "Image" dans un fichier voila le code et fonctionnel :

    void sauvgarderImage()
            {
    
                JpegBitmapEncoder encoder = new JpegBitmapEncoder();
                String photolocation = chemin + "\\fichier.jpg";  //file name 
    
                encoder.Frames.Add(BitmapFrame.Create((BitmapImage)imageCapturer.Source));
    
                using (var filestream = new FileStream(photolocation, FileMode.Create)) encoder.Save(filestream);
            }

    mercredi 27 février 2013 13:43
  • désolé j'ai remarqué une erreur quand on veux enregistrer une image quand celle ci viens de "InteropBitmap".

    donc voila la correction :

    void sauvgarderImage()
            {
                JpegBitmapEncoder encoder = new JpegBitmapEncoder();
                String photolocation = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\imageTemporaireControleOptiFive.jpg";  //file name 
    
                if(image3.Source.GetType().ToString().Contains("InteropBitmap"))
                    encoder.Frames.Add(BitmapFrame.Create((InteropBitmap)imageCaptuer.Source));
                else
                    encoder.Frames.Add(BitmapFrame.Create((BitmapImage)imageCapturer.Source));
    
                using (var filestream = new FileStream(photolocation, FileMode.Create)) encoder.Save(filestream);
            }

    @Aurel Bera

    merci pour le lien dès que j'ai une solution concrête je la posterai

    merci encore pour ton soutiens :)


    • Modifié ahmedmahdi mercredi 27 février 2013 14:34
    mercredi 27 février 2013 14:32
  • non pas vraiment,

    mais j'ai changé je sauvegarde les images dans un fichier a l'abris du regard de l'utilisateur maintenant. j'aurai voulu avoir une seule source de donnée mais bon j'ai passé beaucoup trop de temps dessus donc j'ai changé.

    je change de type de sujet : "question" à "discussion générale"

    merci encore pour votre soutien :)


    vendredi 1 mars 2013 08:31