The bitcount=8, which means that a colour table (palette) is mandatory - see here. That means that the values in the pixel array (i.e. your variable bmpImageData
) are not colours, but actually indexes into the palette. As such, you cannot sensibly directly modify the bmpImageData
.
So, if pixel[0,0] contains, say, 3, you have to look up the 3rd entry in the colour palette to work out what colour that corresponds to.
The palette should be after the BITMAPINFOHEADER and the DIB, so it is from byte 55-435.
I suggest you print out those bytes in hex and have a look at them. I am guessing you will see that they go RGBA, RGBA, RGBA but that the A (alpha or transparency) will be zero, i.e. unused. So I would expect them to look like this, with R=G=B (since they are greyscale):
xx xx xx 00 yy yy yy 00 zz zz zz 00
Then, in order to invert your image, change each xx
to 255-xx
(and likewise y
and z
) there in the palette without needing to process all the bmpImageData
at all.
There are some inconsistencies in my answer, but that is because I can only see a JPEG
file when I am trying to debug a BMP
file. One inconsistency is that the space between the DIB and the pixel array is 436-54 bytes, i.e. 382 bytes which is not divisible by 3 or 4 and therefore doesn't make for a very sensible palette size using either 3 or 4 bytes per entry... but grab the hex data and we will take a look and see if we can get closer to a correct answer.
If you use ImageMagick (available for free for Unix/Linux and Windows from here), you can use the identify
command as follows to help you debug your code:
identify -verbose lena.bmp
Format: BMP (Microsoft Windows bitmap image)
Class: PseudoClass
Geometry: 512x512+0+0
Units: PixelsPerCentimeter
Type: Grayscale
Base type: Grayscale
Endianess: Undefined
Colorspace: Gray
Depth: 8-bit
Channel depth:
gray: 8-bit
Channel statistics:
Pixels: 262144
Gray:
min: 28 (0.109804)
max: 244 (0.956863)
mean: 124.071 (0.486554)
standard deviation: 47.9288 (0.187956)
kurtosis: -0.839484
skewness: -0.0822738
Colors: 28
Histogram:
474: ( 28, 28, 28) #1C1C1C gray(28)
4477: ( 36, 36, 36) #242424 gray(36)
13395: ( 44, 44, 44) #2C2C2C gray(44)
15131: ( 52, 52, 52) #343434 gray(52)
9461: ( 60, 60, 60) #3C3C3C gray(60)
6569: ( 68, 68, 68) #444444 gray(68)
7027: ( 76, 76, 76) #4C4C4C gray(76)
7733: ( 84, 84, 84) #545454 gray(84)
10330: ( 92, 92, 92) #5C5C5C gray(92)
14865: (100,100,100) #646464 gray(100)
12095: (108,108,108) #6C6C6C gray(108)
11631: (116,116,116) #747474 gray(116)
16153: (124,124,124) #7C7C7C gray(124)
17429: (132,132,132) #848484 gray(132)
17623: (140,140,140) #8C8C8C gray(140)
18636: (148,148,148) #949494 gray(148)
19688: (156,156,156) #9C9C9C gray(156)
12554: (164,164,164) #A4A4A4 gray(164)
9848: (172,172,172) #ACACAC gray(172)
7380: (180,180,180) #B4B4B4 gray(180)
5589: (188,188,188) #BCBCBC gray(188)
7162: (196,196,196) #C4C4C4 gray(196)
7451: (204,204,204) #CCCCCC gray(204)
6699: (212,212,212) #D4D4D4 gray(212)
2293: (220,220,220) #DCDCDC gray(220)
425: (228,228,228) #E4E4E4 gray(228)
22: (236,236,236) #ECECEC gray(236)
4: (244,244,244) #F4F4F4 gray(244)
Colormap entries: 256
Colormap:
0: ( 0, 0, 0) #000000 gray(0)
1: (128, 0, 0) #800000 gray(128)
2: ( 0,128, 0) #008000 gray(0)
3: (128,128, 0) #808000 gray(128)
4: ( 0, 0,128) #000080 gray(0)
5: (128, 0,128) #800080 gray(128)
6: ( 0,128,128) #008080 gray(0)
7: (128,128,128) #808080 gray(128)
8: ( 28, 28, 28) #1C1C1C gray(28)
9: (140,140,140) #8C8C8C gray(140)
10: ( 84, 84, 84) #545454 gray(84)
11: (196,196,196) #C4C4C4 gray(196)
12: ( 60, 60, 60) #3C3C3C gray(60)
13: (172,172,172) #ACACAC gray(172)
14: (116,116,116) #747474 gray(116)
15: (228,228,228) #E4E4E4 gray(228)
16: ( 44, 44, 44) #2C2C2C gray(44)
17: (156,156,156) #9C9C9C gray(156)
18: (100,100,100) #646464 gray(100)
19: (212,212,212) #D4D4D4 gray(212)
20: ( 76, 76, 76) #4C4C4C gray(76)
21: (188,188,188) #BCBCBC gray(188)
22: (132,132,132) #848484 gray(132)
23: (244,244,244) #F4F4F4 gray(244)
24: ( 36, 36, 36) #242424 gray(36)
25: (148,148,148) #949494 gray(148)
26: ( 92, 92, 92) #5C5C5C gray(92)
27: (204,204,204) #CCCCCC gray(204)
28: ( 68, 68, 68) #444444 gray(68)
29: (180,180,180) #B4B4B4 gray(180)
30: (124,124,124) #7C7C7C gray(124)
31: (236,236,236) #ECECEC gray(236)
32: ( 52, 52, 52) #343434 gray(52)
33: (164,164,164) #A4A4A4 gray(164)
34: (108,108,108) #6C6C6C gray(108)
35: (220,220,220) #DCDCDC gray(220)
36: ( 0, 0, 0) #000000 gray(0)
37: ( 0, 0, 0) #000000 gray(0)
38: ( 0, 0, 0) #000000 gray(0)
39: ( 0, 0, 0) #000000 gray(0)
40: ( 0, 0, 0) #000000 gray(0)
41: ( 0, 0, 0) #000000 gray(0)
42: ( 0, 0, 0) #000000 gray(0)
43: ( 0, 0, 0) #000000 gray(0)
44: ( 0, 0, 0) #000000 gray(0)
45: ( 0, 0, 0) #000000 gray(0)
46: ( 0, 0, 0) #000000 gray(0)
47: ( 0, 0, 0) #000000 gray(0)
48: ( 0, 0, 0) #000000 gray(0)
49: ( 0, 0, 0) #000000 gray(0)
50: ( 0, 0, 0) #000000 gray(0)
51: ( 0, 0, 0) #000000 gray(0)
52: ( 0, 0, 0) #000000 gray(0)
53: ( 0, 0, 0) #000000 gray(0)
54: ( 0, 0, 0) #000000 gray(0)
55: ( 0, 0, 0) #000000 gray(0)
56: ( 0, 0, 0) #000000 gray(0)
57: ( 0, 0, 0) #000000 gray(0)
58: ( 0, 0, 0) #000000 gray(0)
59: ( 0, 0, 0) #000000 gray(0)
60: ( 0, 0, 0) #000000 gray(0)
61: ( 0, 0, 0) #000000 gray(0)
62: ( 0, 0, 0) #000000 gray(0)
63: ( 0, 0, 0) #000000 gray(0)
64: ( 0, 0, 0) #000000 gray(0)
65: ( 0, 0, 0) #000000 gray(0)
66: ( 0, 0, 0) #000000 gray(0)
67: ( 0, 0, 0) #000000 gray(0)
68: ( 0, 0, 0) #000000 gray(0)
69: ( 0, 0, 0) #000000 gray(0)
70: ( 0, 0, 0) #000000 gray(0)
71: ( 0, 0, 0) #000000 gray(0)
72: ( 0, 0, 0) #000000 gray(0)
73: ( 0, 0, 0) #000000 gray(0)
74: ( 0, 0, 0) #000000 gray(0)
75: ( 0, 0, 0) #000000 gray(0)
76: ( 0, 0, 0) #000000 gray(0)
77: ( 0, 0, 0) #000000 gray(0)
78: ( 0, 0, 0) #000000 gray(0)
79: ( 0, 0, 0) #000000 gray(0)
80: ( 0, 0, 0) #000000 gray(0)
81: ( 0, 0, 0) #000000 gray(0)
82: ( 0, 0, 0) #000000 gray(0)
83: ( 0, 0, 0) #000000 gray(0)
84: ( 0, 0, 0) #000000 gray(0)
85: ( 0, 0, 0) #000000 gray(0)
86: ( 0, 0, 0) #000000 gray(0)
87: ( 0, 0, 0) #000000 gray(0)
88: ( 0, 0, 0) #000000 gray(0)
89: ( 0, 0, 0) #000000 gray(0)
90: ( 0, 0, 0) #000000 gray(0)
91: ( 0, 0, 0) #000000 gray(0)
92: ( 0, 0, 0) #000000 gray(0)
93: ( 0, 0, 0) #000000 gray(0)
94: ( 0, 0, 0) #000000 gray(0)
95: ( 0, 0, 0) #000000 gray(0)
96: ( 0, 0, 0) #000000 gray(0)
97: ( 0, 0, 0) #000000 gray(0)
98: ( 0, 0, 0) #000000 gray(0)
99: ( 0, 0, 0) #000000 gray(0)
100: ( 0, 0, 0) #000000 gray(0)
101: ( 0, 0, 0) #000000 gray(0)
102: ( 0, 0, 0) #000000 gray(0)
103: ( 0, 0, 0) #000000 gray(0)
104: ( 0, 0, 0) #000000 gray(0)
105: ( 0, 0, 0) #000000 gray(0)
106: ( 0, 0, 0) #000000 gray(0)
107: ( 0, 0, 0) #000000 gray(0)
108: ( 0, 0, 0) #000000 gray(0)
109: ( 0, 0, 0) #000000 gray(0)
110: ( 0, 0, 0) #000000 gray(0)
111: ( 0, 0, 0) #000000 gray(0)
112: ( 0, 0, 0) #000000 gray(0)
113: ( 0, 0, 0) #000000 gray(0)
114: ( 0, 0, 0) #000000 gray(0)
115: ( 0, 0, 0) #000000 gray(0)
116: ( 0, 0, 0) #000000 gray(0)
117: ( 0, 0, 0) #000000 gray(0)
118: ( 0, 0, 0) #000000 gray(0)
119: ( 0, 0, 0) #000000 gray(0)
120: ( 0, 0, 0) #000000 gray(0)
121: ( 0, 0, 0) #000000 gray(0)
122: ( 0, 0, 0) #000000 gray(0)
123: ( 0, 0, 0) #000000 gray(0)
124: ( 0, 0, 0) #000000 gray(0)
125: ( 0, 0, 0) #000000 gray(0)
126: ( 0, 0, 0) #000000 gray(0)
127: ( 0, 0, 0) #000000 gray(0)
128: ( 0, 0, 0) #000000 gray(0)
129: ( 0, 0, 0) #000000 gray(0)
130: ( 0, 0, 0) #000000 gray(0)
131: ( 0, 0, 0) #000000 gray(0)
132: ( 0, 0, 0) #000000 gray(0)
133: ( 0, 0, 0) #000000 gray(0)
134: ( 0, 0, 0) #000000 gray(0)
135: ( 0, 0, 0) #000000 gray(0)
136: ( 0, 0, 0) #000000 gray(0)
137: ( 0, 0, 0) #000000 gray(0)
138: ( 0, 0, 0) #000000 gray(0)
139: ( 0, 0, 0) #000000 gray(0)
140: ( 0, 0, 0) #000000 gray(0)
141: ( 0, 0, 0) #000000 gray(0)
142: ( 0, 0, 0) #000000 gray(0)
143: ( 0, 0, 0) #000000 gray(0)
144: ( 0, 0, 0) #000000 gray(0)
145: ( 0, 0, 0) #000000 gray(0)
146: ( 0, 0, 0) #000000 gray(0)
147: ( 0, 0, 0) #000000 gray(0)
148: ( 0, 0, 0) #000000 gray(0)
149: ( 0, 0, 0) #000000 gray(0)
150: ( 0, 0, 0) #000000 gray(0)
151: ( 0, 0, 0) #000000 gray(0)
152: ( 0, 0, 0) #000000 gray(0)
153: ( 0, 0, 0) #000000 gray(0)
154: ( 0, 0, 0) #000000 gray(0)
155: ( 0, 0, 0) #000000 gray(0)
156: ( 0, 0, 0) #000000 gray(0)
157: ( 0, 0, 0) #000000 gray(0)
158: ( 0, 0, 0) #000000 gray(0)
159: ( 0, 0, 0) #000000 gray(0)
160: ( 0, 0, 0) #000000 gray(0)
161: ( 0, 0, 0) #000000 gray(0)
162: ( 0, 0, 0) #000000 gray(0)
163: ( 0, 0, 0) #000000 gray(0)
164: ( 0, 0, 0) #000000 gray(0)
165: ( 0, 0, 0) #000000 gray(0)
166: ( 0, 0, 0) #000000 gray(0)
167: ( 0, 0, 0) #000000 gray(0)
168: ( 0, 0, 0) #000000 gray(0)
169: ( 0, 0, 0) #000000 gray(0)
170: ( 0, 0, 0) #000000 gray(0)
171: ( 0, 0, 0) #000000 gray(0)
172: ( 0, 0, 0) #000000 gray(0)
173: ( 0, 0, 0) #000000 gray(0)
174: ( 0, 0, 0) #000000 gray(0)
175: ( 0, 0, 0) #000000 gray(0)
176: ( 0, 0, 0) #000000 gray(0)
177: ( 0, 0, 0) #000000 gray(0)
178: ( 0, 0, 0) #000000 gray(0)
179: ( 0, 0, 0) #000000 gray(0)
180: ( 0, 0, 0) #000000 gray(0)
181: ( 0, 0, 0) #000000 gray(0)
182: ( 0, 0, 0) #000000 gray(0)
183: ( 0, 0, 0) #000000 gray(0)
184: ( 0, 0, 0) #000000 gray(0)
185: ( 0, 0, 0) #000000 gray(0)
186: ( 0, 0, 0) #000000 gray(0)
187: ( 0, 0, 0) #000000 gray(0)
188: ( 0, 0, 0) #000000 gray(0)
189: ( 0, 0, 0) #000000 gray(0)
190: ( 0, 0, 0) #000000 gray(0)
191: ( 0, 0, 0) #000000 gray(0)
192: ( 0, 0, 0) #000000 gray(0)
193: ( 0, 0, 0) #000000 gray(0)
194: ( 0, 0, 0) #000000 gray(0)
195: ( 0, 0, 0) #000000 gray(0)
196: ( 0, 0, 0) #000000 gray(0)
197: ( 0, 0, 0) #000000 gray(0)
198: ( 0, 0, 0) #000000 gray(0)
199: ( 0, 0, 0) #000000 gray(0)
200: ( 0, 0, 0) #000000 gray(0)
201: ( 0, 0, 0) #000000 gray(0)
202: ( 0, 0, 0) #000000 gray(0)
203: ( 0, 0, 0) #000000 gray(0)
204: ( 0, 0, 0) #000000 gray(0)
205: ( 0, 0, 0) #000000 gray(0)
206: ( 0, 0, 0) #000000 gray(0)
207: ( 0, 0, 0) #000000 gray(0)
208: ( 0, 0, 0) #000000 gray(0)
209: ( 0, 0, 0) #000000 gray(0)
210: ( 0, 0, 0) #000000 gray(0)
211: ( 0, 0, 0) #000000 gray(0)
212: ( 0, 0, 0) #000000 gray(0)
213: ( 0, 0, 0) #000000 gray(0)
214: ( 0, 0, 0) #000000 gray(0)
215: ( 0, 0, 0) #000000 gray(0)
216: ( 0, 0, 0) #000000 gray(0)
217: ( 0, 0, 0) #000000 gray(0)
218: ( 0, 0, 0) #000000 gray(0)
219: ( 0, 0, 0) #000000 gray(0)
220: ( 0, 0, 0) #000000 gray(0)
221: ( 0, 0, 0) #000000 gray(0)
222: ( 0, 0, 0) #000000 gray(0)
223: ( 0, 0, 0) #000000 gray(0)
224: ( 0, 0, 0) #000000 gray(0)
225: ( 0, 0, 0) #000000 gray(0)
226: ( 0, 0, 0) #000000 gray(0)
227: ( 0, 0, 0) #000000 gray(0)
228: ( 0, 0, 0) #000000 gray(0)
229: ( 0, 0, 0) #000000 gray(0)
230: ( 0, 0, 0) #000000 gray(0)
231: ( 0, 0, 0) #000000 gray(0)
232: ( 0, 0, 0) #000000 gray(0)
233: ( 0, 0, 0) #000000 gray(0)
234: ( 0, 0, 0) #000000 gray(0)
235: ( 0, 0, 0) #000000 gray(0)
236: ( 0, 0, 0) #000000 gray(0)
237: ( 0, 0, 0) #000000 gray(0)
238: ( 0, 0, 0) #000000 gray(0)
239: ( 0, 0, 0) #000000 gray(0)
240: ( 0, 0, 0) #000000 gray(0)
241: ( 0, 0, 0) #000000 gray(0)
242: ( 0, 0, 0) #000000 gray(0)
243: ( 0, 0, 0) #000000 gray(0)
244: ( 0, 0, 0) #000000 gray(0)
245: ( 0, 0, 0) #000000 gray(0)
246: ( 0, 0, 0) #000000 gray(0)
247: ( 0, 0, 0) #000000 gray(0)
248: (192,192,192) #C0C0C0 gray(192)
249: (255, 0, 0) #FF0000 gray(255)
250: ( 0,255, 0) #00FF00 gray(0)
251: (255,255, 0) #FFFF00 gray(255)
252: ( 0, 0,255) #0000FF gray(0)
253: (255, 0,255) #FF00FF gray(255)
254: ( 0,255,255) #00FFFF gray(0)
255: (255,255,255) #FFFFFF gray(255)
Rendering intent: Perceptual
Gamma: 0.454545
Chromaticity:
red primary: (0.64,0.33)
green primary: (0.3,0.6)
blue primary: (0.15,0.06)
white point: (0.3127,0.329)
Background color: gray(255)
Border color: gray(223)
Matte color: gray(189)
Transparent color: gray(0)
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 512x512+0+0
Dispose: Undefined
Iterations: 0
Compression: Undefined
Orientation: Undefined
Properties:
date:create: 2014-10-01T09:18:15+01:00
date:modify: 2002-11-25T01:33:53+00:00
signature: dcd0e6587dcdeaaba5999a9bb384473f1af19f7a4c09ffee95356ea51bec22ce
Artifacts:
filename: /Users/mark/Desktop/lena.bmp
verbose: true
Tainted: True
Filesize: 263KB
Number pixels: 262K
Pixels per second: 26.21MB
User time: 0.000u
Elapsed time: 0:01.009
Version: ImageMagick 6.8.9-7 Q16 x86_64 2014-09-10 http://www.imagemagick.org
As you can see there are only 28 unique colours in the image, and the palette is only partially populated, as you have noted.
Another technique that will help you debug your code is to have ImageMagick dump your entire image as text, like this - I only show the first 8 pixels, but you get the idea:
convert lena.bmp -colorspace rgb txt:- | more
# ImageMagick pixel enumeration: 512,512,255,rgb
0,0: (85,85,85) #555555 rgb(85,85,85)
1,0: (95,95,95) #5F5F5F rgb(95,95,95)
2,0: (85,85,85) #555555 rgb(85,85,85)
3,0: (95,95,95) #5F5F5F rgb(95,95,95)
4,0: (95,95,95) #5F5F5F rgb(95,95,95)
5,0: (85,85,85) #555555 rgb(85,85,85)
6,0: (95,95,95) #5F5F5F rgb(95,95,95)
7,0: (85,85,85) #555555 rgb(85,85,85)