User Rating 0.0
Total Usage 0 times

Drop a .bmp file here or click to browse

Supports 24-bit and 32-bit uncompressed BMP files

Is this tool helpful?

Your feedback helps us improve.

About

BMP (Bitmap) files store pixel color channels in BGR order - Blue first, then Green, then Red - a legacy of the Windows GDI specification from 1990. Many image processing pipelines, particularly those using OpenCV or raw framebuffer data, output BGR-ordered bitmaps that display with inverted Red and Blue channels in software expecting standard RGB order. A portrait with natural skin tones rendered in BGR appears with blue-tinted faces and orange skies. This tool performs a precise binary-level channel swap on the pixel data array of .bmp files, converting each pixel triplet from BGR to RGB (or vice versa, since the operation is symmetric). It parses the BMP file header, DIB info header, and raw pixel buffer at the byte level without re-encoding or lossy compression.

The converter handles 24-bit and 32-bit uncompressed BMPs, correctly accounting for row padding to 4-byte boundaries and both top-down and bottom-up scanline orders. Note: compressed BMPs (RLE4, RLE8) and indexed-color formats (1/4/8-bit) are not supported because their pixel data is palette-referenced, not direct BGR triplets. All processing occurs entirely in your browser. No file data leaves your machine.

bgr to rgb bitmap converter bmp channel swap bgr rgb bitmap pixel order bmp converter image converter

Formulas

The BGR to RGB conversion is a symmetric byte-swap operation applied to every pixel in the raw pixel data array. For a 24-bit BMP, each pixel occupies 3 consecutive bytes. The swap exchanges the first and third bytes while leaving the second unchanged.

For each pixel at byte offset i in the pixel data buffer:

R buffer[i] (was Blue)
buffer[i] buffer[i + 2] (Red moves to position 0)
buffer[i + 2] R (Blue moves to position 2)

Row stride (bytes per scanline including padding):

stride = ceil(bpp × w32) × 4

Where bpp = bits per pixel (24 or 32), w = image width in pixels. The pixel loop iterates row by row, advancing by stride bytes per row, and within each row processes w pixels spaced bpp8 bytes apart. Padding bytes at the end of each row are not modified. Since swapping byte 0 and byte 2 is its own inverse, the same operation converts RGB back to BGR. The function f(f(x)) = x - the transform is an involution.

Reference Data

BMP PropertyLocation (Byte Offset)SizeDescription
Magic Bytes0x002 bytes0x42 0x4D ("BM" in ASCII)
File Size0x024 bytesTotal file size in bytes (LE uint32)
Reserved0x064 bytesApplication-specific; usually 0
Pixel Data Offset0x0A4 bytesOffset from file start to pixel array
DIB Header Size0x0E4 bytes40 = BITMAPINFOHEADER, 108 = V4, 124 = V5
Image Width0x124 bytesWidth in pixels (signed int32)
Image Height0x164 bytesHeight in pixels (signed; negative = top-down)
Color Planes0x1A2 bytesMust be 1
Bits Per Pixel0x1C2 bytes24 (BGR) or 32 (BGRA)
Compression0x1E4 bytes0 = BI_RGB (none), 3 = BI_BITFIELDS
Raw Image Size0x224 bytesSize of pixel data (may be 0 if uncompressed)
H Resolution0x264 bytesPixels per meter (horizontal)
V Resolution0x2A4 bytesPixels per meter (vertical)
Colors Used0x2E4 bytesNumber of palette colors (0 = default)
Important Colors0x324 bytesNumber of important colors (0 = all)
Row PaddingCalculatedVariableEach row padded to 4-byte boundary
Scanline OrderHeight sign - Positive height = bottom-up; Negative = top-down
Pixel Byte Order (24-bit)Pixel offset3 bytesByte 0 = Blue, Byte 1 = Green, Byte 2 = Red
Pixel Byte Order (32-bit)Pixel offset4 bytesByte 0 = Blue, Byte 1 = Green, Byte 2 = Red, Byte 3 = Alpha

Frequently Asked Questions

The BMP file format (per Microsoft's BITMAPINFOHEADER spec) stores pixel color components in BGR byte order - Blue at the lowest memory address, then Green, then Red. Software that expects RGB order (such as many Linux framebuffer viewers, web browsers via Canvas, or OpenGL texture loaders) will interpret the Blue byte as Red and vice versa, resulting in blue-tinted skin, orange skies, and inverted color appearance. This converter performs the byte-level swap to correct the channel order.
No. The operation is lossless and size-preserving. Only two bytes per pixel are transposed in the raw pixel buffer. No re-encoding, compression, or resampling occurs. The output file is byte-identical to the input except for the swapped R and B channel bytes in each pixel triplet. File size remains exactly the same.
No. Indexed-color BMPs use a color palette (color table) where each pixel value is an index into that table, not a direct BGR triplet. Swapping bytes in the pixel data of an indexed BMP would corrupt the index values. To fix channel order in a paletted BMP, you would need to swap the R and B entries within the palette itself - a different operation not covered by this tool.
For 32-bit BMPs, each pixel is stored as 4 bytes: Blue, Green, Red, Alpha. The converter swaps byte 0 (Blue) and byte 2 (Red), leaving byte 1 (Green) and byte 3 (Alpha) untouched. The alpha channel is fully preserved. The result is RGBA byte order.
Yes. The operation is symmetric (an involution). Swapping the first and third bytes twice returns to the original state. Mathematically, if f is the swap function, then f(f(x)) = x. You can use this same tool to convert in either direction.
The BMP specification requires each scanline to be aligned to a 4-byte (DWORD) boundary for efficient memory access on x86 architectures. For a 24-bit image with width w, the raw row size is w × 3 bytes. If this is not divisible by 4, 1-3 null padding bytes are appended. For example, a 24-bit image with width 5 has raw row size 15 bytes, padded to 16. The converter skips these padding bytes during the swap.
In the BMP header, the height field is a signed 32-bit integer. A positive value indicates bottom-up storage - the first row in the file is the bottom row of the image. A negative value indicates top-down storage - the first row is the top. This converter handles both cases transparently since the channel swap is independent of scanline order; it simply processes every pixel regardless of row direction.