Texture2D di XNA hanya bisa menampung begitu banyak. Bergantung pada profil mana yang saya gunakan batasnya adalah 2048 atau 4096 piksel. Sejauh yang saya tahu dari penelitian saya (seseorang mengoreksi saya jika saya salah) Gambar GDI tidak memiliki batasan selain tidak melebihi memori pengguna.
Saya mencari cara yang paling efisien untuk mengambil Gambar GDI dan sumber persegi panjang (dalam batasan ukuran XNA) dan membuat Texture2D baru dari data saat runtime. Proses ini juga harus memperhitungkan alfa pra-berlipat ganda XNA 4.0!
ATAU...
Cara untuk mengambil Texture2D.FromStream dan mengadaptasinya sehingga dibutuhkan sumber persegi panjang juga, karena itu akan lebih baik untuk kebutuhan saya.
Persyaratannya adalah:
- Tidak ada pipa konten, saya harus dapat memuatnya saat runtime.
- Gunakan hanya Jangkauan profil jika memungkinkan!
- Hanya peduli dengan Windows. Jangan khawatir tentang portabilitas.
TL; DR:
Saya memerlukan metode seperti:
Texture2D Texture2DHelper.FromStream(GraphicsDevice, Stream, SourceRectangle);
Atau
Texture2D Texture2DHelper.FromImage(Image, SourceRectangle)
Lebih disukai yang pertama.
Gambar besar:
Mengabaikan persegi panjang sumber sesaat (untuk mempermudah visualisasi), saya telah mencoba memuat seluruh tekstur dalam GDI dan meneruskan data ke Texture2D menggunakan pendekatan brute force:
using (System.Drawing.Image image = System.Drawing.Image.FromFile(path))
{
int w = image.Width;
int h = image.Height;
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(image);
uint[] data = new uint[w * h];
for (int i=0; i!=bitmap.Width; ++i)
{
for (int j=0; j!=bitmap.Height; ++j)
{
System.Drawing.Color pixel = bitmap.GetPixel(i, j);
Microsoft.Xna.Framework.Color color = Color.FromNonPremultiplied(pixel.R, pixel.G, pixel.B, pixel.A);
data[i + j * w] = color.PackedValue;
}
}
_texture = new Texture2D(device, w, h);
_texture.SetData(data);
}
Dan hasilnya sangat lambat. Butuh beberapa kali lebih lama daripada sekadar melakukan:
Texture2D.FromStream(GraphicsDevice, new FileStream(path, FileMode.Open));
Saya juga berpikir tentang menggunakan Bitmap.LockBits dan Block Copy tetapi melakukan itu akan meninggalkan koreksi alpha pra-dikalikan, dan saya tidak tahu bagaimana menerapkannya setelah salinan.
Saya tergoda untuk berpikir bahwa solusi yang lebih baik adalah bekerja di sekitar Texture2D.FromStream secara langsung ... Saya tidak terlalu akrab dengan cara kerja Stream tetapi saya telah melihat beberapa metode di .NET yang mengambil Stream dan Rectangle. Bagaimana saya mencapai sesuatu seperti itu? Baik metode FromStream yang sama sekali baru atau pembungkus di sekitar Stream yang menyediakan fungsionalitas "Rectangle".