Conversion d’un object image OLE à partir de MS Access pour une utilisation dans .NET

Je travaille au réaménagement d’un système basé sur Access dans c # .net. Toutefois, lorsque MS est passé de office 2003 à office 2007, il a supprimé l’éditeur d’images dans Access, ce qui signifiait que les images précédemment stockées ne s’afficheraient plus dans le système. Les gars de la société ont fait un piratage qui a fondamentalement enregistré les images avec VBA en utilisant Excel en arrière-plan (je peux obtenir plus d’informations si vous en avez besoin), mais cela signifiait essentiellement que les contrôles d’image d’access pouvaient toujours être utilisés (frameworks liés d’object).

Cependant, j’ai maintenant le problème d’essayer d’afficher celles-ci dans des applications .NET, et après de nombreux jours à essayer différentes façons de manipuler le tableau d’octets, je suis sur le point d’abandonner. J’ai essayé au moins 8 solutions suggérées différentes et chacune d’elles se termine par une exception “Paramètre non reconnu” lors de l’exécution de Image.fromStream (). Ci-dessous le code qui m’a le plus proche jusqu’à présent:

private void imageExtractTest() { LogOnDataSetTableAdapters.QueriesTableAdapter qa = new LogOnDataSetTableAdapters.QueriesTableAdapter(); object docO = qa.GetLogonImage(); if (docO == null || !(docO is byte[])) { return; } byte[] doc = (byte[])docO; MemoryStream ms = new MemoryStream(); ms.Write(doc, 0, doc.Length); int firstByte; int secondByte; ms.Seek(0, SeekOrigin.Begin); firstByte = ms.ReadByte(); secondByte = ms.ReadByte(); if (firstByte != 0x15 && secondByte != 0x1C) { //ErrorResponse("Stored object is not an Access File."); return; } int fileTypeLoc = 20; // begin of the file type short offset; // end of the file type byte[] buffer = new byte[2]; ms.Read(buffer, 0, 2); offset = BitConverter.ToInt16(buffer, 0); long seekTotal = 0; seekTotal += offset; ssortingng docType = Ssortingng.Empty; for (int i = fileTypeLoc; i < offset; i++) { docType += (char)doc[i]; } //if I query docType now I get 'Picture\0\0' // magic eight bytes 01 05 00 00 03 00 00 00 ms.Seek(seekTotal, SeekOrigin.Begin); buffer = new byte[8]; ms.Read(buffer, 0, 8); seekTotal += 8; // Second offset to move to buffer = new byte[4]; ms.Read(buffer, 0, 4); seekTotal += 4; long offset2 = BitConverter.ToInt32(buffer, 0); seekTotal += offset2; ms.Seek(seekTotal, SeekOrigin.Begin); // eight empty bytes buffer = new byte[8]; ms.Read(buffer, 0, 8); seekTotal += 8; // next n bytes are the length of the file buffer = new byte[4]; ms.Read(buffer, 0, 4); seekTotal += 4; long fileByteLength = BitConverter.ToInt32(buffer, 0); // next N bytes are the file byte[] data = new byte[fileByteLength]; // store file bytes in data buffer ms.Read(data, 0, Convert.ToInt32(fileByteLength)); MemoryStream imageStream = new MemoryStream(data); Image test = Image.FromStream(imageStream); } 

Ce code a été adapté à partir d’ ici , je n’avais pas besoin de l’identification des divers doctypes car je ne traitais que des images, mais le type d’image pouvait être un nombre quelconque de choses – jpg, bmp, gif, png, etc.

J’ai également essayé de sauvegarder le tableau d’octets généré, mais je n’ai pas eu la chance de le voir non plus. Mais lorsque je pointe l’access à la firebase database et que je la visualise, tout va bien. Le .NET Crystal Report designer est également capable d’obtenir ces images de la même manière – elles doivent donc se trouver quelque part …

Quelqu’un a-t-il des idées?

Marlon

Essayer de récupérer un champ d’image OLE MS-access à partir de .NET est bien plus casse-tête que ça ne vaut. Il y a quelques bonnes discussions et informations sur ce sujet dans ce post .

En fin de compte, votre meilleure solution, et la plus simple, consiste à utiliser votre méthode de visualisation pour enregistrer ces images sous forme de fichiers séparés, puis à importer ces fichiers dans la firebase database sous forme de champs BLOB, plutôt que de champs d’image. Ensuite, vous pouvez facilement les lire dans .NET.

Dans mon cas, la fonction suivante a fonctionné. Les données sont stockées par une application VB6.

 public static byte[] ConvertOleBytesToRawBytes(byte[] oleBytes) { // The default encoding is in my case - Western European (Windows), Code Page 1252 return Encoding.Convert(Encoding.Unicode, Encoding.Default, (byte[])oleBytes); } 

Essayez cet article de la base de connaissances http://support.microsoft.com/kb/317701 de Microsoft. Il contient des informations sur la façon d’accéder au blob d’image à partir de l’access et de l’afficher dans l’application Winforms.

Ce n’est pas du code C # mais voici un exemple Delphi d’un moyen de résoudre ce problème.

Il utilise l’ IOLEObject pour dessiner ce qui est stocké au lieu d’essayer de lire les données brutes. Pas:

  1. Lire l’en-tête d’access en face de l’object OLE
  2. Lire le stream OLE1
  3. Convertir le stream OLE1 en object OLE2 IStorage
  4. Utilisez OLELoad pour “exécuter” le Ojbect OLE.
  5. Appelez OLEDraw pour dessiner l’image sur une canvas de votre choix.