I am creating screenshots under Windows and using the LockBits
function from GDI+ to extract the pixel data, which will then be written to a file.
To maximise performance I am also:
- Using the same
PixelFormat
as the source bitmap, to avoid format conversion - Using the
ImageLockModeUserInputBuf
flag to extract the pixel data into a pre-allocated buffer - This pre-allocated buffer (pointed to by
BitmapData::Scan0
) is part of a memory-mapped file (to avoid copying the pixel data again.)
I will also be writing the code that reads the file, so I can use (or invent) any format I wish. However I would prefer to use a well-known format that existing programs (ideally web browsers) are able to read, because that means I can visually confirm that the images are correct before writing the code for the other program (that reads the image.)
I have implemented this successfully for the PixelFormat32bppRGB
format, which matches the format of a 32bpp BMP file, so if I extract the pixel data directly into the memory-mapped BMP file and prefix it with a BMP header I get a valid BMP image file that can be opened in Paint and most browsers.
Unfortunately one of the machines I am testing on returns pixels in PixelFormat64bppPARGB
format (presumably t开发者_JAVA技巧his is influenced by the video adapter driver) and there is no corresponding BMP pixel format for this.
Converting to a 16, 24 or 32bpp BMP format slows the program down considerably (as well as being lossy) so I am looking for a file format that can use this pixel format without conversion, so I can extract directly into the memory-mapped file as I have done with the 32bpp format.
What raster image file formats support 48bpp (BGR order, little-endian) and/or 64bpp (BGRA order, little-endian)?
Edit
I have ruled out these formats so far:
- BMP: Depth limited to <=32bpp (would be a perfect match otherwise.)
- PNG: Sample order can only be RGBA.
- TIFF: Sample order can only be RGBA.
Possible partial solutions:
- OpenEXR: 48bpp only. Sample order is alphabetical by channel name; BGR fits but BGRA does not.
It seems that the only reason you need a standard format is for display/testing purposes. So roll your own format, but convert to PNG or TIFF for display. And then move on...life is short.
Do you really want to implement and carefully test separate readers for each of the 14 different PixelFormats? I know that so far you've only encountered 2 of them, but I guarantee there are video cards out there with almost all of the other 12. As one easy example, set your monitor to 256 colors...
You say that you want to maximize performance, but writing the bitmap to a file on disk, even with memory mapping, is going to take more time on average than the time it'd take to just convert it to a device-independent bitmap in memory. Plus if you convert the 64-bit bitmap to a 32-bit bitmap, the resulting file will take half as long to write, so it could actually be faster.
Which bitmap color depths are supported depends on your windows version which means gdi+ version, not the graphics adapter.
You can also use TIFF or PNG (png has lots of parameters, I think you also can tell it to do uncompressed). You can also consider the RAW format.
The imaging library imagemagick which has an .net wrapper includes supports hundreds of image formats, no matter which format you decide to sue at the end, Iam sure it has support for it :)
When the desktop and web file formats let you down, think of reaching for the big guns: FITS (flexible image transport system) or HDF5, even DICOM perhaps.
PNG? 48 bit + alpha = 64 bit
for the compression, "It is possible to store uncompressed data by using only uncompressed deflate blocks"
Is the reading of the file just as performance critical as the writing? If you can fill a buffer easily, and then read at your convenience, this should be a cakewalk. Just have a 1byte header representing the data-format and then the raw data you got.
精彩评论