3

I need to take a BMP that I have in memory (stored as an HBITMAP or a CImage take your pick), and save it to a PNG file on disk.

Here is how I am currently saving the image as a png. CImage img; img.Save("foo.png")

My problem is that is far too slow (250ms for ~1920X1080). This takes 3X the time of saving as JPG, and about 9X the time of saving as a BMP.

I know there are a lot of g++ libraries for linux (e.g. libpng) that will do this, but most of the libraries that support visual studio only support version 6, and I haven't found one with benchmarks, so I'm kind of hesitant to try getting these libraries working only to find out they are too slow.

I am not sure what type of encoder windows uses (it's hidden in a DLL), but there must be a faster one (I'm even willing to sacrifice a bit of disk size, up to twice as much).

Java libraries do this very quickly, but for some reason Microsoft's library is slow as a turtle.

So I was wondering what options I have for saving screen-sizes PNGs to disk in ~100ms?

John Walters
  • 113
  • 5
  • Could you just use a 4:4:4 (no color loss) JPG encoder set at lossless quality? – K. Brafford Jul 29 '12 at 23:47
  • Yes, is there a built-in one in the Microsoft libraries which is easy to create from an HBITMAP/CImage? – John Walters Jul 30 '12 at 03:55
  • I don't know of one off the top of my head, but I was throwing that out there in case you were unnecessarily limiting your search space, assuming that you *had* to have png. DCT based image encoding algorithms (jpg, etc.) have some great data parallel aspects to them and speed up nicely with SSE instructions, so I think you should be on the lookout for decent lossless JPG code also. – K. Brafford Jul 30 '12 at 04:12
  • Here's some lossless jpeg chatter: http://stackoverflow.com/questions/7895697/library-for-further-lossless-jpeg-compression – K. Brafford Jul 30 '12 at 17:12

2 Answers2

1

I'd bet (but I have no bencharks) that libpng is the best option.

At least, I'd seek a library that allows to tune the saving options ( CImage doesn't). There are two relevant options to try:

  1. Zlib compression level (0-9) : the typical default value (6) is usually ok, you'll rarely gain much speed using less compression

  2. Filter type. This can be more important. If we want to optimize for speed, I'd preselect a unique filter (usually PNG_FILTER_PAETH).

leonbloy
  • 73,180
  • 20
  • 142
  • 190
  • 1
    PNG_FILTER_NONE is the fastest and is usually the best for images with a limited number of colors. PNG_FILTER_PAETH is slower to encode and decode, but gives better compression for natural images. – Glenn Randers-Pehrson Feb 25 '14 at 18:20
0

It's very easy to compile libpng yourself. I just did it myself before typing this resposne out. It took about 90 seconds.

  1. Download zlib from http://zlib.net/ Either in source or precompiled form such that you have zlib.h

  2. Download libpng from http://sourceforge.net/projects/libpng/files/libpng15/1.5.12/lpng1512.zip/download

  3. Unzip the contents of libpng zip file.

  4. Open a command shell.

  5. "cd /d d:\projects\libpng" (cd into whatever directory you just unzipped the libpng sources from)

  6. "copy scripts\libpng.h.prebuilt libpng.h"

  7. Create a new Visual Studio C++ project (static library) in the libpng directory

  8. Add all the *.c files from the libpng directory to the project

  9. Add your zlib project directory to the project's include path. (Wherever it can find zlib.h)

  10. Build your project. It should compile the png code library just fine. Done.

selbie
  • 100,020
  • 15
  • 103
  • 173
  • Thanks for trying to help, but I don't want to figure out how to convert HBITMAP/CImages to a format libpng accepts unless I'm sure it will be faster. – John Walters Jul 30 '12 at 13:06
  • @JohnWalters - There's only one sure way to find out if libpng is faster than GDI+... – selbie Jul 31 '12 at 18:10
  • Sorry if I came off as rude, I have a deadline soon and I thought there might be another microsoft library that could do this, or at least a benchmarked library, I'm sure your steps will help whoever else googles this problem and has a bit more time on their hands :). – John Walters Aug 01 '12 at 04:06