Я озирался много и единственные методы, которые я нашел для создания 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 и надо надеяться сохранить время обработки.
Любая справка очень ценилась бы.
Спасибо
Вы хотите 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;
}
Я обнаружил, что мне нужно указать 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;