User Rating 0.0
Total Usage 0 times
Drop BMP file here or click to browse Supports 24-bit and 32-bit uncompressed BMP
Is this tool helpful?

Your feedback helps us improve.

About

BMP files store pixel data in BGR order internally due to Windows GDI legacy conventions, yet external tools and APIs often expect RGB. Mismatched channel order produces images with inverted red-blue tones - skin appears cyan, skies turn orange. This converter performs direct byte-level swapping at offsets i and i+2 within each pixel triplet, preserving all other header data and metadata intact. The operation is lossless and reversible (applying twice restores the original).

Critical edge cases handled: row padding to 4-byte boundaries per BMP specification, negative height values indicating top-down scanline order, and 32-bit BMPs where the alpha channel at position 3 remains untouched. The tool rejects RLE-compressed BMPs (compression types 1 and 2) since channel swapping would corrupt the encoded data stream.

bmp converter rgb to bgr bgr to rgb color channel swap bitmap editor image processing pixel manipulation

Formulas

The RGB↔BGR swap operates on the byte level within each pixel. For a 24-bit BMP, each pixel occupies 3 consecutive bytes. The swap exchanges bytes at relative positions 0 and 2:

For each pixel at byte index i:
temp data[i]
data[i] data[i + 2]
data[i + 2] temp

Row padding ensures each scanline aligns to a 4-byte boundary. The padding calculation prevents reading into adjacent row data:

rowSize = width × bytesPerPixel
padding = (4 rowSize mod 4) mod 4
stride = rowSize + padding

Where bytesPerPixel = 3 for 24-bit or 4 for 32-bit BMPs. The stride represents the actual number of bytes per row including padding. Pixel data offset dataOffset is read from bytes 10-13 of the file header (little-endian 32-bit integer).

Reference Data

BMP FormatBits Per PixelChannelsStorage OrderSwap OperationSupported
Monochrome11IndexedN/A (palette)No
16 Color41IndexedN/A (palette)No
256 Color81IndexedN/A (palette)No
High Color163RGB555/RGB565Bit maskingNo
True Color243BGR[0]↔[2]Yes
True Color + Alpha324BGRA[0]↔[2]Yes
RLE-8 Compressed81EncodedN/ANo
RLE-4 Compressed41EncodedN/ANo
JPEG CompressedVariable3EmbeddedN/ANo
PNG CompressedVariable3-4EmbeddedN/ANo
Header FieldOffset (bytes)Size (bytes)DescriptionTypical Value
Signature02Magic bytes0x42 0x4D ("BM")
File Size24Total file sizeVariable
Reserved64Application-specific0
Data Offset104Pixel array start54 (no palette)
DIB Header Size144Header version40 (BITMAPINFOHEADER)
Width184Image width in pixelsVariable
Height224Image height (signed)Positive = bottom-up
Color Planes262Must be 11
Bits Per Pixel282Color depth24 or 32
Compression304Compression method0 (BI_RGB)
Image Size344Pixel data size0 or calculated
X Pixels/Meter384Horizontal resolution2835 (72 DPI)
Y Pixels/Meter424Vertical resolution2835 (72 DPI)
Colors Used464Palette entries0 (full palette)
Important Colors504Significant colors0 (all)

Frequently Asked Questions

Historical Windows GDI convention. When Microsoft defined the DIB format in the late 1980s, they chose BGR ordering to match the COLORREF structure used in Windows API calls. The x86 architecture's little-endian byte order made BGR natural for direct memory-mapped video buffers. This legacy persists for backward compatibility.
No. The operation is completely lossless. Only the red and blue byte positions within each pixel are exchanged. All header fields (dimensions, resolution, color depth), ICC profiles, and any application-specific reserved bytes remain untouched. The file size stays identical.
The image returns to its original state. The RGB↔BGR swap is its own inverse operation (mathematically, a self-inverse permutation). Converting BGR→RGB→BGR produces the identical byte sequence as the original file.
These formats use a color palette table where actual RGB values are stored, and pixel data contains only palette indices. Swapping bytes in the index data would reference wrong palette entries, producing garbage output. To convert these, you would need to swap channels in the palette entries themselves, not the pixel indices.
BMP specification mandates each scanline (row) padded to a 4-byte boundary. A 24-bit image of width 10 pixels has row size 30 bytes, requiring 2 padding bytes per row. The converter must skip these padding bytes to avoid swapping padding data into actual pixel values, which would corrupt the image.
Yes. OpenGL traditionally expects RGB ordering while DirectX uses BGR matching the BMP native format. If textures appear with swapped red-blue channels after loading, this tool corrects the source file. However, most modern graphics APIs provide format flags (GL_BGR, DXGI_FORMAT_B8G8R8A8) to handle this at load time without file modification.