Я говорю, что у меня есть монохромное растровое изображение 240×60 с битовой глубиной 1, в байтовом массиве в памяти, как
BYTE bitMapBytes[2048]
Предполагая, что байты все и только байты данных изображения (без BITMAPINFOHEADER, BITMAPFILEHEADER), как сместить растровое изображение влево и вправо?
Например, как мне сдвинуть влево на 40 пикселей, с режимом обтекания?
В моих экспериментах у меня был некоторый успех с перемещением вправо, выполнив
int offset = 40;
for(int i = 0; i < bitmapBytes; i++){
newBitmapBytes[i] = oldBitmapBytes[i + offset];
}
Но я все еще понимаю, как работают растровые изображения — и сдвиг влево и обтекание байтов все еще немного сбивает меня с толку
Вы не очень хорошо объяснили свою цель, но я предполагаю, что вы хотите, чтобы «циклический переход» происходил на основе каждой строки. Итак N пиксели слева от каждой строки должны заканчиваться потоком справа от линии.
Просто сдвинув байты вокруг всего изображения, вы получите эти байты на предыдущий линии, потому что байты находятся в одномерной последовательности, и вы не создали никакой логики, чтобы обратить внимание на условную «ширину» вашего изображения.
Если вы хотите 2D-логику, вам нужно написать 2D-код.
Вот полный пример:
#include <iostream>
int main()
{
// Some constants
const size_t width = 6;
const size_t height = 4;
const size_t bitmapBytes = width*height;
// Actual data
char oldBitmapBytes[bitmapBytes] =
{
'1', '2', '3', '4', '5', '6',
'a', 'b', 'c', 'd', 'e', 'f',
'.', ',', '/', '~', '#', '$',
'!', '-', '!', '+', '!', '?'
};
char newBitmapBytes[bitmapBytes];
// Variables
const size_t x_offset = 2;
// Some utilities
auto convertCoordsToIndex = [&](const size_t x, const size_t y)
{
return y*width + x;
};
auto printBitmap = [&](const char* bitmapBytes)
{
for (size_t row = 0; row < height; row++)
{
for (size_t col = 0; col < width; col++)
std::cout << bitmapBytes[convertCoordsToIndex(col, row)];
std::cout << '\n';
}
};
// Display original bitmap
printBitmap(oldBitmapBytes);
// Shift by x_offset
for (size_t row = 0; row < height; row++)
{
for (size_t col = 0; col < width; col++)
{
const size_t adjustedCol = (col + x_offset) % width;
const size_t oldIndex = convertCoordsToIndex(col, row);
const size_t newIndex = convertCoordsToIndex(adjustedCol, row);
newBitmapBytes[newIndex] = oldBitmapBytes[oldIndex];
}
}
// Display shifted bitmap
std::cout << '\n';
printBitmap(newBitmapBytes);
}
// Output:
// 123456
// abcdef
// .,/~#$
// !-!+!?
//
// 561234
// efabcd
// #$.,/~
// !?!-!+
Интересный бит находится в самом низу, где я зацикливаюсь с учетом строк и столбцов, копируя байты из старого растрового изображения в новое, но используя прибавление (+
) а также по модулю (%
), чтобы компенсировать, какой столбец я копирую в каждом случае.
В конце концов, это просто математика!
Мы также можем сделать это на месте (т.е. не нужен второй массив), и делать это с std::rotate
делает вещи немного проще, может быть.
Обратите внимание, что это не будет работать для реальных растровых изображений в целом, так как многие форматы (включая BMP) имеют не только заголовки, но и заполнение строк. Вы должны были бы встроить некоторые пособия для этих вещей.
Других решений пока нет …