In my display program, if a picture is larger than the width of the screen it is automatically scrolled slowly across the screen. It's a nice effect and one I want to keep. Implementing it was simple: I plotted the picture using the jpeg routine from the BB4W Help, subtracted 2 from the horizontal position and re-plotted. It wasn't particularly fast, but it was good enough.
I'm now trying to do the same thing using imglip, but it is horribly slow. Looking at PROC_imgPlot I suspect that it is the overheads of creating, manipulating and deleting the matrices which are slowing things down. I'm afraid I don't know anything about matrix arithmetic; can anyone suggest a simple way of re-plotting the image 2 pixels to the left? (Or, of course, to the right.)
Many thanks.
imglib again
Re: imglib again
Hi Kendall,
I'm having a look at this - I agree it's quite slow when you use it repeatedly with a large image (albeit I'm using a 6000 x 4000 image, which probably isn't a fair test in an 800 x 600 window!).
It does feel a bit as though you are using a sledgehammer to crack a nut, here though - using a routine which can move, scale and rotate an image (and has to try, even if each transformation is "nil") when all you want to do is plot it at a given point. Couldn't you use *MDISPLAY, or something similar (look at the routine in the manual for displaying JPG images, if you want to use JPGs on Windows).
I believe *MDISPLAY can handle JPGs natively in the SDL version? That might be a good reason to go for BBC-SDL in this case?
It appears that there is a GdipDrawImage command, which doesn't do all the fancy matrix stuff - you could try if that helps. I made a custom version of the library, which included
just before the equivalent GdipDrawImageFX instruction in PROC_imgInit, and a simplified plotting routine:
Then you can amend you main code to use
where I% is the address of your image (as before), x and y are the horizontal and vertical offsets (which you are looping by 2 - but it may now be in pixels - I've removed the divide by 2! I've probably also reversed the sense of y displacement - but you didn't mention wanting to use that). I've used an integer for the offset - you will see that the library code converts to 4 byte float.
Note that I've stripped out a lot of the "protection" in Richard's code, for things like plotting relative to a moved origin, on the assumption that you are looking for speed over robustness/flexibility. Having said that, it's not very evidently faster, at least with my very large images.
This should very much be seen as a tryout rather than finished code - enough for you to see if it's likely to solve your problem.
Best wishes,
D
I'm having a look at this - I agree it's quite slow when you use it repeatedly with a large image (albeit I'm using a 6000 x 4000 image, which probably isn't a fair test in an 800 x 600 window!).
It does feel a bit as though you are using a sledgehammer to crack a nut, here though - using a routine which can move, scale and rotate an image (and has to try, even if each transformation is "nil") when all you want to do is plot it at a given point. Couldn't you use *MDISPLAY, or something similar (look at the routine in the manual for displaying JPG images, if you want to use JPGs on Windows).
I believe *MDISPLAY can handle JPGs natively in the SDL version? That might be a good reason to go for BBC-SDL in this case?
It appears that there is a GdipDrawImage command, which doesn't do all the fancy matrix stuff - you could try if that helps. I made a custom version of the library, which included
Code: Select all
SYS "GetProcAddress", L@imglib%, "GdipDrawImage" TO `GdipDrawImage`
Code: Select all
REM Plot an image simply:
REM I% = pointer to image object
REM x = horizontal coordinate of centre of object (BBC BASIC units)
REM y = vertical coordinate of centre of object (BBC BASIC units)
DEF PROC_imgPlot_F(I%, x, y)
LOCAL R% : DIM R% LOCAL 15
IF @vdu.hr% SYS `GdipSetClipHrgn`, G@imglib%, @vdu.hr%, 0
SYS `SetBoundsRect`, @memhdc%, 0, 5
SYS `GdipDrawImage`, G@imglib%, !I%, FN_f4(x), FN_f4(y) TO result%
SYS `GetBoundsRect`, @memhdc%, R%, 0
SYS `OffsetRect`, R%, -@ox%, -@oy%
SYS `InvalidateRect`, @hwnd%, R%, 0
ENDPROC
Code: Select all
PROC_imgPlot_F(I%, (-x%),0)
Note that I've stripped out a lot of the "protection" in Richard's code, for things like plotting relative to a moved origin, on the assumption that you are looking for speed over robustness/flexibility. Having said that, it's not very evidently faster, at least with my very large images.
This should very much be seen as a tryout rather than finished code - enough for you to see if it's likely to solve your problem.
Best wishes,
D
-
- Posts: 327
- Joined: Wed 04 Apr 2018, 06:36
Re: imglib again
Thanks for the suggestions. My pictures are typically large in one dimension only - wider than 1280 and it scrolls horizontally, taller than 840 and it scrolls vertically.
I like Richard's idea of using a string variable to hold the image for *MDISPLAY, but of course with a large picture you get a NO ROOM error almost immediately and have to set HIMEM to a ridiculously high level.
I'll check out your routine and report back. To avoid the problem of having the library overwritten I have simply incorporated the multi-win version of GDPI into the program - it's not all that large - so adding in your bits will not be difficult.
I like Richard's idea of using a string variable to hold the image for *MDISPLAY, but of course with a large picture you get a NO ROOM error almost immediately and have to set HIMEM to a ridiculously high level.
I'll check out your routine and report back. To avoid the problem of having the library overwritten I have simply incorporated the multi-win version of GDPI into the program - it's not all that large - so adding in your bits will not be difficult.
-
- Posts: 327
- Joined: Wed 04 Apr 2018, 06:36
Re: imglib again
Yes, it is faster, but not as fast as the jpg routine.
The second problem is that like the original IMGLIB, it doesn't work with multiple windows and the call to DrawImage does not take the dc handle as the first parameter, as DrawImageFX does.
And a third problem is that with a wide picture it seems to automatically scale it so that it does not fill the screen vertically. (Mind you, it doesn't fill the screen horizontally either - seems to be about half the width of the screen but less than half the height of the screen.)
The second problem is that like the original IMGLIB, it doesn't work with multiple windows and the call to DrawImage does not take the dc handle as the first parameter, as DrawImageFX does.
And a third problem is that with a wide picture it seems to automatically scale it so that it does not fill the screen vertically. (Mind you, it doesn't fill the screen horizontally either - seems to be about half the width of the screen but less than half the height of the screen.)