{drop two images, a button and an openpicturedialog on a form and then delete the unit code and paste in the code below remember to double click the button to initiate the event handler and then run to generate a histogram of an 8 bit grey scale bitmap} unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, ExtDlgs; type TForm1 = class(TForm) Button1: TButton; Image1: TImage; Image2: TImage; OpenPictureDialog1: TOpenPictureDialog; procedure Button1Click(Sender: TObject); procedure Histogram(var Bitmap : TBitmap; var Histcount : array of integer); procedure Histogram100(var HistCount : array of integer); Procedure DrawHistogram(var Histcount : array of integer); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} {the histogram function here only works on 8 bit grey scale bitmaps so be sure to load a bitmap of this type to generate a valid histogram} procedure TForm1.Button1Click(Sender: TObject); var Bitmap : TBitmap; HistCount : array[0..255] of integer; begin If OpenPictureDialog1.execute then begin Bitmap := TBitmap.create; Bitmap.LoadFromFile(OpenPictureDialog1.Filename); Image1.Picture.Bitmap := Bitmap; Histogram(Bitmap, HistCount); Histogram100(HistCount); DrawHistogram(Histcount); end; end; {to calculate a histogram of an 8 bit grey scale image in this example we check each byte and then we increment the corresponding element in an array each time we count a byte of a certain intensity value for example if a byte has intensity 102 we increment array position 102 by one each time we find the byte 102 in the bitmap} procedure TForm1.Histogram(var Bitmap : TBitmap; var Histcount : array of integer); var x, y, i, j : integer; pb : pbytearray; begin For i := 0 to 255 do begin HistCount[i] := 0; end; for y := 0 to Bitmap.height - 1 do begin pb := Bitmap.scanline[y]; for x := 0 to Bitmap.width - 1 do begin {the C++ code to calculate the totals for the histogram j = *(Image->data+x+(long)y*image->cols); dereference the pointer to extract the byte in the bitmap} j := pb[x]; {that's it in Delphi, same thing} {next Increment the pixel count in the histogram for this pixel intensity, using j, the byte value as the index into the array} inc(HistCount[j]); end; end; end; {a histogram can have thousands of points of the same intensity in order to output the histogram to a bitmap for display the points will interpreted as a percentage of the maximum value so the points will will be output as values between 0 and 100} procedure TForm1.Histogram100(var HistCount : array of integer); var maxi, i : integer; begin maxi := 0; for i := 0 to 255 do begin {find maximum value in array} if HistCount[i] > maxi then maxi := Histcount[i]; end; If maxi < 100 then exit {else make each histogram point <= 100} else begin for i := 0 to 255 do begin {express each histogram point as a percentage of maxi so that the histogram points will vary from 0 to 100} HistCount[i] := ((HistCount[i] * 100) div maxi); end; end; end; {draw the histogram on a bitmap} Procedure TForm1.DrawHistogram(var Histcount : array of integer); var x : integer; rect : Trect; begin Image2.picture.Bitmap.pixelformat := pf8bit; Image2.Width := 256; Image2.Height := 200; Image2.picture.Bitmap.height := 200; Image2.picture.Bitmap.width := 256; rect.Left := 0; rect.right := Image2.Width - 1; rect.Top := 0; rect.Bottom := Image2.height - 1; with Image2.Picture.Bitmap do begin Canvas.Brush.Color := clWhite; Canvas.Brush.Style := bsSolid; Canvas.FillRect(rect); Canvas.Pen.Color := clBlack; Canvas.Pen.Style := psSolid; Canvas.Pen.Width := 1; Canvas.MoveTo(0, HistCount[0]); for x := 1 to 255 do begin Canvas.LineTo(x, 200 - HistCount[x]); end; end; end; end. {included here is the C++ code which is discussed on this web page http://www.awitness.org/delphi_pascal_tutorial/c++_delphi/grey_scale_histogram.html This C++ code is equivalent to the Delphi Histogram procedure above.. void Histogram(struct Image *IMAGE, int HISTCOUNT[]) { int x, y, i, j; for (i=0;i<=255;i++) HISTCOUNT[i] = 0; for (y=0; yRows; y++) { for (x=0; xCols; x++) { j = *(IMAGE->Data+x+(long)y*IMAGE->Cols); HISTCOUNT[j] = HISTCOUNT[j]+1; } } }