Use PngEncoderB to convert your BufferedImage to a PNG encoded byte array.
You can apply a filter to it, which will help prepare the image for better optimization. This is what OptiPNG does, only OptiPNG calculates which filter will give you the best compression.
You may need to try applying each filter to find out which one is best for you. With 2-bit color, I think the only filter that can help is up, so I guess the one to be used.
Once you get the image in a PNG encoded byte array, you can write it directly to a file.
source share