We have a encoder library which takes 32 bpp data. We have a screen capture library which needs to support 16 bpp as well. I would like to convert a 16bpp raw data into 32bpp whenever I need to pass the new screen captures to encoder. How can it be done efficiently and are there any other alternatives ?
I dont want to change the encoder library because that will require changes upstream of encoder as well.
Thanks!
You could load the source bitmap into an HBITMAP, create a destination bitmap with the desired pixel format and then draw the source onto the destination. That would be the easiest way to do it.
If you wanted to work directly with the bits then that would be possible but it's easier to let the system worry about it for you. It's probably quicker when the system does it because it will be well optimised.
To clarify the other answers: you need to use CreateDIBSection to create bitmaps in the formats you are interested in: 16bpp and 32bpp.
The handy thing with this function is it returns a pointer to the memory buffer with the pixel data, allowing you to easily initialize the bitmap from the one source, and extract the pixel data to give to the encoder library.
The source bitmap doesn't need to be a DIBSection, it can be any kind of HBITMAP at all (as long as its compatible with the HDC you try to select it into - but the screen capture library will be giving you a screen DC compatible HBITMAP if it gives you an HBITMAP at all)
BitBlt can then be used to get the device driver to perform the format conversion.
Use BitBlt:
"If the color formats of the source and destination device contexts do not match, the BitBlt function converts the source color format to match the destination format."
http://msdn.microsoft.com/en-us/library/dd183370%28v=VS.85%29.aspx
Related
I have an .emf file that I want to convert to a bitmap in legacy VC++ 6.0 code.
I've been looking through the WIC documentation and I'm surprised I haven't seen a way to do this.
Am I missing something?
If WIC ends up not supporting this, is there a method programattically load an .emf file into a CBitmap object?
There's no need for WIC. It's built into the core of Windows itself in the form of PlayEnhMetafile.
So, to get the picture into a BMP, you select your BMP into a DC, then do PlayEnhMetafile on that DC, and the result will go into the BMP.
Note that this isn't really converting a metafile into a BMP--it's rendering the metafile into the BMP. That is to say, a metafile is (usually) resolution independent. For example, it may specify a line from logical coordinate (0,0) to (100, 100). When you render that into a BMP, you get the line rasterized at a specific resolution. If you later wanted the same picture at higher resolution, the metafile could provide it, but the rendering in the BMP couldn't/can't.
I have seen and understood example of how to manipulate with the .bmp images themselves. My next step is to convert the raw bits that I am getting from my
FPGA device
binary file (.bin file)
and convert them to pixels so that I can make the bitmap from it.
I try the following function, CreateBitmap() in C++ but cannot succeed since it seems it only deals with pixels.
thanks
you can look at this site for understand bitmap architecture and you can find how to convert raw data to bitmap or bitmap to raw data
http://en.wikipedia.org/wiki/BMP_file_format
I'm currently writing a 3D renderer (for fun and research), so I need a way to draw my framebuffer to a window. Since I'm doing all of my calculations on CPU, the drawing needs to be as fast as possible.
One of my goals is to use no existing graphics library (OpenGL/DirectX) so the drawing to the screen is pure Win32. In my research I've found a couple of ways to create and draw bitmaps and now I'm looking for the best one.
My current implementation uses a bitmap created with CreateDIBSection(), which is drawn to my window DC using BitBlt().
CreateDIBSection() give me a pointer to my bitmap bytes so I can manipulate it without copying. Using this method I achieve an update rate of about 260 FPS (without any rendering done).
This seems a bit slow, so I'm looking for optimizations.
I've read something about that if you don't create a bitmap with the same palette as the system palette, some slow color conversions are done.
How can I make sure my DIB bitmap and window are compatible?
Are there methods of drawing an bitmap which are faster than my current implementation?
I've also read something about DrawDibDraw(), can anyone confirm that this is faster?
I've read something about that if you don't create a bitmap with the same palette as the system palette, some slow color conversions are done.
Very few systems run in a palette mode any more, so it seems unlikely this is an issue for you.
Aside from palettes, some GDI functions also cause a color matching conversion to be applied if the source bitmap and the destination have different gamuts. BitBlt, however, does not do this type of color matching, so you're not paying a price for that.
How can I make sure my DIB bitmap and window are compatible?
You don't. You can use DIBs (which are Device-Independent Bitmaps) or compatible (device-dependent) bitmaps. It's possible that your DIB bitmap matches the current mode of your device. For example, if you're using a 32 bpp DIB, and your display is in that same mode, then no conversion is necessary. If you want a bitmap that's guaranteed to be in the same mode as your device, then you can't use a DIB and all the nice properties it provides for predictable pixel layout and format.
Are there methods of drawing an bitmap which are faster than my current implementation?
The limitation is most likely in getting the data from system memory to graphics adapter memory. To get around that limitation, you need a faster graphics bus, or you need to render directly into graphic memory, which means you'd need to do your computation on the GPU rather than the CPU.
If you're rendering a 1920 x 1080 pixel image at 24 bits per pixel, that's close to 6 MB for your frame buffer. That's an awful lot of data. If you're doing that 260 times per second, that's actually pretty impressive.
I've also read something about DrawDibDraw(), can anyone confirm that this is faster?
It's conceivable, but the only way to know would be to measure it. And the results might vary from machine to machine because of differences in the graphics adapter (and which bus they use).
I need it to work with RGB24 data using GDI functions (specifically StretchBlt() which is pretty fast) and I can't use CreateCompatibleDC() since it can create memory DC only with color depth of other DC. Usually it's used with screen DC (by transmitting NULL pointer to function) and usually screen has color depth of value 32. In addition I can't rely on it, 'coz if screen settings are changed my application probably won't work.
So I need some way to create memory DC with specific certain color depth. So far I've found only one way with using CreateDC() function but it requires many device specific parameters and seems somewhat unreliable for me. Moreover there are too many fields to be filled with appropriate values to call CreateDC().
Is there some easier way to create specific memory DC and not rely on some devices? Or even if to create memory DC with 24 bpp?
P.S. I need it for some fast graphics. I've tried manual adding alpha channel to bitmap for using it with compatible to screen 32bpp memory DC and it worked out, but was too slow. And as I said above, I can't rely on screen settings which can be changed.
Bits-per-pixel does not really depend on a DC, but on the bitmap selected into it. Create a 24bpp bitmap with CreateDIBSection then select it into a memory DC.
Hopefully someone has an answer, and it's not TOO complex. I'm working on a C++ dll (no C# or .Net, fully static DLL).
Anyhow, its woring on buildin monochrome bitmaps. I have all of it working EXCEPT the resolution. I get the Device Context, Get Compatible Device Context, build bitmap, draw what I need to (as black/white), and can save. All this works fine. However, I can't figure out how to set the resolution of the bitmap.
While doing some testing from another utility under C#, I can create a bitmap and set the resolution. In doing so, I ran a routine to generate the same file content with a parameter from 1 to 300 for the resolution. Each image came out exactly the same EXCEPT for the values in the "biCompression" DWORD property. The default is the screen resolution of 96x96, but need to obviously change for printers of 300x300, and even some at 203x203 resolution.
Are you absolutely sure? The description of the behavior you observe sounds fishy to me and I would suspect the code that you're using to write your bitmaps or your code that reads them back in.
Are you sure you don't want to set biXPelsPerMeter and biYPelsPerMeter? Those two fields tell you how many pixels per meter in X and Y, which you can use to set the DPI. biCompression only deals with the compression type of the bitmap, e.g., RLE, JPG, PNG, etc.
Thanks for input, but I'll look into the biXPelsPerMeter an biYPels... too. I'll double check the format, and what was set... if so, you may have hit it with a second set of eyes (minds) on my issue.
Thanks