There are 8 neighbouring pixels, they are at...
(-1,-1)
(-1,0)
(-1,1)
(0,-1)
(0,1)
(1,-1)
(1,0)
(1,1)
...relative to the pixel you are looking at.
Let's say the 'height' of these pixels is h0 to h7, and the height of the center pixel is c, then 8 normals could very roughly be
(-1,-1,c-h0)
(-1,0,c-h1)
(-1,1,c-h2)
(0,-1,c-h3)
(0,1,c-h4)
(1,-1,c-h5)
(1,0,c-h6)
(1,1,c-h7)
remembering to divide down the c-h'es by 512 because they are brightnesses.
Then you can normalise each vector by taking its length and dividing out,
so for each of the vectors above, (x,y,z)
length = sqrt(x^2 + y^2 + z^2)
nx = x/length
ny = y/length
nz = z/length
Then you can add together all the vectors (by adding the 8 nx, ny, nz values together) to get an average normal - let's make that (sx,sy,sz)
You can renormalise that
length = sqrt(sx^2 + sy^2 + sz^2)
rx = sx/length
ry = sy/length
rz = sz/length
Now you have a rough normal for your pixel (rx,ry,rz).
The final step is to encode that as pixel data in the bumpmap, and that depends on the format of the bumpmap.
Jim