2016-03-30 2 views
2

J'utilise LibTiff.Net de BitMiracle pour lire dans une image Bitmap et renvoyer un octet TIFF [] qui est incorporé dans un fichier en tant que Base64String. J'ai remarqué que la chaîne Base64 finit par être un peu plus longue que ce à quoi je m'attendais, la queue de laquelle se trouve un grand nombre de caractères 'A'. Pendant le débogage, je vois que l'octet [] que me renvoie LibTiff a plusieurs milliers de 0 valeurs à la fin qui ne semblent pas être une partie nécessaire de l'image elle-même (pour autant que je sache).Grand nombre de 0 valeurs à la fin de la matrice d'octets

Je suis en utilisant le code exemple de BitMiracle ici pour convertir: https://bitmiracle.github.io/libtiff.net/html/075f57db-d779-48f7-9fd7-4ca075a01599.htm

Je ne peux pas tout à fait voir ce qui causerait des « ordures » à la fin de l'octet [], bien que. Des pensées?

Modifier pour ajouter du code - GetTiffImageBytes() est dans le lien ci-dessus:

public void GenImage() 
     using (System.Drawing.Image frontImage = System.Drawing.Image.FromStream(file))//; 
      { 
       file.Close(); 

       //Draw something 
       b = new Bitmap(frontImage); 
       Graphics graphics = Graphics.FromImage(b); 
       graphics.DrawString(data1, (Font)GlobalDict.FontDict["font1"], Brushes.Black, 200, 490); 
       graphics.DrawString(data2, (Font)GlobalDict.FontDict["font2"], Brushes.Black, 680, 400); 

      } 
      //Convert to TIF - requires BitMiracle.LibTiff.Classic 
      byte[] tiffBytes = GetTiffImageBytes(b, false); 

      return tiffBytes; 
      } 

ci-dessus est appelé par:

byte[] aFrontImage = MiscTools.GenImage(somestuff); 

    fileXML.WriteLine(" <FrontImage>" + System.Convert.ToBase64String(aFrontImage, 0, aFrontImage.Length) + "</FrontImage>"); 

Toutes choses dit et fait, il fonctionne très bien, le résultat les images sont lisibles par notre application. J'essaie juste de réduire la taille car certains de ces fichiers peuvent contenir des dizaines de milliers d'images. J'ai des fichiers d'exemple plus anciens qui ont été créés à la main avec des chaînes Base64 via une autre méthode qui sont à peu près de la même taille, sauvegardez tous les octets de queue que je pense être garbage. Comme quelqu'un l'a commenté, une option peut être de simplement lire l'octet [] et supprimer toutes les 0 valeurs de la fin avant la conversion, mais j'essaie de comprendre pourquoi cela se passe pour commencer.

Merci!

+0

Postez votre code ici, s'il vous plaît. –

+1

Si vous pensez qu'ils sont des déchets, supprimez-les et essayez de charger l'image. Si cela ne fonctionne pas, cela signifie qu'ils sont nécessaires. – Eser

+0

J'ai ajouté une partie du code - merci. @Eser - J'aimerais bien, mais je suis curieux de savoir d'où proviennent les données supplémentaires. Je préférerais réparer la cause première plutôt que de la contourner, si possible. –

Répondre

2

Le problème est très probablement cela, trouvé dans le linked source example:

return ms.GetBuffer(); 

Pour MemoryStream, cela l'ensemble revenir tableau sous-jacent, même si vous ne l'avez pas réellement utilisé tout cela encore tableau. Ce tampon sera redimensionné à un tampon plus grand si vous écrivez assez pour le remplir, mais il ne sera pas étendu pour couvrir juste la taille nécessaire, il va croître à deux fois sa taille précédente à chaque fois. De plus, vous avez une propriété Length qui indiquera quelle partie de ce tableau est réellement utilisée.

Cela s'apparente à la capacité d'un List<T>, qui doublera également en taille chaque fois que vous remplissez la capacité actuelle. La propriété Count indique le nombre d'éléments que vous avez réellement dans la liste.

Le correctif est facile, remplacer la ligne au-dessus du code avec ceci:

return ms.ToArray(); 

Cela va créer un nouveau tableau, juste assez grand pour contenir les octets réellement écrits dans le flux de mémoire et copier le contenu de le tampon (la partie qui s'ajuste, et compte) en elle.

Pour vérifier que la mémoire tampon est plus grand que nécessaire, vous pouvez exécuter ce code simple:

var ms = new MemoryStream(); 
Console.WriteLine("GetBuffer: " + ms.GetBuffer().Length); 
Console.WriteLine("ToArray: " + ms.ToArray().Length); 
ms.WriteByte(0); 
Console.WriteLine("GetBuffer: " + ms.GetBuffer().Length); 
Console.WriteLine("ToArray: " + ms.ToArray().Length); 

Affichera ceci:

GetBuffer: 0 
ToArray: 0 
GetBuffer: 256 
ToArray: 1 

Comme vous pouvez le voir, la taille initiale du tampon lors de l'écriture seulement 1 octet à lui est passé à 256 octets. Après cela, il doublera chaque fois que vous atteignez la taille actuelle.

.NET Fiddle here.

+0

Eh bien, ouais. Je vous remercie! C'était parfait en fait. Quelle bêtise d'avoir manqué. C'est propre et garde définitivement mes tags TIFF intacts. –

+0

Le décodage d'image le plus probable ne tient pas compte des zéros supplémentaires, mais vous devriez maintenant supprimer définitivement votre code de rognage, si vous supprimez un zéro qui est attendu (et maintenant, avec le changement ci-dessus, correct), il est probable provoquer un problème de décodage d'image. –

+0

Oui, je n'utilise pas fixImageByteArray() avec ToArray(). Merci! :) –

0

Pour l'instant, je suis allé avec « fixer » la question après le fait et a créé une méthode que je demande à chaque image:

 private static byte[] fixImageByteArray(byte[] inByte) // Fix issue with garbage suffix data - reduces image byte[] size by roughly half. 
    { 
     int newByteBaseLength = inByte.Length - 1; 
     while (inByte[newByteBaseLength] == 0) 
     { 
      --newByteBaseLength; 
     } 

     float newByteModifiedLength = ((inByte.Length - newByteBaseLength) * 0.1f) + 0.5f; // When using newByteBaseLength + 1, some TIFF Tag data was getting lost. This seems to resolve the issue. 

     int newByteModifiedLengthAsInt = (int)newByteModifiedLength; 

     byte[] outByte = new byte[newByteBaseLength + newByteModifiedLengthAsInt]; 
     Array.Copy(inByte, outByte, newByteBaseLength + newByteModifiedLengthAsInt); 

     return outByte; 
    } 

EDIT: Je modifié les noms de variables pour faire un peu plus de sens . J'ai trouvé que l'ancienne façon (en utilisant newByteBaseLength + 1) de dimensionner le tableau a causé des dommages aux tags TIFF. En utilisant une méthode légèrement moins efficace, la taille de l'image est encore considérablement réduite, mais les balises restent intactes.