Home » Community » Newbie corner » Displaying raw image data
Displaying raw image data [message #39738] |
Mon, 22 April 2013 17:46 |
keltor
Messages: 73 Registered: February 2012
|
Member |
|
|
Hey everyone,
Silly me, I started to think that I was getting more fluent with U++, yet here I am in the newbie subforum once again.
I have a library that draws some stuff in memory. The drawing can be accessed using something like obj->GetRGBA(); however it is raw data, namely an unsigned char * consisting of 4 bytes for each pixel.
The library does its magic and creates the raw data. I would like to draw it into a bitmap, ideally as a picture in an ImageCtrl. However, I am a little lost with Buffer, Raster and the like. I couldn't find any suitable documentation or examples, so here I am.
My goal would be to reuse the raw buffer as the data to plug directly into ImageCtrl, so that if eventually the data in the buffer changes, one can force a redraw without having to copy data. But I don't know it that can be achieved, much less how. So if someone with more experience with this kind of things can help me out, he would certainly have my gratitude.
To clarify a bit more the kind of data I'm dealing with: bytes 0 to 3 contain the RGBA info for point (0,0); bytes 4-7 for (1,0); and point (i,j) is at 4*(i+width*j). The buffer itself has no picture height/width information, but that can be obtained elsewhere.
Thanks for reading
Keltor
|
|
|
Re: Displaying raw image data [message #39739 is a reply to message #39738] |
Mon, 22 April 2013 18:59 |
|
Hi Keltor
keltor wrote on Mon, 22 April 2013 17:46 | Silly me, I started to think that I was getting more fluent with U++, yet here I am in the newbie subforum once again.
| Happens to me all the time
keltor wrote on Mon, 22 April 2013 17:46 | I have a library that draws some stuff in memory. The drawing can be accessed using something like obj->GetRGBA(); however it is raw data, namely an unsigned char * consisting of 4 bytes for each pixel.
The library does its magic and creates the raw data. I would like to draw it into a bitmap, ideally as a picture in an ImageCtrl. However, I am a little lost with Buffer, Raster and the like. I couldn't find any suitable documentation or examples, so here I am.
My goal would be to reuse the raw buffer as the data to plug directly into ImageCtrl, so that if eventually the data in the buffer changes, one can force a redraw without having to copy data. But I don't know it that can be achieved, much less how. So if someone with more experience with this kind of things can help me out, he would certainly have my gratitude.
|
Some libraries let you do the opposite, that is to tell them in which part of memory should they draw. If that is your case, than you can simply do (assuming it uses same byte order) something like Image img;
ImageBuffer ib(width, height);
obj->setTargetMem(ib.Begin());
obj->doSomething();
img = ib;
If not, then the easiest way is AFAIK to do the copy, it should be very quick if you just memcpy the entire thing (again, same byte order expected):
Image img;
ImageBuffer ib(width, height);
memcpy(ib.Begin(), obj->getRGBA(), 4*width*height);
img = ib;
Creating ImageBuffer or Image using your pre-allocated piece of memory is not possible, IIRC. I think it would be possible to add such feature, but I'm not sure if it really corresponds with the "U++ way" of handling memory
Best regards,
Honza
|
|
|
|
Re: Displaying raw image data [message #39746 is a reply to message #39745] |
Tue, 23 April 2013 07:27 |
|
keltor wrote on Tue, 23 April 2013 00:03 | Much obliged, Honza. I will try to create a derived class to override the memory location of the raw data. If that doesn't work, I guess I will be stuck with the memcpy that I was trying to avoid, but no big deal. Thank you for the clear examples!
Kel
|
You're welcome. If you really want to try modifying the U++ classes, you'll probably need to create your own variant of ImageBuffer::Create() that skips the pixels Buffer allocation. Note that you'll probably not be able to use derived classes, Image and ImageBuffer are quite tied together and were not designed with extensibility in mind. So you'll probably have to modify the methods directly in the U++ sources, meaning you'll have to maintain it when new versions come out, which can be quite a burden sometimes Consider yourself warned
But... Are you sure memcpy is a problem here? It usually takes much less time than generating the image. Don't forget what Donald Knuth said Quote: | We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.
|
Honza
|
|
|
Re: Displaying raw image data [message #39750 is a reply to message #39738] |
Tue, 23 April 2013 11:04 |
keltor
Messages: 73 Registered: February 2012
|
Member |
|
|
Oh, no, I meant to create a class derived from my image library. I planned to make some kind of wrapper that contains both the class that deals with the image and a pointer to the memory that can be accessed by Upp::Image, as per your first example.
However, you are probably right, I may be too paranoid. Images, even in uncompressed format, tend to be rather small for today's standards. Copying 5, 10 or 30 MB is next to nothing. My original motivation was that the user may interact with the image in real time, rotate it in 3D and such. So I thought that it would reduce the refresh time if I'd do it without memcpy. But I will make it as you suggest first, and see how fast it is. The more I think about it, the more I agree that there is basically no overhead.
Thanks again, I'll get to it now.
Kel
[Updated on: Tue, 23 April 2013 11:05] Report message to a moderator
|
|
|
|
|
|
|
|
Re: Displaying raw image data [message #39783 is a reply to message #39778] |
Fri, 26 April 2013 13:31 |
|
keltor wrote on Fri, 26 April 2013 08:37 | Image expects a RGBA*, while I have an unsigned char*. Force-casting does not work (naturally), the image just displays some garbage.
| Casting should work, I do it quite often The only restriction that your library must return data in same order as they are sorted in RGBA, that is {B,G,R,A} if I remember it correctly. Otherwise the color channels would be switched, which might result in garbled data as you describe.
Anyway, I'm glad to hear you found a working solution
Honza
|
|
|
Goto Forum:
Current Time: Wed Dec 04 15:59:46 CET 2024
Total time taken to generate the page: 0.02198 seconds
|