dummzeuch 1505 Posted April 14, 2022 (edited) The following code is supposed to create a TBitmap in 8 bit greyscale: function MakeGrayPalette(_NumColors: TNumColors = 256): HPALETTE; var i: Integer; lp: TMaxLogPalette; Grey: Byte; begin lp.palVersion := $300; lp.palNumEntries := _NumColors; for i := 0 to _NumColors - 1 do begin Grey := i * 255 div _NumColors; lp.palPalEntry[i].peRed := Grey; lp.palPalEntry[i].peGreen := Grey; lp.palPalEntry[i].peBlue := Grey; lp.palPalEntry[i].peFlags := PC_RESERVED; end; Result := CreatePalette(pLogPalette(@lp)^); end; // to be used like this: bmp := TBitmap.Create; bmp.PixelFormat := pf8bit; butBmp.Palette := MakeGrayPalette(); I think I got it from here (stackoverflow) but there are several Google hits for the same code, e.g. here (book "Delphi in a Nutshell") or here (DelphiPower), but I guess the book is the original source. Since it looked fine I never questioned it until I used it today to load a bitmap from a file, modify a part of it and save it again. When I checked the result, I found that in addition to the expected changes there were subtle differences in gray shades varying by a few values. Looking at the code again now, I think there is a bug in the line assigning Grey: Grey := i * 255 div _NumColors; Shouldn't that be ... Grey := i * 256 div _NumColors; ... instead? If I change it like that the bitmaps only contain the expected differences. Or am I missing something here? Edited April 14, 2022 by dummzeuch Share this post Link to post
Anders Melander 1783 Posted April 14, 2022 What you're dealing with is an unavavoidable rounding problem and a misunderstanding of what's going on mathematically. The two versions are equally bad. They just distribute the rounding error differently. You want the first palette entry to have a grey-level value of 0 and the last one to have a value of 255 - not 256. Level = 255 * (Index / (Levels-1)) or Grey := i * 255 div (_NumColors-1) 1 Share this post Link to post