3
\$\begingroup\$

I have built a level editor for an XNA-based Megaman clone I am working on and one of the features I would like to implement is the ability to save a full-resolution map of the entire level (like this one). My problem is that the levels can be arbitrarily large and XNA has a texture size limit of 4028x4028. I don't need to use the texture for anything in the editor itself, only to save it to disk.

I have stored the image data in an array using game.GraphicsDevice.GetBackBufferData, but I am having trouble finding a way to store this to disk in a readable format (preferably PNG). Everything I've found online says to use the Texture2D.SetData and Texture2D.SaveAsPng methods, but those calls are restricted to the 4028x4028 max texture size.

Any suggestions?

Note: I do realize that the example map I linked above was likely created by hand and while I could certainly output multiple full-resolution images of each screen and put them together by hand in Photoshop, I would like the process to be available directly in the editor if possible.

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

As far as I know there's no way around Texture2D size limit, so my suggestion is the following:

  1. Add a reference to System.Drawing to your project.
  2. Create an instance of System.Drawing.Bitmap to store your map. I don't think there's a size limit using Bitmap, because I even tried with sizes over 15000 pixels wide and it worked.
  3. Write your data to the Bitmap. The easy but slow way is to use Bitmap.SetPixel. The harder but significantly faster way is to use Bitmap.LockBits (documentation). You'll also need to convert your colors from Microsoft.Xna.Framework.Color to System.Drawing.Color but that is easy with System.Drawing.Color.FromArgb.
  4. Save Bitmap as a PNG to file by calling Save with ImageFormat.Png as the second parameter.

Example using the slow method:

bitmap = new Bitmap(width, height);
for (int x = 0; x != width; ++x)
    for (int y = 0; y != height; ++y)
       bitmap.SetPixel(x, y, System.Drawing.Color.Red);
bitmap.Save("level.png", ImageFormat.Png);

But I warn you that it will perform extremely slow, so use it only as a test drive, and then switch over to the LockBits method.

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .