И два растровых изображения в C # - PullRequest
1 голос
/ 09 сентября 2010

Я пытаюсь И две растровые изображения, как это:

        [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);
        }

Но я получаю исключение "Объект в настоящее время используется в другом месте" из оператора Draw. Перемещение оператора ReleaseHdc до выполнения оператора Draw, но без использования указанного растра.

Подход LockBits слишком медленный, поскольку он копирует весь растровый файл дважды, одно из растровых изображений огромно, и это должно происходить много раз в секунду

Есть идеи, как обмануть .NET в растровые изображения ANDing?

Ответы [ 2 ]

3 голосов
/ 09 сентября 2010
    lock (g.Clip)

Это не может работать. Вы получаете это исключение, потому что вы используете растровое изображение в более чем одном потоке. Я думаю, в другом потоке, который рисует растровое изображение. Чтобы это работало, вы должны убедиться, что два потока не могут использовать растровое изображение одновременно. И это действительно требует ключевого слова блокировки. Но на том же объекте блокировки. Используемый вами экземпляр Graphics не будет прежним. Замок не работает.

Создание выделенного объекта блокировки, который используют оба потока.

1 голос
/ 05 октября 2010

Несмотря на то, что вы нашли обходной путь, стоит отметить фактический источник исключения. Операции GDI и GDI + не могут чередоваться - одна или другая могут работать одновременно, но не одновременно.

В вашем коде вызов g.GetHdc() переводит графический объект в состояние, в котором вновь созданный HDC может использоваться для рендеринга GDI. Графический объект будет «использоваться» до вызова g.ReleaseHdc(). В этот момент HDC уничтожается, и объект Graphics можно снова использовать для рендеринга.

Отметив, что HDC, возвращенный вызовом к GetHdc(), не был создан и существует только до вызова к ReleaseHdc(), где он уничтожен, очевидно, что ROP не применяется к более поздним операциям, выполняемым Графический объект.

Если вам нужно было использовать GDI ROP, вам нужно было бы выполнить весь связанный рендеринг в чистом контексте GDI - используя Bitmap.GetHbitmap(), чтобы получить необходимые дескрипторы. Имейте в виду, что, как и Graphics.GetHdc(), HBITMAP заново создается из Bitmap, но не разделяет с ним состояние.

Более подробная информация о взаимодействии GDI / GDI + приведена в KB 311221

...