Put simply, I need help creating an algorithm that places the images in a larger image in a grid.
Currently, I'm working on a system that can be used to generate infinite random maps based on the x and y coordinates of a panel. A core piece of functionality is the ability to subdivide this infinite map into "panels", and subdivide panels into "chunks" (for the purpose of organization, statistics, scaling, and generation). The system generates the chunks (while handling overlaps), then sews them together into the panel.
The issue I'm running into right now is figuring out how to copy the entire byte array from each of the panels, and properly placing them in the byte array of the panel. I presume others will have similar issues placing images in larger images at specific locations much like I do. I'm utilizing the Universal Windows Platform using C#.
What I have tried:
I've tried finding similar algorithms, but they do not work with byte arrays themselves. Only with larger libraries that do not work with the UWP.
The system I have set up thus far has a few key components, which are summarized by my
MapPanel
class:
[ComImport]
[Guid("5B0D3235-4DBA-4D44-865E-8F1D0E4FD04D")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
unsafe interface IMemoryBufferByteAccess
{
void GetBuffer(out byte* buffer, out uint capacity);
}
public class MapPanel
{
public const int PANEL_SIZE = 2400;
public const int CHUNK_UNITS = 16;
private MapChunk[,] chunks =
new MapChunk[(int)Math.Sqrt(CHUNK_UNITS),(int)Math.Sqrt(CHUNK_UNITS)];
public MapPanel()
{
for(int x = 0; x < Math.Sqrt(CHUNK_UNITS); x++)
{
for (int y = 0; y < Math.Sqrt(CHUNK_UNITS); y++)
{
chunks[x, y] = new MapChunk();
}
}
}
public unsafe SoftwareBitmap GetBitmap()
{
SoftwareBitmap panelBitmap =
new SoftwareBitmap(BitmapPixelFormat.Bgra8, PANEL_SIZE, PANEL_SIZE, BitmapAlphaMode.Premultiplied);
using (BitmapBuffer buffer = panelBitmap.LockBuffer(BitmapBufferAccessMode.Write))
{
using (var reference = buffer.CreateReference())
{
byte* dataInBytes;
uint capacity;
((IMemoryBufferByteAccess)reference).GetBuffer(out dataInBytes, out capacity);
BitmapPlaneDescription bufferLayout = buffer.GetPlaneDescription(0);
for (int chunk_x = 0; chunk_x < Math.Sqrt(chunks.Length); chunk_x++)
{
for (int chunk_y = 0; chunk_y < Math.Sqrt(chunks.Length); chunk_y++)
{
for(int i = 0; i < PANEL_SIZE / CHUNK_UNITS; i++)
{
for (int j = 0; j < PANEL_SIZE / CHUNK_UNITS; j++)
{
dataInBytes[bufferLayout.StartIndex + 0]
= chunks[chunk_x, chunk_y].chunkData[i, j, 0];
dataInBytes[bufferLayout.StartIndex + 1]
= chunks[chunk_x, chunk_y].chunkData[i, j, 1];
dataInBytes[bufferLayout.StartIndex + 2]
= chunks[chunk_x, chunk_y].chunkData[i, j, 2];
dataInBytes[bufferLayout.StartIndex + 3]
= chunks[chunk_x, chunk_y].chunkData[i, j, 3];
}
}
}
}
}
}
return panelBitmap;
}
}
The only remaining piece of the algorithm that I personally struggle with is finding the "pixel index" used when determining where in the array to place the pixels in the new larger image. The for loops I have set up run through every pixel of every chunk. The array "dataInBytes" runs left-to-right and top-to-bottom like every bitmap, but runs in units of 4 bytes (to represent BGRA values). Any help would be appreciated. Thank you!