C / C ++ SHIFT / OFFSET /向左或向右移动位图?

时间:2018-11-02 14:40:35

标签: c++ c bitmap bitmapimage

我说我在内存的字节数组中有一个位深度为1的单色240x60位图,例如

BYTE bitMapBytes[2048]

假设所有字节都是图像图像的所有字节(无BITMAPINFOHEADER,BITMAPFILEHEADER),如何左右移动位图图像?

例如,如何以环绕行为向左移动40个像素?

在我的实验中,我成功地做到了向右移动

int offset = 40;
for(int i = 0; i < bitmapBytes; i++){
    newBitmapBytes[i] = oldBitmapBytes[i + offset];
}

但是我仍然了解位图的工作原理-向左移动并环绕字节仍然让我感到困惑

1 个答案:

答案 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
//   #$.,/~
//   !?!-!+

live demo

有趣的位在底部附近,在这里我以行感知和列感知的方式循环,将字节从旧的位图复制到新的位图中,但使用了 addition ({{1} }和 modulo +)来抵消我在每种情况下要复制的列。

最终,这只是数学!

我们也可以就地执行此操作(即不需要第二个数组),doing it with std::rotate可能会使事情稍微简单一些。

请注意,这通常不适用于实际的位图,因为许多格式(包括BMP)不仅具有标头,而且具有行填充。您必须为这些事情增加一些津贴。