Announcement

Collapse
No announcement yet.

Image to Binary und anders herum

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Image to Binary und anders herum

    Hallo,
    ich habe mich hier angemeldet, da ich momentan ein kleines Problem habe.
    Ich verwende von MS den SQL Server 2005 und möchte gerne ein Bild darin hinterlegen, welches vom Typ Binary ist.
    Im Programm verwende ich eine PictureBox, die mir den Umgang mit einem Image erleichtert.
    Das Bild soll über den OpenfileDialog ausgewählt werden können.
    Wie bekomme ich nun aber die beiden unterschiedlichen Datentypen gehandelt?
    Gibt es schon fertige Converter? Ich komm einfach nicht weiter!

    Mit freundlichem Gruß

    Matthias

  • #2
    Servus,

    Speichere das Byte[] welches du mit nem FileStream.Read bekommst in die Datenbank.

    Auslesen aus der Datenbank kannst du das Bild wenn du dir die Daten holst und es anschließend wieder in nem FileStream wegschreibst und die gespeicherte Datei die PictureBox reinlädst.

    Hoffe geholfen zu haben.

    Gruß Stefan
    Mitarbeiterführung ist:
    Den Mitarbeiter so schnell über den Tisch zu ziehen, dass er die Reibungshitze als Nestwärme empfindet!

    Comment


    • #3
      Hey Stefan,
      ich habe das bereits auch schon so wie du sagtest erstellt gehabt, nur leider schreibt er folgenden Fehler:

      Ein Objekt- oder Spaltenname fehlt oder ist leer. Überprüfen Sie für SELECT INTO-Anweisung, ob jede Spalte einen Namen aufweist. Suchen Sie für andere Anweisungen nach leeren Aliasnamen. Mit "" oder [] definierte Aliase sind nicht zulässig. Fügen Sie einen Namen oder ein Leerzeichen als Aliasnamen hinzu.
      Falsche Syntax in der Nähe von ''.
      Code:
      public int SqlImageAnimal(int id, byte[] image)
              {
                  this.SqlConnect();
                  SqlCommand SqlCommandFischkopp = new SqlCommand("UPDATE Animal SET Photo="+image+" WHERE AnimalId="+id+";", _connection);
                  
                  int affectedRows = SqlCommandFischkopp.ExecuteNonQuery();
                  this.SqlDisconnect();
                  return affectedRows;
              }
      Code:
      openFileDialog_picture.Title = "Bild änder...";
                  openFileDialog_picture.Filter = "Bild| *.jpg; *.jpeg; *.gif; *.bmp";
                  openFileDialog_picture.FileName = "";
                  openFileDialog_picture.ShowDialog();
                  if (openFileDialog_picture.FileName.ToString() != "")
                  {
                      pictureBox_Picture.ImageLocation = openFileDialog_picture.FileName.ToString();
                  }
      
                  byte[] image;
                  string fileName = openFileDialog_picture.FileName.ToString();
      
                  using (FileStream fs = new FileStream(fileName, FileMode.Open))
                  {
                      BinaryReader reader = new BinaryReader(fs);
                      image = reader.ReadBytes((int)fs.Length);
                      fs.Close();
                  }
                  SqlFischkopp sqlImage = new SqlFischkopp();
                  sqlImage.SqlImageAnimal(_thisFish.FishId, image);

      Comment


      • #4
        Du benutzt den Byte Array beim zusammenbasteln des Updates wie einen string.

        Ein Byte Array ist aber kein string du mußt den schon wenn du so updaten willst selbst in eine string umwandeln. So wie du es jetzt machst wird einfach ToString() des Arrays aufgerufen. ToString() ist aber eher eine diagnostische Funktion insbesondere bei komplexen Datentypen und sollte meiner Meinung nach auch nur so verwendet werden. In deinem Fall byte[] liefert ToString die Typbezeichnung als 'System.byte[]'.

        Du solltest nicht selbst den Update string zusammenbasteln. Benutze Parameter. Die Parameterklassen wissen wie sie ihren Inhalt korrekt umwandeln um sie dann bei einem update zur Datenbank zu transportieren.

        Comment


        • #5
          Vielen Dank für eure Antworten.
          Ich habe es nur selbst definiert, da mein Vorgänger, dessen Code ich benutzen soll, es auch getan hat.
          Jetzt steh ich gerad auf dem Schlauch und versuch mir das zurechtzubasteln!
          Schönen Abend noch

          Comment


          • #6
            Wie bereits gesagt wurde, musst du an der Stelle mit Parametern arbeiten.

            Hier ein kleines Beispiel andem du dich orientieren kannst.

            Code:
            //SQL Statement
            UPDATE Animal SET Photo="@image"
            
            //Parameter befüllen
            this.sqlUpdate = "UPDATE Animal SET Photo="@image"; 
            this.sqlCommand = new SqlCommand(this.sqlUpdate, this.sqlConnection); 
            SqlParameter paramObject = new SqlParameter("@image", SqlDbType.Image); 
            paramObject.Value = <dein byte array>; 
            this.sqlCommand.Parameters.Add(paramObject);
            Mitarbeiterführung ist:
            Den Mitarbeiter so schnell über den Tisch zu ziehen, dass er die Reibungshitze als Nestwärme empfindet!

            Comment


            • #7
              Hallo Stefan,
              danke für die Antwort.
              Habe es jetzt soweit abgeändert und es sollte eigentlich funktionieren.
              Nun wollte ich gerne natürlich auf das Bild abrufen. Ich habe dazu auch schon etwas erstellt. Es funktioniert nur leider nicht
              Ich wollte eigentlich den MemoryStream verwenden, soweit sogut.
              Nur diesem übergebe ich ein byte[] und ich weiß nicht was ich beim ExecuteScalar() übergeben soll.

              // Get Database
              Database db = DatabaseFactory.CreateDatabase();

              // Create Example DbCommand
              string selectSql = "SELECT Photo FROM Photos
              WHERE PhotoID = 1";
              DbCommand selectCommand =
              db.GetSqlStringCommand(selectSql);

              // Execute Command
              byte[] storedImage = (byte[])db.
              ExecuteScalar(selectCommand);

              // Convert byte[] to Image
              Image newImage;
              using (MemoryStream stream =
              new MemoryStream(storedImage))
              {
              newImage = Image.FromStream(stream);
              }

              // Display to make sure code works
              pictureBox1.Image = newImage;
              In meinem Code habe ich bis jetzt folgendes für das Speichern:
              Code:
              public void ImageConverter(string File)
                      {
                          byte[] image;
                          string fileName = File;
              
                          using (FileStream fs = new FileStream(fileName, FileMode.Open))
                          {
                              BinaryReader reader = new BinaryReader(fs);
                              image = reader.ReadBytes((int)fs.Length);
                              fs.Close();
                          }
                          SqlFischkopp ImageTransfer = new SqlFischkopp();
                          ImageTransfer.SqlImage(image, _thisFish.FishId);
              
                      }
              Code:
              public void SqlImage(byte[] Image, int Id)
                      {
                          try
                          {
                              SqlConnect();
                              SqlCommand SqlImage = new SqlCommand("UPDATE Animal SET Photo=(@picture) WHERE AnimalId=(@Id)", _connection);
                              SqlImage.Parameters.Add("@picture", SqlDbType.Image);
                              SqlImage.Parameters["@picture"].Value = Image;
                              SqlImage.Parameters.Add("@Id", SqlDbType.Int);
                              SqlImage.Parameters["@Id"].Value = Id;
                              int affectedrows = SqlImage.ExecuteNonQuery();
                              SqlCommand commit = new SqlCommand("commit", _connection);
                              SqlImage.ExecuteNonQuery();
                          }
                          finally
                          {
                              SqlDisconnect();
                          }

              Wenn man einen Eintrag auswählt lädt er eine neue Form, wo die Daten hineingespeichert werden aus der Datenbank. Ebenso das Bild. Dieses muss ich so übernehmen wie es ist. Ich weiß nur nicht wo ich jetzt den Abruf des Bildes übernehmen soll! Das Bild ist der der Tabelle Animal und Spalte Photo (Image als Datentyp)

              Code:
              public void InitializeFish(int fishId)
                      {
                          SqlFischkopp fishSql = new SqlFischkopp();
              
                          fishSql.SqlConnect();
              
                          SqlDataReader SqlDataReaderFischkopp = fishSql.SqlDataReaderFischkopp("SELECT * FROM Animal WHERE AnimalId =" + fishId);
                          
                          while (SqlDataReaderFischkopp.Read())
                          {
                                             
              
                              this.setfish((int)SqlDataReaderFischkopp["AnimalId"], SqlDataReaderFischkopp["SciName"].ToString(), SqlDataReaderFischkopp["GerName"].ToString(), SqlDataReaderFischkopp["SciFamily"].ToString(), SqlDataReaderFischkopp["GerFamily"].ToString(), SqlDataReaderFischkopp["Category"].ToString(), SqlDataReaderFischkopp["Habitat"].ToString(), SqlDataReaderFischkopp["GenderDifferences"].ToString(), SqlDataReaderFischkopp["Breed"].ToString(), SqlDataReaderFischkopp["Food"].ToString(), SqlDataReaderFischkopp["SocialBehavior"].ToString(), SqlDataReaderFischkopp["Keeping"].ToString(), SqlDataReaderFischkopp["Specialty"].ToString(), (decimal)SqlDataReaderFischkopp["MinLengthAquarium"], (decimal)SqlDataReaderFischkopp["MaxSizeAnimal"], (decimal)SqlDataReaderFischkopp["MinPhValue"], (decimal)SqlDataReaderFischkopp["MaxPhValue"], (decimal)SqlDataReaderFischkopp["MinKhValue"], (decimal)SqlDataReaderFischkopp["MaxKhValue"], (decimal)SqlDataReaderFischkopp["MinTemperature"], (decimal)SqlDataReaderFischkopp["MaxTemperature"], Photo);
                          }
              
                          fishSql.SqlDisconnect();
                      }
              Zuletzt editiert von swimawies; 10.12.2008, 13:23.

              Comment


              • #8
                Funktioniert das speichern?

                Also ich könnt mir jetz nur noch vorstellen, dass du beim MemoryStream noch nen write oder flush aufrufen musst.

                Am Besten schreibst du die Daten mal testweise in ne Temporäre Datei und setzt die dann in die PictureBox rein.

                Was anderes fällt mir jetz leider nicht mehr dazu ein.

                Ansonste gibts bei CodeProject noch nen interessanten Artikel den ich grad gefunden hab.
                Zuletzt editiert von Stefan Wimmer; 10.12.2008, 14:23.
                Mitarbeiterführung ist:
                Den Mitarbeiter so schnell über den Tisch zu ziehen, dass er die Reibungshitze als Nestwärme empfindet!

                Comment


                • #9
                  Hey Stefan,
                  er wirft so jedenfalls keinen Fehler aus und die Variablen sind gefüllt. Ich greife über Visual Studio 2008 auf die DB zu und kann leider zur Laufzeit keine Änderungen sehen, da er das View nie updatet...
                  Macht er auch nicht, wenn man Werte wirklich ändert. Müsste die Connection closen, obwohl wir nach jedem Aufruf mit commit bestätigen!
                  Warum fragst du?

                  Lieben Gruß
                  Matthias

                  Comment


                  • #10
                    Das ist ja schon mal ne gute Voraussetzung

                    Schau dir auf jeden Fall mal den Artikel an den ich vorher noch verlinkt hab. Evtl hilft der noch weiter.

                    Gruß Stefan
                    Mitarbeiterführung ist:
                    Den Mitarbeiter so schnell über den Tisch zu ziehen, dass er die Reibungshitze als Nestwärme empfindet!

                    Comment


                    • #11
                      Hallo,
                      so, jetzt habe das dieses Tutorial auch noch gelesen
                      War das 12. was ich gelesen habe. Ist echt schrecklich, wenn man Code von anderen benutzen MUSS und dass so umständlich ist.
                      Code:
                      SqlFischkopp conn = new SqlFischkopp();
                                  conn.SqlConnect();
                                  string command = "SELECT Photo" + "FROM Animal WHERE AnimalId=@ID";
                                  SqlCommand cmdSelectImage = new SqlCommand(command);
                                  cmdSelectImage.Parameters.Add("@ID", SqlDbType.Int);
                                  cmdSelectImage.Parameters["@ID"].Value = fishId;
                                  byte[] imagebyte = (byte[])cmdSelectImage.ExecuteScalar(command);
                                  string strfn = Convert.ToString(DateTime.Now.ToFileTime());
                                  FileStream fs = new FileStream(strfn,FileMode.CreateNew, FileAccess.Write);
                                  fs.Write(imagebyte,0,imagebyte.Length);
                                  fs.Flush();
                                  fs.Close();
                                  cmdSelectImage.ExecuteNonQuery();
                                  this.Photo = Image.FromFile(strfn);
                                  conn.SqlDisconnect();
                      Er macht jetzt nurnoch folgenden Fehler: bei ExecuteScalar();
                      Keine Überladung fpr die ExcuteScalar-Methode nimmt 1 Argumente an.

                      Comment


                      • #12
                        jo, nimm bei
                        Code:
                        byte[] imagebyte = (byte[])cmdSelectImage.ExecuteScalar(command);
                        das command raus aus der Klammer, dann sollte das gehen.

                        Gib bitte kurz Rückmeldung ob das speichern und laden dann funktioniert hat.

                        Grüßle
                        Stefan
                        Mitarbeiterführung ist:
                        Den Mitarbeiter so schnell über den Tisch zu ziehen, dass er die Reibungshitze als Nestwärme empfindet!

                        Comment


                        • #13
                          Hey,
                          ohne command kam dieser Fehler :
                          Das Objekt des Typs System.DBNull kann nicht in Typ System.Byte[] umgewandelt werden.
                          Das liegt daran, dass noch kein Bild in der Datenbank an dieser Stelle existiert!

                          Comment


                          • #14
                            Jo, das liegt daran wie schon gesagt, dass noch nix in der Datenbank drin ist, zumindest kein Bild.

                            Das musst du vorher natürlich abprüfen, ob da überhaupt was zurückkommt. Also ungleich DBNull oder null

                            Wenn nix zurück kommt, kannst ja ein Default Image laden wie beim Internet Explorer wenn kein Bild vorhanden ist. (Ich glaub dass kannst sogar direkt in der PictureBox einstellen )

                            Im Umkehrschluss heißt das aber auch, dass das speichern nicht geht oder?

                            Gruß Stefan
                            Mitarbeiterführung ist:
                            Den Mitarbeiter so schnell über den Tisch zu ziehen, dass er die Reibungshitze als Nestwärme empfindet!

                            Comment


                            • #15
                              Ja, so sieht es aus Werd wahrscheinlich jetzt dazu über gehen nur den Pfad als String zu speichern und die Bilder lokal!

                              Comment

                              Working...
                              X