Click here to Skip to main content
15,888,062 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
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:
C#
[ComImport]
[Guid("5B0D3235-4DBA-4D44-865E-8F1D0E4FD04D")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
unsafe interface IMemoryBufferByteAccess 
{
    void GetBuffer(out byte* buffer, out uint capacity); //Allows access to raw pixel data via a buffer
}

public class MapPanel
{
    public const int PANEL_SIZE = 2400; //Must divide evenly by CHUNK_UNITS
    public const int CHUNK_UNITS = 16; //Must be a perfect square root


    //Panel variables here

    private MapChunk[,] chunks =
        new MapChunk[(int)Math.Sqrt(CHUNK_UNITS),(int)Math.Sqrt(CHUNK_UNITS)]; //Creates a 2D array of chunks


    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);



                // Fill-in the BGRA plane
                BitmapPlaneDescription bufferLayout = buffer.GetPlaneDescription(0);

                for (int chunk_x = 0; chunk_x < Math.Sqrt(chunks.Length); chunk_x++) //x - Chunk column (top-to-buttom)
                {
                    for (int chunk_y = 0; chunk_y < Math.Sqrt(chunks.Length); chunk_y++) //y - Chunk row (left-to-right)
                    {

                        for(int i = 0; i < PANEL_SIZE / CHUNK_UNITS; i++) //x - pixel column in chunk (top-to-bottom)
                        {
                            for (int j = 0; j < PANEL_SIZE / CHUNK_UNITS; j++) //y - pixel in chunk (left-to-right)
                            {
                                dataInBytes[bufferLayout.StartIndex /* +  Pixel Index */ + 0]
                                    = chunks[chunk_x, chunk_y].chunkData[i, j, 0]; //B
                                dataInBytes[bufferLayout.StartIndex /* +  Pixel Index */ + 1]
                                    = chunks[chunk_x, chunk_y].chunkData[i, j, 1]; //G
                                dataInBytes[bufferLayout.StartIndex /* +  Pixel Index */ + 2]
                                    = chunks[chunk_x, chunk_y].chunkData[i, j, 2]; //R
                                dataInBytes[bufferLayout.StartIndex /* +  Pixel Index */ + 3]
                                    = chunks[chunk_x, chunk_y].chunkData[i, j, 3]; //A
                            }
                        }
                    }
                }
            }
        }
        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!
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900