2010-09-09 17 views
0

Je suis en train de et deux bitmaps comme celui-ci:et deux bitmaps en C#

 
     [DllImport("gdi32.dll")] 
     public static extern int SetROP2(IntPtr hDC, int nDrawMode); 

     const int SRCAND = 0x008800C6; // AND raster op. 

     lock (g.Clip) 
     { 
      IntPtr pDC = g.GetHdc(); 
      SetROP2 (pDC, SRCAND); 
      g.DrawImageUnscaled (currentBitmap, bound.Location); 
      g.ReleaseHdc (pDC); 
     } 

Mais je reçois une exception « objet est actuellement utilisé ailleurs » de la déclaration de tirage au sort. Déplacer l'instruction ReleaseHdc avant que l'instruction Draw s'exécute, mais n'utilise pas l'opérande raster spécifiée. L'approche LockBits est trop lente, car elle copie l'intégralité du bitmap deux fois, l'une des bitmaps est énorme, et cela doit se produire plusieurs fois par seconde.

Des idées pour tromper .NET dans les bitmaps ANDing?

Répondre

3
lock (g.Clip) 

Cela ne peut pas fonctionner. Vous obtenez cette exception car vous utilisez le bitmap dans plusieurs threads. Je devinerais à un autre fil qui dessine l'image bitmap. Pour que cela fonctionne, vous devez vous assurer que les deux threads ne peuvent pas utiliser le bitmap en même temps. Et cela nécessite en effet le mot clé lock. Mais sur le même objet de verrouillage. L'occurrence de Graphics que vous utilisez ne sera pas la même. La serrure ne fonctionne pas.

Créez un objet de verrouillage dédié que les deux threads utilisent.

+0

Je l'ai utilisé le même objet de verrouillage pour les deux endroits qui peuvent attirer, mais je me fais toujours la même erreur. Cela fonctionne si je sors l'appel SetROP2. Si le problème était plusieurs threads utilisant le même bitmap ou objet graphique, le problème ne resterait-il pas? – user20493

+0

Trouvé une solution: Utiliser une couleur transparente pour l'arrière-plan bitmap donne le même effet dans ce cas. Merci pour la suggestion Hans. – user20493

0

Bien que vous ayez trouvé une solution de contournement, il est important de noter la source réelle de l'exception. Les opérations GDI et GDI + ne peuvent pas être entrelacées: l'une ou l'autre peut fonctionner à la fois, mais pas les deux.

Dans votre code, l'appel g.GetHdc() fait passer l'objet Graphics dans un état où le HDC nouvellement créé peut être utilisé pour le rendu GDI. L'objet Graphics sera alors "utilisé" jusqu'à ce que vous appeliez g.ReleaseHdc(). À ce stade, le HDC est détruit et l'objet Graphics peut être réutilisé pour le rendu. En notant que le HDC renvoyé par l'appel à n'a pas été créé et n'existe que jusqu'à l'appel à ReleaseHdc(), où il est détruit, il est évident que le ROP n'est pas appliqué aux opérations ultérieures effectuées par l'objet Graphics.

Si vous aviez besoin d'utiliser des ROP GDI, vous auriez à faire tout le rendu associé dans un contexte GDI pur - en utilisant Bitmap.GetHbitmap() pour obtenir les handles nécessaires. Soyez conscient que similaire à Graphics.GetHdc(), le HBITMAP est nouvellement créé à partir du Bitmap, mais ne partage aucun état avec celui-ci.

Plus de détails sur GDI/GDI + Interop sont données dans KB 311221