2012-08-06 6 views
0

Je dois traiter (changer la luminosité, le contraste, etc.) de très grandes bitmaps de haute qualité (souvent plus de 10MPx) plusieurs fois par seconde et les mettre à jour à chaque fois (sur Image control dans WPF). Actuellement, j'utilise la bibliothèque AForge.NET pour le traitement d'image non géré, mais il y a quelques problèmes que je ne peux pas résoudre. Tout d'abord, une opération prend ~ 300ms (sans mettre à jour l'écran) ce qui n'est pas acceptable pour moi. Voici un exemple de code:Traitement de grandes images bitmap dans WPF

UnmanagedImage _img; 
BrightnessCorrection _brightness = new BrightnessCorrection(); 

void Load() 
{ 
    _img = UnmanagedImage.FromManagedImage((Bitmap)Bitmap.FromFile("image.jpg")); 
} 

void ChangeBrightness(int val) // this method is invoked by changing Slider value - several times per second 
{ 
    _brightness.AdjustValue = val; 
    _brightness.ApplyInPlace(_img); // it takes ~300ms for image 22MPx, no screen update - just change brightness "in background" 
} 

Je n'ai aucune expérience dans le traitement de l'image, mais je pense qu'il ne peut pas être beaucoup plus rapide car il est très haute résolution. Ai-je raison?

Un autre problème - comment mettre à jour efficacement l'écran? En ce moment je donne les résultats suivants (OFC très mauvaise) solution:

void ChangeBrightness(int val) 
{ 
    _brightness.AdjustValue = val; 
    _brightness.ApplyInPlace(_img); 

    using (MemoryStream ms = new MemoryStream()) 
    { 
     using (Bitmap b = _img.ToManagedImage()) 
     { 
      b.Save(ms, ImageFormat.Bmp); 
      ms.Seek(0, SeekOrigin.Begin); 

      var bmp = new BitmapImage(); 
      bmp.BeginInit(); 
      bmp.StreamSource = ms; 
      bmp.CacheOption = BitmapCacheOption.OnLoad; 
      bmp.EndInit(); 

      MyImageControl.Source = new WriteableBitmap(bmp); // !!! 
     } 
    } 
} 

Comme vous pouvez le voir, chaque fois que de nouvelles WriteableBitmap est créé (vous pouvez imaginer ce qui est happenin). Au lieu de ces « usings » J'ai essayé de cette façon:

WriteableBitmapSource.Lock(); // this object (of type WriteableBitmap) is just MVVM ViewModel's property which is binded to MyImageControl.Source 
    WriteableBitmapSource.Source.WritePixels(new Int32Rect(0, 0, _img.Width, _img.Height), _img.ImageData, _img.Stride * _img.Height * 3, _img.Stride, 0, 0); // image's PixelFormat is 24bppRgb 

... mais la méthode WritePixels jette « la valeur ne tombe pas dans la plage attendue. » Des idées pourquoi? Toute aide sera très appréciée :)

P.S. AForge.NET est-il un bon choix? Peut-être qu'il y a un meilleur traitement de l'image lib?

désolé pour mon anglais; P

+0

J'imagine que 10MP est votre problème - toute machine faisant cela va en souffrir. J'ai installé Photoshop et sur un fichier 6MP, il faut un moment pour changer le contraste/la luminosité de l'image. – Charleh

Répondre

0

~ 300ms pour l'image 22MPx est d'environ 20 ns par pixel. Cela devrait être à peu près juste.

Vous devez tenir compte du coût du processeur et du coût d'accès à la mémoire.

Si vous voulez améliorer encore ceci, considérez: 1) Utilisez plusieurs threads, chacun responsable d'une section de l'image bitmap. 2) Écrivez votre propre implémentation en utilisant les instructions SIMD. 3) Ne pas prétraiter le bitmap, transformer la ligne de balayage bitmap quand ils sont nécessaires.