Can we use png instead bitmap in GDI for bitblt? - gdi+

HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmOld = SelectObject(hdcMem, g_hbmBall);
GetObject(g_hbmBall, sizeof(bm), &bm);
BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
I've found that many games use bitmap for displaying animation . But can we use png instead ?
Because bitmap is quite big when i convert fron png ( 1kb -> 12kb in bitmap )
Thanks for reading this :)

No, you can't BitBlt with a PNG. BitBlt (which stands for "bit block transfer", by the way) is very fast, but it is basically just a simple memory copying routine. So the only way to BitBlt any image format other than an uncompressed bitmap is to first convert that format to a bitmap.
By the way, applications typically use bitmaps for animation because you don't want to increase your overall frame rendering time by having to uncompress your sprite images each time. Bitmaps are just an example of generally caching things in memory to improve performance.

No, I don't think so, but GDI+ supports PNG among several other formats.

Related

How to glReadPixels properly to write the data into QImage in Linux

Summary
I want to write the opengl pixels(GL_RGB) by glReadPixels to a QImage.This renders correct, but when i resize the window, it scales weird and distorts my shape(triangle).
What i tried
I tried (QImage)img.scale(width(),height(),Qt::KeepAspectRatio)
but it didn't solve the problem.
Played with how i write the pixels buffer from glReadPixels to QImage but No.Didn't work.
Should i read the pixels in three buffers(GLubyte *rpixel,*gpixel,*bpixel) or on one(GLubyte **pixels)?Which one is the easiest because i will resize the array when i will resize my window(so i want dynamic arrays).
Some code
I have uploaded a minimal code recreating the bug-weird behaviour in github.Download and compile using the Qt Creator.
https://github.com/rivenblades/GlReadPixelsQT/tree/master
Pictures
Here is how i wanted(it works when not resizing)
Here is after resizing(Weird behaviour)
As you can see, when resizing, the image gets splitted at right and contunues at left at probably another row.So i am guessing the size of the image is wrong(needs more width?).
By default, the start of each row of an image is assumed to be aligned to 4 bytes. This is because the GL_PACK_ALIGNMENT respectively GL_UNPACK_ALIGNMENT parameter is by default 4, see glPixelStore.
When a framebuffer is read by glReadPixels the GL_PACK_ALIGNMENT parameter is considered.
If you want to read the image in a tightly packed memory, with not alignment at the start of each line, then you've to change the GL_PACK_ALIGNMENT parameter to 1, before reading the color plane of the framebuffer:
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(0,0,unchangable_w, unchangable_h, GL_RED, GL_UNSIGNED_BYTE, tga.rpic);
glReadPixels(0,0,unchangable_w, unchangable_h, GL_GREEN, GL_UNSIGNED_BYTE, tga.gpic);
glReadPixels(0,0,unchangable_w, unchangable_h, GL_BLUE, GL_UNSIGNED_BYTE, tga.bpic);
If that is missed, this cause a shift effect at each line of the image, except if the length of a line of the image in bytes is divisible by 4.

Lossless JPEG is a special case of JPEG image compression

I've read lossless jpeg is invoked when the user selects a 100% quality factor in an image tool.
What is the image tool they meant?
Thanks in advance.
OK Image Compression is sorta like a ZIP file; JPG Takes up less space but has less quality then a PNG or TIFF. In short it removes Bytes and Changes The Algorithm, the Higher the Quality The More Space it Takes for the Algorithm Compression, Read More Here:
https://en.wikipedia.org/wiki/Lossless_compression

Use an Image or using the graphic function for 2D game dev?

I'm trying to write a simple game that has some dogs and cats move around. Now my dogs, cats is the read and blue rectangle, I need to make them more pretty and now is 2 options for me:
Using an Image.
Draw them by some graphic class.
But I not sure what should I choose!
If use Image, I must draw some (the object can animate). But it make thing simple.
Use graphic function give me more power (like in case there more than just dog and cat, OO will help me alot). But I will make my barin hurt.
And the the most important is which is faster?
BTW I'm using Qt.
I'd most definitely use a bitmap.
Rendering a bitmap image is usually faster because it can be fully cached in memory unless it's large (which it shouldn't be, in your case). The underlying mechanics would simply involve a blazingly-fast memcpy (or the like) once it's been read from the disk.
Drawing a dog using vector graphics would incur a large overhead in terms of performance due to function calls, math/transformations, and would end up effectively needing more memory than a bitmap.

StretchDIBits seems slow, Is there any API faster?

