(expanding on my comments)
The problem boils down to this: people typically believe that the "format" given by the following command:
ImageIO.getReaderFileSuffixes();
are supported by Java.
But that's not how it should be read/understood because that is simply not how it works.
Wrong: "ImageIO can read any file encoded with one of these format"
Correct: "ImageIO cannot read image encoded with a format that is not one of these format"
But now what does that say about formats appearing in that list? Well... It gets tricky.
For example that list typically returns both "PNG" and "BMP" (and other formats). But there's not "one" PNG nor "one" BMP. I can come tomorrow with a "valid" PNG (sub)format that would be perfectly fine but that no single PNG decoder out there would decode (it would have to be validated and accepted: but once it would be accepted, it would "break" all the existing PNG decoders out there). Luckily, for the PNG pictures the problem ain't too bad.
The BMP format is very complicated. You can have compression or not (which may explain the varying file size you've seen). You can have various headers (of differing length, which may also explain the varying file sized you've seen). Heck, BMP is actually so complex that I think that you can embed PNG encoded pixels inside a BMP "shell".
There are basically two problematic types of BMP files:
- BMP variants that appeared after the Java decoder was created
- BMP variants that are obscure enough so that the Java ImageIO implementors didn't consider it worthy of support
The "error" consists in thinking that there's one PNG or one BMP format. Both formats (and other image formats too) are actually "extensible". An everytime a new variant comes out it has the potential to break any decoder out there.
So what's happening in your case is this:
you're reading your original BMP file from MS Paint and MS Paint is able to read that file because it happens to be a BMP format that MS Paint understands.
that same BMP format is alien to the Java version you're using (there's hope that it will be supported in another Java version but I wouldn't count on it).
when you re-save that file from MS Paint, you're saving in a BMP format that is definitely not the same as the original format (the varying file size being quite a tell)
that other format happens to be supported by your version of Java.
Now to actually solve your problem: in my experience image libraries like ImageMagick are able to read much much more pictures than the default Java ImageIO API so I'd give a look at either other image libraries or wrappers around ImageMagick.
These libraries are also typically updated to support newer variants and newer formats much faster than Java is. For example the amazing WebP format from Google (up to 28% to 34% better than PNG on lossless+translucent images) is already supported by quite some image manipulation libraries but I'm not holding my breath when it comes to do a ImageIO.read( someWebPpicture)...
Another option would be to use PNG: even though theoretically PNG can be extended you're less likely to find "non supported" PNGs in the wild. With BMPs it's all too common.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…