Best way to render Large Size images
-
- Knows some wx things
- Posts: 25
- Joined: Tue May 11, 2021 1:49 pm
Best way to render Large Size images
I want to create an image window that displays a plot of data.
My problem is the data points are large (about 2 million).
If I allocate a pixel to each data point that would be an image size with a pixel width of 2million.
Obviously there isnt a screen that is 2million pixels wide so this is not practical. The way I thought to go about it was to "virtually draw" the entire graph. Then zoom out until the picture fits in the users screen. That way if the user zooms, the details are preserved.
Am I going about this the right way? Can anyone recommend some code to look at or try to get started?
My goal is to match matplotlibs rendering speed which is about 1-2 seconds for my dataset.
My problem is the data points are large (about 2 million).
If I allocate a pixel to each data point that would be an image size with a pixel width of 2million.
Obviously there isnt a screen that is 2million pixels wide so this is not practical. The way I thought to go about it was to "virtually draw" the entire graph. Then zoom out until the picture fits in the users screen. That way if the user zooms, the details are preserved.
Am I going about this the right way? Can anyone recommend some code to look at or try to get started?
My goal is to match matplotlibs rendering speed which is about 1-2 seconds for my dataset.
- doublemax@work
- Super wx Problem Solver
- Posts: 474
- Joined: Wed Jul 29, 2020 6:06 pm
- Location: NRW, Germany
Re: Best way to render Large Size images
Do you have an image that gives an idea of what you want to achieve?
2 million pixels is not that much, e.g. thats 1920x1080. Or is it 2 million in x-direction only and the values go in y-direction?
2 million pixels is not that much, e.g. thats 1920x1080. Or is it 2 million in x-direction only and the values go in y-direction?
-
- Knows some wx things
- Posts: 25
- Joined: Tue May 11, 2021 1:49 pm
Re: Best way to render Large Size images
Correct it would be 2 million in the x direction only. The Y values only go from 0 to 120 so I think I can get away with 360 or 480 as that pixel value but that still comes out to 720,000,000 pixels.doublemax@work wrote: ↑Mon Aug 02, 2021 11:01 am Do you have an image that gives an idea of what you want to achieve?
2 million pixels is not that much, e.g. thats 1920x1080. Or is it 2 million in x-direction only and the values go in y-direction?
As I read the data file I am building a List of x-values, I can add something in that same loop that builds the x-values that pre-constructs some sort of image or bitmap if that will help.
- doublemax@work
- Super wx Problem Solver
- Posts: 474
- Joined: Wed Jul 29, 2020 6:06 pm
- Location: NRW, Germany
Re: Best way to render Large Size images
On which platform do you need this to work?
I wouldn't use a bitmap for that. I'd go for a custom drawn control that renders a subset of the data at a given x-offset.
Do you need to draw points/circles or bars for each data value?
The maximum number of data points you need to render is the x-resolution of the screen, so about 5k max. Even if you zoom out to render all 2 million data points, you don't need to draw 2 million lines. You can either skip values or calculate an average (the latter will be slow).
In order to test if the performance is good enough, write a small sample that renders 5000 vertical lines or rectangles. I would suspect this should be fast enough for realtime display. (If you're under Windows, make sure to use Direct2D renderer)
I wouldn't use a bitmap for that. I'd go for a custom drawn control that renders a subset of the data at a given x-offset.
Do you need to draw points/circles or bars for each data value?
The maximum number of data points you need to render is the x-resolution of the screen, so about 5k max. Even if you zoom out to render all 2 million data points, you don't need to draw 2 million lines. You can either skip values or calculate an average (the latter will be slow).
In order to test if the performance is good enough, write a small sample that renders 5000 vertical lines or rectangles. I would suspect this should be fast enough for realtime display. (If you're under Windows, make sure to use Direct2D renderer)
-
- Knows some wx things
- Posts: 25
- Joined: Tue May 11, 2021 1:49 pm
Re: Best way to render Large Size images
It would be for Windows platform. Only lines currently, no circles.
I would be worried about aliasing so looping through for the max value would be mandatory I believe. I understand it would be slower (since I would have to loop through 2million points every time) but is this the only way?
Is it not feasible to virtually render the entire line, then adjust the userscale to draw to the users window size ? or would the above in effect be what I am trying to accomplish.
Also, Do you have any sample code that uses the Direct2D renderer?
Thanks for all the help DoubleMax
I would be worried about aliasing so looping through for the max value would be mandatory I believe. I understand it would be slower (since I would have to loop through 2million points every time) but is this the only way?
Is it not feasible to virtually render the entire line, then adjust the userscale to draw to the users window size ? or would the above in effect be what I am trying to accomplish.
Also, Do you have any sample code that uses the Direct2D renderer?
Thanks for all the help DoubleMax
- doublemax@work
- Super wx Problem Solver
- Posts: 474
- Joined: Wed Jul 29, 2020 6:06 pm
- Location: NRW, Germany
Re: Best way to render Large Size images
I'm note sure if any system can handle bitmaps with these dimensions. 2 millions x 480pixel would already require 1GB RAM when using 1 Byte per pixel. With 3 bytes per pixel, you're already at 3GB. Just try creating a bitmap of that size and see what happensIs it not feasible to virtually render the entire line, then adjust the userscale to draw to the users window size ? or would the above in effect be what I am trying to accomplish.
Check the "drawing" sample that comes with wxWidgets. It's a little hard to follow, in principle it goes like this:Do you have any sample code that uses the Direct2D renderer?
Code: Select all
void MyCanvas::OnPaint( wxPaintEvent &event )
{
wxPaintDC pdc(this);
wxGraphicsRenderer *d2dr = wxGraphicsRenderer::GetDirect2DRenderer();
wxGraphicsContext *gc = d2dr->CreateContext(pdc);
// use wxGraphicsContext methods to draw
delete gc;
}
Re: Best way to render Large Size images
I made some tests and on a 1920 pixel wide screen i get at least 20fps with a graphics height of 480pixel. Even if i calculate max or average values for each pixel.
So this should be no problem performance wise.
(and there is even room for more performance optimization )
So this should be no problem performance wise.
(and there is even room for more performance optimization )
Use the source, Luke!
Re: Best way to render Large Size images
I'd recommend to filter out those of points that overlapped with others with some reasonable precise. In that case you will have much less drawing.
Re: Best way to render Large Size images
Yes, that's what i did. I only rendered as many (vertical) lines as visible pixels in x-direction. To my surprise the calculation of max or average values had almost no impact on the performance. Modern memory performance is so incredible fast.
Use the source, Luke!
-
- Earned some good credits
- Posts: 119
- Joined: Wed May 19, 2021 11:17 pm
- Contact:
Re: Best way to render Large Size images
I would get the screen sizegeorgeplusplus wrote: ↑Mon Aug 02, 2021 8:38 am I want to create an image window that displays a plot of data.
My problem is the data points are large (about 2 million).
If I allocate a pixel to each data point that would be an image size with a pixel width of 2million.
Obviously there isnt a screen that is 2million pixels wide so this is not practical. The way I thought to go about it was to "virtually draw" the entire graph. Then zoom out until the picture fits in the users screen. That way if the user zooms, the details are preserved.
Am I going about this the right way? Can anyone recommend some code to look at or try to get started?
My goal is to match matplotlibs rendering speed which is about 1-2 seconds for my dataset.
create a wxMemoryDC based on a wxBitmap which is based on an wxImage of the screen size.
The wxImage is constructed from a data array.
Then depending on scroll and zoom settings,
I would write a function that renders the 2 million point dataset
or some subset of it to the screen size data array via interpolation.
Then Blit the wxMemoryDC which actually represents your rendered image.
So image size is always screen size and your rendering code is dynamic.
You need controls for a zoom and scroll input from the user.
You don't pre-render a really large image and then zoom into parts of it.
You can do this with wxPaintDC, don't need anything beyond that.
Note that each time you update your image array you will have to reset the data in the wxMemoryDC
Code: Select all
image.SetData( ImageArrayRGB, true );
image.SetAlpha( ImageArrayA, true );
memDC.SelectObject( wxNullBitmap );
bitmap = wxBitmap( image, 32 );
memDC.SelectObject( bitmap );
Re: Best way to render Large Size images
That's a good alternative if the required drawing operations are very simple (like points and lines).Note that each time you update your image array you will have to reset the data in the wxMemoryDC
But the conversion from wxImage to wxBitmap is slow (done pixel by pixel), so it would be better to use raw bitmap access to write directly into the bitmap. https://docs.wxwidgets.org/trunk/classw ... _data.html
Use the source, Luke!
-
- Knows some wx things
- Posts: 25
- Joined: Tue May 11, 2021 1:49 pm
Re: Best way to render Large Size images
Thanks for all the great suggestions. Definitly gonna give them a try. Ill report back on their performance as well.
-
- Knows some wx things
- Posts: 25
- Joined: Tue May 11, 2021 1:49 pm
Re: Best way to render Large Size images
Rendering Worked great it is extremely fast. The image is a bit gritty but I suppose thats what zoom is for. Thank you all for the help and suggestions.