Creating Normal maps from a Texture?
Theory

First thing normal map generators do is to converts the input image into a grayscale image, even if it is colored, that is because color information is practically useless in the generation process, the algorithm used to convert the RGB colors into single values varies from a generator to another, so it is recommended that you convert your input image into grayscale before using the normal map generator, the reason will become clear in the next section.

Imagine the image as a grid of vertices, each vertex represents a pixel, the z location (height) of each vertex is equal to its value (Which is just a scalar not an RGB vector; because it is a grayscale image, remember). So we realize that the image is just a 2D function that associates a value to each point in space, except it is not a continuous function, since it is only defined on some discrete points in space. This surface we just described has normals at each vertex (just like your mesh has normals), and those normals is what a normal map stores, so the generator's job is to simply compute the normals of the surface and encode it in an image. It can be proven that the normals' components relates to partial derivatives of the surface using the equation:

\begin{equation}
\vec{N_x} = \frac{-\frac{\partial F}{\partial x}}{\sqrt{{\frac{\partial F}{\partial x}}^2 + {\frac{\partial F}{\partial y}}^2 +1 }} \\
\vec{N_y} = \frac{-\frac{\partial F}{\partial y}}{\sqrt{{\frac{\partial F}{\partial x}}^2 + {\frac{\partial F}{\partial y}}^2 +1 }}\\
\vec{N_z} = \frac{1}{\sqrt{{\frac{\partial F}{\partial x}}^2 + {\frac{\partial F}{\partial y}}^2 +1 }
}
\end{equation}

Where $F$ is the function that represents the surface and $N$ is the unit normal vector. Partial derivatives describes the steepness and direction of the surface and they can be computed using what is know as Symmetric Derivatives which I explained in more details in my answer
here.

Assuming we have the partial derivatives, we can compute the normal vector components using the previous equation. A normal map stores the $x$, $y$ and $z$ components of the normal vector into the $R$, $G$ and $B$ channels of the image respectively. If we attempted to do that, we will encounter a problem, the image can only store positive values that are less than one (Assuming a standard image format is used), the normal vector components will always be smaller than one because it is a unit vector, however the vector components can be negative denoting directions opposite to the fundamental vectors of the space, so we have to find a way to encode these data which belongs to the interval $[-1, 1]$ to the interval $[0, 1]$ which is the possible values for a pixel. This is a simple remapping task that can be performed using the equation:

$$
\begin{equation} R = \frac{(\vec{N}_x+1)}{2}\\G = \frac{(\vec{N}_y+1)}{2}\\\label{1} \end{equation}
$$

Where $R$ and $G$ are the red and green channels respectively, notice that we didn't perform the same remapping to the $z$ component because it is always positive, think about the surface that represents the image again, its normals will always be facing the positive direction of the $z$ axis. By using the previous equation, we get the RGB values for the normal map, so we are ready to do the implementation.

Implementation

We can make a node group that computes both the $\frac{\partial F}{\partial x}$ and $\frac{\partial F}{\partial y}$ partial derivatives given an input image. The implementation is as simple as a translation and a subtraction:



Refer to the article for more information, the rest of the implementation is as easy as applying the two equations above and creating an image out of the individual channels.

An example result