Un Texture2D en XNA solo puede contener tanto. Dependiendo de qué perfil utilizo, ese límite es de 2048 o 4096 píxeles de ancho. Por lo que pude ver en mi investigación (alguien me corrige si estoy equivocado), las imágenes GDI no tienen ninguna otra limitación que no sea exceder la memoria del usuario.
Estoy buscando la forma más eficiente de tomar una imagen GDI y un rectángulo de origen (dentro de las limitaciones de tamaño de XNA) y crear una nueva Texture2D a partir de esos datos en tiempo de ejecución. ¡El proceso también debe tener en cuenta el alfa pre-multiplicado de XNA 4.0!
O...
Una forma de tomar Texture2D.FromStream y adaptarlo para que también tome un rectángulo fuente, ya que eso sería aún mejor para mis necesidades.
Los requisitos son:
- Sin canalización de contenido, necesito poder cargarlos en tiempo de ejecución.
- ¡Usando solo el perfil Reach si es posible!
- Solo se preocupan por Windows. No te preocupes por la portabilidad.
TL; DR:
Necesito un método como:
Texture2D Texture2DHelper.FromStream(GraphicsDevice, Stream, SourceRectangle);
O
Texture2D Texture2DHelper.FromImage(Image, SourceRectangle)
Preferiblemente el primero.
Cuadro grande:
Ignorando el rectángulo de origen por un momento (para hacer que las cosas sean más fáciles de visualizar), he intentado cargar una textura completa en GDI y pasar los datos a un Texture2D usando un enfoque completamente de fuerza bruta:
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);
}
Y el resultado fue realmente lento. Tomó muchas más veces que simplemente hacer:
Texture2D.FromStream(GraphicsDevice, new FileStream(path, FileMode.Open));
También pensé en usar Bitmap.LockBits y Block Copy, pero hacer eso dejaría de lado la corrección alfa pre-multiplicada, y no sé cómo aplicarla después de la copia.
Estoy tentado a pensar que una mejor solución sería trabajar directamente con Texture2D. Desde StreamStream ... No estoy muy familiarizado con el funcionamiento de Stream, pero he visto algunos métodos en .NET que toman un Stream y un Rectángulo. ¿Cómo lograría algo así? Ya sea un método FromStream completamente nuevo o un contenedor alrededor de cualquier Stream que proporcione la funcionalidad "Rectángulo".