Существует ли быстрая альтернатива созданию Texture2D от Растрового объекта в XNA?

Я озирался много и единственные методы, которые я нашел для создания Texture2D от Битового массива:

using  (MemoryStream s = new  MemoryStream())
{
   bmp.Save(s, System.Drawing.Imaging.ImageFormat.Png);
   s.Seek(0, SeekOrigin.Begin);
   Texture2D tx = Texture2D.FromFile(device, s);
}

и

Texture2D tx = new Texture2D(device, bmp.Width, bmp.Height,
                        0, TextureUsage.None, SurfaceFormat.Color);
tx.SetData<byte>(rgbValues, 0, rgbValues.Length, SetDataOptions.NoOverwrite);

Где rgbValues является массивом байтов, содержащим пиксельные данные битового массива в 32-разрядном формате ARGB.

Мой вопрос, там какие-либо более быстрые подходы, которые я могу попробовать?

Я пишу редактор карт, который должен читать в изображениях пользовательского формата (мозаики карты) и преобразовать их в структуры Texture2D для отображения. Предыдущая версия редактора, который был реализацией C++, преобразовала изображения сначала в битовые массивы и затем в структуры, которые будут оттянуты с помощью DirectX. Я делал попытку того же подхода здесь, однако оба из вышеупомянутых подходов являются значительно слишком медленными. Для загрузки в память, все структуры, требуемые для карты, занимают для первого подхода ~250 секунд и для второго подхода ~110 секунд на разумном компьютере спецификации (для сравнения, код C++ занял приблизительно 5 секунд). Если существует метод для редактирования данных структуры непосредственно (такой как с методом LockBits Растрового класса) затем, я смог бы преобразовать изображения пользовательского формата прямо в Texture2D и надо надеяться сохранить время обработки.

Любая справка очень ценилась бы.

Спасибо

9
задан Matthew Bowen 19 May 2010 в 22:15
поделиться

2 ответа

Вы хотите LockBits? Вы получите LockBits.

В моей реализации я передал GraphicsDevice от вызывающей стороны, чтобы сделать этот метод общим и статическим.

public static Texture2D GetTexture2DFromBitmap(GraphicsDevice device, Bitmap bitmap)
{
    Texture2D tex = new Texture2D(device, bitmap.Width, bitmap.Height, 1, TextureUsage.None, SurfaceFormat.Color);

    BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat);

    int bufferSize = data.Height * data.Stride;

    //create data buffer 
    byte[] bytes = new byte[bufferSize];    

    // copy bitmap data into buffer
    Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);

    // copy our buffer to the texture
    tex.SetData(bytes);

    // unlock the bitmap data
    bitmap.UnlockBits(data);

    return tex;
}
10
ответ дан 4 December 2019 в 09:12
поделиться

Я обнаружил, что мне нужно указать PixelFormat как .Format32bppArgb при использовании LockBits, поскольку вы предлагаете захватить изображения с веб-камеры.

        BitmapData bmd = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height),
            System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
        int bufferSize = bmd.Height * bmd.Stride;
        //create data buffer 
        byte[] bytes = new byte[bufferSize];
        // copy bitmap data into buffer
        Marshal.Copy(bmd.Scan0, bytes, 0, bytes.Length);

        // copy our buffer to the texture
        Texture2D t2d = new Texture2D(_graphics.GraphicsDevice, bmp.Width, bmp.Height, 1, TextureUsage.None, SurfaceFormat.Color);
        t2d.SetData<byte>(bytes);
        // unlock the bitmap data
        bmp.UnlockBits(bmd);
        return t2d;
3
ответ дан 4 December 2019 в 09:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: