2009-12-28 5 views
-1

Est-il possible d'écrire un bitmap en C# ligne par ligne? Je suis inquiet que l'utilisation de la fonction Bitmap.Save() exigera trop de mémoire lorsqu'ils traitent des fichiers LARGE ..Création d'un fichier bitmap ligne par ligne

Pour clarifier les choses, je veux le faire:

  1. Ouvrez le fichier et écrire le bitmap en-tête (le cas échéant)
  2. Mettez 1 valeur scanline de données d'image dans une mémoire tampon (octet [])
  3. écrire le contenu de la mémoire tampon dans le fichier
  4. Répétez de 2 à moins que des lignes plus de balayage
  5. Proche de e fichier

Comment cela se fait-il en C#?

Merci,

Kreb

+0

sont u que, bitmap.save() nécessite une grande mémoire? – Benny

+0

Si vous voulez lire une ligne par ligne, vous devez implémenter vous-même le décodage du fichier source. Les fonctions intégrées chargeront toute l'image afaik. –

+0

@Benny: Désolé, je voulais dire que la route Bitmap.Save() nécessite que je charge l'image entière en mémoire, car je dois utiliser un pointeur sur ce bloc de mémoire pour enregistrer le fichier .. – krebstar

Répondre

0

@Mikael

Il ressemble à ceci:

int bufferSize = ((width +31) >> 5) << 2); // the width is in pixels, 1bpp, 
// so I had to round up to the nearest 32 bits 

byte[] buffer = new byte[bufferSize]; 
byte[] buffer = new byte[height * bufferSize]; 

for (int i = 0; i < height; i++) 
{ 
    getLine(buffer,bufferSize); 
    Buffer.BlockCopy(bufffer,0,bigBuffer, i*bufferSize, bufferSize); 
} 

unsafe 
{ 
    fixed (byte* ptr = bigBuffer) 
    { 
     using (Bitmap image = new Bitmap(width,height,bufferSize,System.Drawing.Imaging.PixelFormat.Format1bbIndexed, new IntPtr(ptr))) 
     { 
      image.SetResolution(xres,yres); 
      image.Save(filename,System.Drawing.Imaging.ImageFormat.Tiff); 
     } 
    } 
} 

Je suis inquiet que pour les images vraiment grandes, bigBuffer pourrait devenir trop grand .. Je voudrais changer cela pour écrire au fichier ligne par ligne, au lieu de l'écrire en une seule fois ..

Merci .. :)

+0

Ok, donc la bibliothèque C++ vous donne des octets décodés, que vous voulez enregistrer en TIFF. Si vous souhaitez enregistrer cette ligne par ligne, vous ne pouvez pas utiliser la classe Bitmap intégrée, mais vous devez rechercher une bibliothèque qui prend en charge l'écriture de bloc par bloc. Ou vous pouvez persister bigbuffer en tant que fichier mappé en mémoire, et le point IntPtr à la place. Cela vous épargnerait de l'utilisation de la mémoire physique.Cela dit, 32bit .Net peut contenir des données jusqu'à ~ 800mb avant que vous n'ayez des exceptions de mémoire, et 64bit autant que vous avez (plus ou moins). De quelles tailles de données parlons-nous? –

+0

Oui, c'est vrai :) Vraiment grand .. Je suis censé planifier des fichiers de 2 Go .. Pourriez-vous me donner un exemple ou me diriger vers un tutoriel sur les fichiers mappés en mémoire? Cela semble intéressant et semble être la clé :) – krebstar

+0

Découvrez http://github.com/tomasr/filemap/ ou le nouvel espace de noms System.IO.MemoryMappedFiles dans .Net 4.0. Vous pouvez également regarder mon projet http://mmf.codeplex.com pour l'utiliser. –

0

J'écrivais du code qui enregistrait un fichier JPEG de 32kx32k pixels. J'ai eu des tas de problèmes avec la création, le chargement, la visualisation et la manipulation (Photoshop peut gérer des fichiers jusqu'à 30kx30k). Après avoir essayé d'allouer j'ai laissé tomber l'affaire entière et a décidé de sauver des parties de la grande image à de petites images et écrire un programme de gestionnaire qui sait comment "assembler" ces fichiers en cas de besoin.

Je ne sais pas quand vous êtes pour, mais si elle est pour l'affichage, vous pouvez vérifier sur DeepZoom

+0

Merci, va vérifier cela quand j'ai le temps :) Merci :) – krebstar

Questions connexes