I want to draw a dib on to a HDC, the same size.
I am using :
des and src are of the same size.
::StretchDIBits(hdc,
des.left,des.top,des.right - des.left,des.bottom - des.top,
src.left, GetHeight() - src.bottom, src.right - src.left,src.bottom - src.top,
m_pImg->accessPixels(),m_pImg->getInfo(), DIB_RGB_COLORS, SRCCOPY);
but I find it is slow, because the des size is the same, I just need to copy the dib onto a dc.
Is there any method faster than StretchDIBits?
just as
StretchBlt (slow) vs Bitblt.(faster)
StretchDIBits (slow ) vs ?(faster)
The speed difference comes from doing any necessary color conversion in addition to the generality necessary to handle the stretching (even if your target size is the same as your source size).
If you're just drawing the image just once, then I think function you're looking for is SetDIBitsToDevice.
If you care about the speed because you're drawing the same DIB multiple times, then you can improve performance by copying the DIB to a compatible memory DC once, and then BitBlt-ing from the memory DC to the screen (or printer) each time you need it. Use CreateCompatibleDC to create the memory DC, and then use StretchDIBits or SetDIBitsToDevice to get the image on it. After that, you can use BitBlt directly. You might also look into using a DIBSECTION, which gives a compromise in performance between a true DIB and a compatible DC.

GDI+ 's Amazing decode speed, and terrible draw speed!

Thanks for answers,Actually I am not puzzled about draw 1024*768 pixels is slower than 100* 100 pixels... It is so simple a logic..
Which made me puzzled is that DrawImage's interpolation algorithm may be very slow, while there exists lots of better algorithm, and its decoder seems can decode from a jpg with a certain resolution, it is really cool, I search for sometime but do not find any free lib to do this...
It is really strange!
I add the following code into on Paint method. c:\1.jpg is 5M jpg file, about 4000*3000
//--------------------------------------------------------------
HDC hdc = pDC->GetSafeHdc();
bitmap = Bitmap::FromFile(L"c:\\1.jpg",true);
Graphics graphics(hdc);
graphics.SetInterpolationMode( InterpolationModeNearestNeighbor );
graphics.DrawImage(bitmap,0,0,200,200);
The above is really fast! even real time! I don't think decode a 5m JPG can be that fast!
//--------------------------------------------------------------
HDC hdc = pDC->GetSafeHdc();
bitmap = Bitmap::FromFile(L"c:\\1.jpg",true);
Graphics graphics(hdc);
graphics.SetInterpolationMode( InterpolationModeNearestNeighbor );
graphics.DrawImage(bitmap,0,0,2000,2000);
The above code become really slow
//--------------------------------------------------------------
If I add Bitmap = Bitmap::FromFile(L"c:\1.jpg", true); // into construct
leave
Graphics graphics(hdc);
graphics.SetInterpolationMode( InterpolationModeNearestNeighbor );
graphics.DrawImage(bitmap,0,0,2000,2000);
in OnPaint method,
The code is still a bit slow~~~
//------------------------------------------------------------------
Comparing with decoding, the drawImage Process is really slow...
Why and How did they do that? Did Microsoft pay the men taking charge of decoder double salary than the men taking charge of writing drawingImage?
So, what you're really wondering is why
graphics.DrawImage(bitmap,0,0,200,200);
is faster than
graphics.DrawImage(bitmap,0,0,2000,2000);
Correct?
Well, the fact that you are drawing 100 times more pixels in the second case could have something to do with it.
You don't need to decode JPGs if you're scaling down by a factor of 8. JPG images consist of blocks of 8 by 8 pixels, DCT-transformed. The average value of this block is the 0,0 coefficient of the DCT. So, scaling down a factor of 8 is merely a matter of throwing away all other components. Scaling down even further (eg 4000->200) is just a matter of scaling down from 4000 to 500, and then scaling normally from 500 to 200 pixels.
It could be possible that the decoding is deferred until needed. That's why it is so fast.
Maybe on the 200x200 case GDI+ only decodes enough blocks to paint 200x200 and on 2000x2000 they decodes more.
Graphic routines always contains some obscure optimizations, you could never know.
Maybe Reflector will tell you?
Just a guess, but could you try drawing with 4000x3000 or 2000x1500? Perhaps the fact that 4000 and 3000 are divisible by 200 is speeding up the whole and 3000 not being divisible by 200 slows it down (although this really would be weird).
Generally, do some profiling or time measurement. If 2000x2000 is about 100 times slower than 200x200, everything is okay. And don't bother if 2000x2000 is too slow. If your screen is at 1024x768, you can't see the whole image, so you better pick the part of the image that is visible on the screen and draw it, 1024x768 is 5 times faster than 2000x2000.

Resources