Rotating a BMP image

Discussions related to graphics (2D and 3D), animation and games programming
RichardRussell

Re: Rotating a BMP image

Post by RichardRussell »

mikeg wrote: Tue 10 Mar 2020, 00:26 I did take a look at the Aliens example in BBCSDL and it was awesome. I will work with that tool.
If you are not particularly concerned about cross-platform compatibility then there are many examples that can be adapted, such as aliens.bbc for BBCSDL and David Williams's GFXLIB demos for BB4W. But if you are targetting both BB4W and BBCSDL (and don't want to have to write two versions of your program!) your best bet for relatively high performance cross-platform rotation, currently, is the BOX2DGFX library. That's optimised for Box2D however and there could be an argument for producing a more generic equivalent.

It would be easy enough (for me or anybody else) to break down the PROC_displayrotate() routine into its component parts - initialisation, image loading, rendering, cleanup - so that it could be used more like the BOX2DGFX routines, for example in order to dynamically rotate an image, without all the 'housekeeping' overhead on every single call.
mikeg
Posts: 101
Joined: Sat 23 Jun 2018, 19:52

Re: Rotating a BMP image

Post by mikeg »

there are many examples that can be adapted, such as aliens.bbc
I understand enough about the alien example to use it and tested it with my own PNG image. BUT

**** How did you make the transparent background work on the image? ****

Did you use Paint 3D to make a transparent canvas from the picture or did you use a special color or did you use a special utility?

OR the bigger question is.. can I make the transparent background using BBCSDL graphics and draw the image within BBCSDL?

Thanks.
Focus is on code subject. Feel free to judge the quality of my work.
RichardRussell

Re: Rotating a BMP image

Post by RichardRussell »

mikeg wrote: Tue 10 Mar 2020, 22:59How did you make the transparent background work on the image?
I'm pretty sure I didn't "make" the transparent background at all, I think I found the image on the web as a .PNG file with the transparency included. That's by far the easiest way if you can find a suitable stock image!
Did you use Paint 3D to make a transparent canvas from the picture or did you use a special color or did you use a special utility?
No, none of those. I'm not any kind of graphic artist (my father was, but I didn't inherit that skil!) so I wouldn't know where to start. I imagine that it's actually quite difficult to draw a sprite with a proper antialiased transparency mask, which is what you need for good quality. I expect there are image editors that let you draw with a 'transparent colour' but that will result in a hard-edged mask and the resulting aliases can be ugly.
OR the bigger question is.. can I make the transparent background using BBCSDL graphics and draw the image within BBCSDL?
Of course you could. You can do anything, if you're prepared to write the code!
RichardRussell

Re: Rotating a BMP image

Post by RichardRussell »

RichardRussell wrote: Wed 11 Mar 2020, 10:09Of course you could. You can do anything, if you're prepared to write the code!
In all fairness I should add that, if what you are trying to achieve is to create a PNG file in BBC BASIC, it's considerably easier in BBC BASIC for Windows (because there are API functions you can call to do it) than in BBC BASIC for SDL 2.0 (which would most likely need a 3rd-party library like libpng). So if it was me, and I wanted to create a PNG file (and I have done that in the past), I'd use BB4W; the trial version would probably be adequate.
RichardRussell

Re: Rotating a BMP image

Post by RichardRussell »

As discussed, the code I listed is intended as a simple replacement for *DISPLAY, with the additional ability to rotate the image. It's not suitable when performance is important (e.g. when dynamically rotating a sprite in a game) because every single time it's called the graphics subsystem is re-initialised, the image is re-read from file, and then everything is closed down again. This makes it self-contained, but wrecks the performance.

Consequently I have now written a pair of highly compatible libraries (imglib.bbc), one for BB4W and one for BBCSDL, which separate out the various steps. They are necessarily slightly more difficult to use, but should be much more suitable for real-time animation. Each library has four functions/procedures as follows:
  • PROC_imgInit: Call just once at the start of your program.
  • PROC_imgExit: Call just once at the end of your program (and when exiting on an error).
  • FN_imgLoad(): Load an image from a file, returning an integer 'handle'.
  • PROC_imgPlot(): Plot an image with a specified position, scale, rotation and flip.
A minimal program using them would be something like this:

Code: Select all

      INSTALL @lib$ + "imglib"

      ON ERROR PROC_imgExit : OSCLI "REFRESH ON" : : REPORT : END
      ON CLOSE PROC_imgExit : QUIT
      PROC_imgInit

      img%% = FN_imgLoad(@dir$ + "bbc256x.png")
      IF img%% = 0 ERROR 100, "Couldn't load bbc256x.png"

      COLOUR 128+2
      *REFRESH OFF
      REPEAT
        a += 0.5
        CLS
        PROC_imgPlot(img%%, 640, 500, 0.7, a, 0)
        *REFRESH
        IF INKEY$(-256) = "W" WAIT 2
      UNTIL FALSE
      END
Here are the libraries, they require the latest versions of BB4W (v6.13a) and BBCSDL (v1.11a)
Last edited by RichardRussell on Fri 17 Apr 2020, 11:34, edited 3 times in total.
DDRM

Re: Rotating a BMP image

Post by DDRM »

Hi Richard,

Thanks, that's very nice. I've updated both versions of BBC Basic and added both libraries!

Best wishes,

D
RichardRussell

Re: Rotating a BMP image

Post by RichardRussell »

I've made a small change to the BB4W library. Where it previously had:

Code: Select all

      SYS `GdipSetSmoothingMode`, G@imglib%, 2
it now has:

Code: Select all

      SYS `GdipSetInterpolationMode`, G@imglib%, 3
I realised that SetSmoothingMode controls drawing of lines and curves, whereas SetInterpolationMode controls scaling of images, which is what is relevant here. Setting it to 3 corresponds to bilinear interpolation; I think this is the default so in fact this change won't make any difference at all to the performance, but it means if you ever wanted to try changing it (e.g. 7 is the highest quality mode) it would actually have an effect!
DDRM

Re: Rotating a BMP image

Post by DDRM »

Hi Richard,

Does that need a parallel change to the GetProcAddress block?

Best wishes,

D
RichardRussell

Re: Rotating a BMP image

Post by RichardRussell »

DDRM wrote: Mon 30 Mar 2020, 16:01 Does that need a parallel change to the GetProcAddress block?
Yes, I changed that at the same time. Don't try to edit your own copy, it's too risky, re-grab the entire library from my edited post or download it from groups.io.