Real-valued image types, such as ImageGrayd and ImageRGBd, produce empty files when called with the default syntax (save(filename)). This enforces the use of IO::save01_in_u8(image, filename), but this is inconvenient with template types that can be different Image types.
I suggest to change save(filename) so that it saves real-valued images by assuming their value is between 0 and 1, and clamp values that are not in this range.