Dylan Green Ответов: 0

Как правильно вставить "куски" изображения в сетку на увеличенном изображении?


Проще говоря, мне нужна помощь в создании алгоритма, который помещает изображения в более крупное изображение в сетке.

В настоящее время я работаю над системой, которая может быть использована для генерации бесконечных случайных карт на основе координат x и y панели. Основной частью функциональности является возможность разбивать эту бесконечную карту на "панели", а также разбивать панели на "куски" (с целью организации, статистики, масштабирования и генерации). Система генерирует куски (при обработке перекрытий), а затем сшивает их вместе в панель.


Проблема, с которой я сталкиваюсь прямо сейчас, заключается в том, чтобы выяснить, как скопировать весь массив байтов из каждой панели и правильно разместить их в массиве байтов панели. Я предполагаю, что у других будут такие же проблемы с размещением изображений в больших изображениях в определенных местах, как и у меня. Я использую универсальную платформу Windows с использованием C#.

Что я уже пробовал:

Я пытался найти подобные алгоритмы, но они не работают с байтовыми массивами сами по себе. Только с большими библиотеками, которые не работают с UWP.

Система, которую я создал до сих пор, имеет несколько ключевых компонентов, которые суммируются моими MapPanel класс:
[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;
    }
}


Единственная оставшаяся часть алгоритма, с которой я лично борюсь, - это поиск "индекса пикселей", используемого при определении того, где в массиве разместить пиксели в новом увеличенном изображении. Циклы for, которые я установил, проходят через каждый пиксель каждого фрагмента. Массив "dataInBytes" работает слева направо и сверху вниз, как и любое растровое изображение, но работает в единицах по 4 байта (для представления значений BGRA). Любая помощь будет оценена по достоинству. Спасибо!

0 Ответов