我说我在内存的字节数组中有一个位深度为1的单色240x60位图,例如
BYTE bitMapBytes[2048]
假设所有字节都是图像图像的所有字节(无BITMAPINFOHEADER,BITMAPFILEHEADER),如何左右移动位图图像?
例如,如何以环绕行为向左移动40个像素?
在我的实验中,我成功地做到了向右移动
int offset = 40;
for(int i = 0; i < bitmapBytes; i++){
newBitmapBytes[i] = oldBitmapBytes[i + offset];
}
但是我仍然了解位图的工作原理-向左移动并环绕字节仍然让我感到困惑
答案 0 :(得分:2)
您没有很好地说明您的目标,但我想您希望“换行”以每行为基础。因此,每行左侧的 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
// #$.,/~
// !?!-!+
有趣的位在底部附近,在这里我以行感知和列感知的方式循环,将字节从旧的位图复制到新的位图中,但使用了 addition ({{1} }和 modulo (+
)来抵消我在每种情况下要复制的列。
最终,这只是数学!
我们也可以就地执行此操作(即不需要第二个数组),doing it with std::rotate
可能会使事情稍微简单一些。
请注意,这通常不适用于实际的位图,因为许多格式(包括BMP)不仅具有标头,而且具有行填充。您必须为这些事情增加一些津贴。