Split BMP into smaller Textures using Unity

I am currently trying to split a larger BMP (304x160) into smaller Bmp files (16x16) using C# script in unity. Unfortunately I cannot add the larger BMP file to the Project but must load it using System.IO as eventually this BMP file will be sent from a game server.

I’ve tried splitting the larger BMP into smaller BMPs using two methods:

  1. using System.Drawing.Graphics.DrawImage()
  2. using System.Drawing.Bitmap.Clone()

Unfortunately option #1 throws an Invalid Win32 GDI exception while Option #2 is throwing an “OutOfMemoryException”.

The end goal is: I need to split this larger BMP (which holds 2d textures), store these Texture2Ds in an array, so that I can apply each texture to a cube (instantiated prefab). Which texture to use is specified by the game server depending on the location of the cube.

I’m currently at a loss as how to get around these issues while working within the Unity Framework. (Yes I know using System.Drawing isn’t exactly in the framework but supoorted when I drag/dropped it into my Project).

Any suggestions are welcome!


Current Code attempts:

				public static bool BitmapToArray(out System.Drawing.Bitmap[,] tiles, System.Drawing.Bitmap bmpfile, int dimX, int dimY, int padX, int padY)
				{
					int itemsInX = (bmpfile.Width - padX) / (dimX + padX);
					int itemsInY = (bmpfile.Height - padY) / (dimY + padY);
					tiles = new Bitmap[itemsInX, itemsInY];
					
					for (int i = 0; i < itemsInY; i++)
					{
						for (int j = 0; j < itemsInX; j++)
						{
							//below caused errors
							//System.Drawing.Bitmap smallBMP = new System.Drawing.Bitmap(dimX, dimY);
							//Graphics g = Graphics.FromImage(smallBMP);
							//g.DrawImage (bmpfile, 0, 0, new Rectangle((j*dimX)+ padX,(i*dimY)+padY, dimX, dimY), GraphicsUnit.Pixel);
							//g.Dispose();
							//tiles[j,i] = smallBMP;
																							
							tiles[j,i] = bmpfile.Clone(new Rectangle((j*dimX)+ padX,(i*dimY)+padY, dimX, dimY),System.Drawing.Imaging.PixelFormat.Format32bppArgb);
						}
					}
					return true;
				}

You don’t need to break them up at all. Just adjust the UV coordinates of the cube’s material instance to the location on the texture. This has the added benefit of allowing all of your blocks to be dynamically batched for fewer drawcalls, which in-turn allows higher frame rates.

Checkout the material page in the Unity Docs for info about texture offsets. To discover the offsets you can manually set play with them in the inspector and evaluate which offsets each type of block should have.