C #: создание растрового изображения с использованием массива байтов - PullRequest
2 голосов
/ 04 мая 2009

Я пытаюсь динамически создать растровое изображение, используя байтовый массив, используя следующий код

Bitmap GetImage()
{
    IntPtr  ip = Marshal.AllocCoTaskMem(imagesize);

    //some code to fill ip

    Image img =  new Bitmap(
                    w,
                    h,
                    -stride,
                    PixelFormat.Format24bppRgb,
                    (IntPtr)(ip.ToInt32() + imagesize - stride)
                    );

    Marshal.FreeCoTaskMem( ip); // Comment this line to work

    return img;
}

void SaveImage()
{
    Image img =  GetImage();
    img.save("test.bmp"); // This call fails
    img.Dispose();
}

Теперь моя проблема в том, что я хочу вернуть битовую карту, но в то же время я не хочу сохранять указатель ip, так как память выделяет утечки. Это никогда не освобождается. Как я могу вернуть изображение, созданное с помощью байтового массива и не мешая вызывающей функции GetImage () освободить память.

Ответы [ 2 ]

4 голосов
/ 04 мая 2009

Самым простым способом может быть создание растрового изображения (хотя в аналогичном коде я использовал обычный byte[], а затем fixed блок, а не непосредственно с помощью AllocCoTaskMem), и затем создайте секунду Bitmap того же размера. Вызовите Graphics.FromImage во втором растровом изображении, затем Graphics.DrawImage, используя растровое изображение first , чтобы эффективно скопировать содержимое первого растрового изображения во второе. Затем вы можете вызвать Dispose для первого растрового изображения, освободить память и использовать второе растровое изображение, которое в основном является копией.

Возможно, есть более эффективный способ сделать это, если вы более опытны с изображениями, но если вы просто ищете способ заставить его работать, это отправная точка:)

РЕДАКТИРОВАТЬ: комментарий zachrrs действительно облегчает использование конструктора Bitmap (Image) :

using (Bitmap original = new Bitmap(...))
{
    Bitmap copy = new Bitmap(originalImage);
    // Then return "copy" from your method, and you can free the
    // memory
}
0 голосов
/ 04 мая 2009

Если вы знаете размеры заранее, почему бы не создать растровое изображение и не использовать метод Bitmap.LockBits для получения адреса входного буфера?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...