What is the significance of the imaginary parts in the output of an Inverse Fourier Transform? Can I avoid them? Starting with an image, I have taken its fourier transform and then modified it, and finally taken the inverse fourier transform of the modified fourier transform to get my resulting image.  In my result, I get a lot of very small imaginary components in each pixel.  My question is what causes these, and is there some insight into how I can play with a fourier transform in such a way that I won't get these imaginary components once I invert the transform at the end?

The reason this is an issue for me is because although I can simply zero out the imaginary components, or take the magnitude of each complex number as the pixel value and still obtain the resulting image that I desire, once I take the fourier transform of that new image, it does not yield the fourier transform that I used to generate the image previously.  Because the English is getting messy, it's much easier to see in pseudocode:

function fft(input):
   return 2D fourier transform of input 2D array

function ifft(input):
   return 2D inverse fourier transform of input 2D array

function fix(image):
   zero out imaginary component in each pixel of input image (2D array)
   return updated image

// Suppose we have computed an input 2D matrix, and are ready to ifft it to get an image
input = /*...*/
test1 = fft(ifft(input))
test2 = fft(fix(ifft(input)))


While test1 will yield back the matrix (up to floating point errors) input that we started with, the image generated is not a real image.  If we attempt to fix the image, we find that test2 significantly differs from our input.

What I would like to do is understand how to modify the fourier transform in such a way that I can achieve my original input after going through the process of taking the inverse fourier transform, storing that as a valid image, and then taking the fourier transform of that image.
The Fourier Transform is the change of basis, the discrete signal from image, which is finite, gets transformed into sines. The transformation itself is prone to rounding, because in frequency domain there is no such thing as finite impulse or rectangular for that matter (see Gibbs effect), there will be some approximation.

The complex numbers represent the transformed signal, where amplitude is the length (magnitude) of the number while phase is the angle. Cutting off the imaginary part destroys the phase and changes the amplitude so image looks like a noise. There is no way to avoid Imaginary part (unless the image itself is fully even-symmetric then Im is zero).

The small components in Imaginary part cannot be avoided, extending precision will help a lot, but please keep in mind that some inputs cannot be preserved and some loss will occur. Using only magnitude and discarding the phase is equivalent to saving pixel intensities and discarding the location.

If you want to store FFT result as the valid image, the best idea is to produce two images, for Real and Imaginary part or another pair using Phase and Magnitude. Another idea is to save separate channels, which works for grayscale image but is not sn option for grayscale. This operation is very lossy, some fixed unsigned integer (for example 8bit) is converted into complex pair, both floating point, so using any standard storage option will lose crucial data. Probably to make it work the log transform would be need.