0
votes

i would like to create a large bitmap or png-file using Microsoft XNA and C# in visual Studio. I have the normal Game1-Class with a spritebatch to draw on the screen. I am completely new and a noob in XNA. Everything works great when i want to display it in the game. But i need the option to export to any image-type like bmp or png. Now i have a problem, i want to create a bitmap-file which contains 100x100 tiles which have 64x64 pixels. I know, this is very large but i don`t care with my powerful PC. But i have two problems:

the first is that Microsoft XNA doesn't seem to support such large files the second problem: my code doesn't even work with very small tiles.

I really need some possibility to draw that large files at once. There are also lines from other methods which i want to draw in the future and those lines connect sereral blocks

EDIT: Is there a way to draw a texture2d into a System.Drawing.Bitmap? Creating a System.Drawing.Bitmap works with that size... Now i just have to fill my Tiles in!

EDIT 2: Maybe my language was a bit confusing. All i'd like to do is saving an existing level as a large bitmap or other image-format. For example for printing or putting it for a download that people have a map of the built level.

Here is my code (with a few added comments):

//Idea: creating another spritebatch
SpriteBatch spriteBatch = new SpriteBatch(Game1.graphics.GraphicsDevice);
spriteBatch.Begin();
//typical try and catch
try
{
    //The level is 100x100
    for (int x = 0; x < 100; x++)
    {
        for (int y = 0; y < 100; y++)
        {
            //this is just a test to check if my map contains a tile at this place
            if (this.blockContent[y, x].Foreground.Number != 65535)
            {
                //the tileSetBlock is a large tileset containing many recktangles for the single tiles
                //tileSheetBlock is the big sprite with the tiles
                //load the recktangle from the tileSetBlock depending on the block number at x/y
                bounds = Game1.tileSetBlock[(int)this.blockContent[y, x].Foreground.Number];
                //my idea: draw the sprite to the bitmap-file
                spriteBatch.Draw(Game1.tileSheetBlock, new Vector2((y * 64), (x * 64)), bounds, Color.White);
            }
        }
    }
    //here i wanted to create the texture
    Texture2D destination = new Texture2D(Game1.graphics.GraphicsDevice, 6400, 6400);
    //here i wanted to draw the content into my texture
    spriteBatch.Draw(destination, new Rectangle(0, 0, 6400, 6400), Color.White);
    //here i just wanted to save everything
    destination.SaveAsPng(new System.IO.FileStream(@"C:\test.png", System.IO.FileMode.CreateNew), 6400, 6400);
}

Maybe there is some framework or anything else which could help? Its no problem to keep large images in the memory, if this is the only way.

2
That is a very large graphic; even so, what errors are you getting?BradleyDotNET
by creating the bitmap it said its too large. So i think i will need an additional package. And with a smaller image it simply does not work. I think i misunderstood how to use a spritebatch... I would expec something like an object where i can draw the tiles and save it as an image. I didn't find any possibilityuser4823001
My understanding is that bitmaps larger than your video screen are always an iffy proposition.Loren Pechtel
but how can i draw them anyways? are there any other metods? Maybe i cannot use the XNA, but another framework to draw themuser4823001

2 Answers

0
votes

You never render a level by generating a whole bitmap out of it, it is inefficient and does not make sense at all.

Instead you use tile-based rendering and render only what's currently visible on the screen.

See my previous answer on GameDev on how to do that easily:

https://gamedev.stackexchange.com/questions/29121/organize-a-game-set/29930#29930

enter image description here

Another tool I wrote a while ago that might be helpful to you, it decomposes a level bitmap to tiles:

https://github.com/aybe/LevelDecomposer

Input:

enter image description here

Output:

enter image description here

And you most certainly want to generate your levels using a proper editor such as Tiled.

0
votes

It is old question but what you need for saving generated texture is RenderTarget which lets you draw over other stuff than your screen.

Currently what you do is:

  1. Draw Game1.tileSheetBlock into graphic Device
spriteBatch.Draw(Game1.tileSheetBlock, new Vector2((y * 64), (x * 64)), bounds, Color.White);
  1. You create new empty texture draw it and save that empty texture...
Texture2D destination = new Texture2D(Game1.graphics.GraphicsDevice, 6400, 6400);
            //here i wanted to draw the content into my texture
            spriteBatch.Draw(destination, new Rectangle(0, 0, 6400, 6400), Color.White);
            //here i just wanted to save everything
            destination.SaveAsPng(new System.IO.FileStream(@"C:\test.png",

 System.IO.FileMode.CreateNew), 6400, 6400);

What you need is:

  1. Create RenderTarget with desired dimensions
RenderTarget2D renderTarget = new RenderTarget2D(Game1.graphics.GraphicsDevice, 6400, 6400);
  1. Set it as preferred output of your spritebatches
Game1.graphics.GraphicsDevice.SetRenderTarget(renderTarget);
  1. Draw!
spriteBatch.Draw(Game1.tileSheetBlock, new Vector2((y * 64), (x * 64)), bounds, Color.White);
  1. Reset render target so you can draw at screen again :)
gd.SetRenderTarget(null);

As RenderTarget is Texture2D you can do all stuff related to texture with it too (like saving and so on) :)