Load an display a 32 bit (with alpha) png

30 posts / 0 new
Last post
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
Load an display a 32 bit (with alpha) png

Hello everyone,

this time i'm trying to understand how a picture can be loaded and displayed on amigaos4.

I'm talking about 32 bit png image with alpha channel.

the following code (WINDOW_BackFillName, "Sys:Prefs/Presets/Patterns/Chalk/ChalkBlue.brush) can load directly an image at window creation time, but i'm not sure if this image can be 32 bit png with alpha channel...

if ((winobj = IIntuition->NewObject (WindowClass,NULL,
WA_PubScreen, scr,
WA_Title, title,
WA_Flags, WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_SIZEBBOTTOM | WFLG_SIZEGADGET | WFLG_ACTIVATE,
WA_IDCMP, IDCMP_VANILLAKEY | IDCMP_INTUITICKS,
WA_Width, scr->Width * 6 / 10,
WA_Height, scr->Height * 4 / 10,
WINDOW_NewMenu,newmenu,
WINDOW_BackFillName, "Sys:Prefs/Presets/Patterns/Chalk/ChalkBlue.brush",

zzd10h
zzd10h's picture
Offline
Last seen: 7 years 2 weeks ago
Joined: 2012-08-24 20:56
What do you want to know

What do you want to know ?
How to display an alpha picture on a Reaction window ?

Like these 2 littles alpha png pictures?

http://zzd10h.amiga-ng.org/GFXDock/GFXDock_Reaction.jpg

AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
How to display an alpha


How to display an alpha picture on a Reaction window ?

Like these 2 littles alpha png pictures?

this would be interesting to know too.

I would like to know how to load an image from disk and display it on a window.
The image should be 32 bit with alpha, for future usage with blitting functions

zzd10h
zzd10h's picture
Offline
Last seen: 7 years 2 weeks ago
Joined: 2012-08-24 20:56
Edit : post removed Ok,

Edit : post removed

Ok, miserdunstood,
It was not that I pasted here !

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
struct BitMap
  1. struct BitMap *LoadBitMapARGB(CONST_STRPTR filename, uint32 *width, uint32 *height) {
  2. Object *dtobject;
  3.  
  4. dtobject = IDataTypes->NewDTObject(filename,
  5. DTA_GroupID, GID_PICTURE,
  6. PDTA_ModeID, PMODE_V43,
  7. TAG_END);
  8.  
  9. if (dtobject != NULL) {
  10. struct BitMapHeader *bmh = NULL;
  11.  
  12. IDataTypes->GetDTAttrs(dtobject,
  13. PDTA_BitMapHeader, &bmh,
  14. TAG_END);
  15.  
  16. if (bmh != NULL) {
  17. struct BitMap *bm;
  18.  
  19. bm = IP96->p96AllocBitMap(bmh->bmh_Width, bmh->bmh_Height, 32, 0, NULL, RGBFB_A8R8G8B8);
  20.  
  21. if (bm != NULL) {
  22. struct RenderInfo ri;
  23. LONG lock;
  24. struct pdtBlitPixelArray pbpa;
  25.  
  26. lock = IP96->p96LockBitMap(bm, (APTR)&ri, sizeof(ri));
  27.  
  28. pbpa.MethodID = PDTM_READPIXELARRAY;
  29. pbpa.pbpa_PixelData = ri.Memory;
  30. pbpa.pbpa_PixelFormat = PBPAFMT_ARGB
  31. pbpa.pbpa_PixelArrayMod = ri.BytesPerRow;
  32. pbpa.pbpa_Left = 0;
  33. pbpa.pbpa_Top = 0;
  34. pbpa.pbpa_Width = bmh->bmh_Width;
  35. pbpa.pbpa_Height = bmh->bmh_Height;
  36. IIntuition->IDoMethodA(dtobject, &pbpa);
  37.  
  38. IP96->UnlockBitMap(bm, lock);
  39.  
  40. IDataTypes->DisposeDTObject(dtobject);
  41.  
  42. *width = bmh->bmh_Width;
  43. *height = bmh->bmh_Height;
  44. return bm;
  45. }
  46. }
  47. IDataTypes->DisposeDTObject(dtobject);
  48. }
  49. return NULL;
  50. }
AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
Nice! Thank you salass! The

Nice! Thank you salass!

The returned bitmap could be blitted on a window?

AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
I got some error: passing

I got some error:

passing argument 3 of 'IIntuition->IDoMethodA' from incompatible pointer type

and

'struct P96IFace' has no member named 'UnlockBitMap'

should this "IP96->UnlockBitMap(bm, lock);" be "IP96->p96UnlockBitMap(bm, lock)" ?

Is this line missing a semicolon? pbpa.pbpa_PixelFormat = PBPAFMT_ARGB

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
passing argument 3 of


passing argument 3 of 'IIntuition->IDoMethodA' from incompatible pointer type

Just add a cast like so:
IIntuition->IDoMethodA(dtobject, (Msg)&pbpa);


should this "IP96->UnlockBitMap(bm, lock);" be "IP96->p96UnlockBitMap(bm, lock)" ?

Is this line missing a semicolon? pbpa.pbpa_PixelFormat = PBPAFMT_ARGB

Yes to both questions.

AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
Incredible! I corrected my

Incredible! I corrected my teacher the Gran coder Master :P

Can you please add the little example of how to blit to a window?

AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
Sorry, double post.

Sorry, double post.

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
I made a simple example with

I made a simple example with a bouncing ARGB boing ball (boing ball PNG image found with google image search):
https://dl.dropboxusercontent.com/u/26599983/boing.lha

In a real program you should rather use timer.device than IDCMP_INTUITICKS but it works well enough here for this rather simple example.

AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
Thank you again, salass. It

Thank you again, salass. It works!

I get 2 times a warning for the line:

boing_bm = LoadBitMapARGB("PROGDIR:boing.png", &boing_width, &boing_height);

warning: pointer targets in passing argument 2 of 'LoadBitMapARGB' differ in signedness

Now, it is possible to blit beetween two bitmap? A sort of composing image in memory, then blit to a window?

Thank you

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
I get 2 times a warning for


I get 2 times a warning for the line:

boing_bm = LoadBitMapARGB("PROGDIR:boing.png", &boing_width, &boing_height);

Shouldn't happen unless you went and changed something.

I compiled with -Wall and -Werror which means if there was a warning it would be treated as an error and the compile would fail.

Prototype of function is (I changed the 2nd and 3rd parameters from "uint32 *" to "int32 *"):
struct BitMap *LoadBitMapARGB(CONST_STRPTR, int32 *, int32 *);

The boing_width and boing_height variables are both defined as int32.


Now, it is possible to blit beetween two bitmap? A sort of composing image in memory, then blit to a window?

Yes, just set BLITA_DestType to BLITT_BITMAP instead of BLITT_RASTPORT and pass a bitmap pointer to BLITA_Dest. BltBitMapTagList/Tags() is the new one size fits all replacement for the now deprecated BltBitMap(), BltBitMapRastPort(), BltMaskBitMapRastPort(), etc. functions.

AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
I changed struct BitMap

I changed

struct BitMap *LoadBitMapARGB(CONST_STRPTR, uint32 *, uint32 *);

to

struct BitMap *LoadBitMapARGB(CONST_STRPTR, int32 *, int32 *);

and the warning disappeared.

Thank you

Btw, if i resize the window, the loaded image disappear

AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
Hello, two things remains to

Hello,

two things remains to be done with the image:

1) i would like to make permanent the image (if i resize a window the image disappear)
2) i would like to use hardware accelerate functions (compositing) to blit the image

How can i do this?

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
@AmigaBlitter If you explain

@AmigaBlitter

If you explain what exactly you want to do and why you need the window to be resizable I could write a more appropriate example code.

AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
No need a resizable window.

No need a resizable window. It's just to learn in this case.

About the other way to blit (via compositing) is cause i want to use hw acceleration where possible and, also in this case, to learn.

AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
@salass00 i tried to use the

@salass00

i tried to use the composite tags instead of using regular blitting methods, but i don't get any image on screen.

  1. //IGraphics->BltBitMapTags(
  2. //BLITA_DestX, win->BorderLeft + boing_x,
  3. //BLITA_DestY, win->BorderTop + boing_y,
  4. //BLITA_Width, boing_width,
  5. //BLITA_Height, boing_height,
  6. //BLITA_SrcType, BLITT_BITMAP,
  7. //BLITA_Source, boing_bm,
  8. //BLITA_DestType, BLITT_RASTPORT,
  9. //BLITA_Dest, win1->RPort,
  10. //BLITA_UseSrcAlpha, TRUE,
  11. //TAG_END);
  12.  
  13. IGraphics->CompositeTags(COMPOSITE_Src_Over_Dest,
  14. boing_bm,
  15. win1->RPort,
  16. COMPTAG_SrcWidth, boing_width,
  17. COMPTAG_SrcHeight, boing_height,
  18. COMPTAG_DestX, win->BorderLeft + boing_x,
  19. COMPTAG_DestY, win->BorderTop + boing_y,
  20. COMPTAG_Flags, COMPFLAG_IgnoreDestAlpha,
  21. TAG_DONE);

Btw, i get this warning too:
warning: passing argument 4 of 'IGraphics->CompositeTags' from incompatible pointer type

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
That's because you need a

That's because you need a bitmap as the destination for CompositeTags() so you need to composite blit into an off-screen bitmap first and then blit that into your window using BltBitMapTags().

This is what I do in my CDXL player, CDXLPlay (source code included).

AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
So i should create a

So i should create a secondary bitmap where to blit via composite tags, then using again BltBitMapTags to blit to the window->Rport?

What's the benefit of this?

I mean, using the composite tags implies one more operation than regular blitting.

thomas
thomas's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2011-05-16 14:23
What's the benefit of

What's the benefit of this?

Proper graphics handling in a multitasking enviroment.

As you've been told, the destination of Composite is a bitmap. But your window does not own a bitmap, it only has a rastport which shares the screen's bitmap with all other windows on this screen.

If you blit into window->RPort->BitMap no clipping will be done and you most likely overwrite areas of the screen which do not belong to your application. Not to mention that coordinates will be all wrong.

If you need proper clipping (and you always need it) you have to blit into the window's rastport, not into the screen's bitmap.

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
I added an additional example

I added an additional example (boing2) which uses CompositeTags(), an offscreen bitmap and a simple refresh window:
https://dl.dropboxusercontent.com/u/26599983/boing.lha

Using an offscreen bitmap the drawing and blitting functions (apart from the one that blits to the window) don't need to care about clipping so it may pay off in the end if you have more than one graphic to blit. Also it makes implementing IDCMP_REFRESHWINDOW pretty easy for a simple refresh window.

Using ILayers->DoHookClipRects() and COMPTAG_DestX/DestY/DestWidth/DestHeight tags you could do a clipped composite blit but it might be more trouble than it's worth with the above in mind.

AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
I just want to thank you all

I just want to thank you all of you for all these explainations.
Coming from Windows world, having forgot all of amiga programming world, it's really hard for me to step in to the reaction/intuition/ macro, not macro and so on...

Btw, thanks to all of you, i'm slowly learning how to manage things on the amiga way.
Thank you to Hans de Ruiter to for his precious infos

:)

AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
I used your example and now i

I used your example and now i can load 32 bit png image into a window, using simple bitblit or composite tag.

Btw, i have some problems.

I created a secondary off screen bitmap just like in your example.
Now, if i load a secondary bitmap (a png) and try to blit this into another window, i get some graphics errors (glitch) in the destination window. it could be the result of a non standard 32 bit png image? I created this image with PhotoShop, btw.

Another thing i noticed is that if i blit the image into a window with a backfill, the blitted image is not clipped.

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
I created a secondary off


I created a secondary off screen bitmap just like in your example.
Now, if i load a secondary bitmap (a png) and try to blit this into another window, i get some graphics errors (glitch) in the destination window. it could be the result of a non standard 32 bit png image? I created this image with PhotoShop, btw.

Not knowing what exactly you're doing it's hard to tell what you're doing wrong.


Another thing i noticed is that if i blit the image into a window with a backfill, the blitted image is not clipped.

What do you mean by not being clipped? Do you mean that it draws outside your window or just that it overdraws your window's border graphics? If it's the latter you can fix it by using a Gimme-Zero-Zero (GZZ) window.

Note that GZZ windows use more resources than regular windows as they have two layers (one for the borders and one for the window contents). Also when using a GZZ window you do not need to offset rendering coordinates with window->BorderLeft and window->BorderTop as you would otherwise.

AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
Hi, i solved the glitches

Hi,

i solved the glitches problem: wrong width and height blit values.
Maybe i used the wrong term using "clipping", sorry.
What i'm not able to do is "transparent blitting".
I thought so cause i have an hold code with two function (make_alpha_clip) and (allocate_alpha_bitmap) that get me confused. Sorry for this.

AmigaBlitter
AmigaBlitter's picture
Offline
Last seen: 6 years 9 months ago
Joined: 2012-02-18 19:55
Solved the transparent blit

Solved the transparent blit too using Hans suggestions about compositing.

Thank you

mritter0
mritter0's picture
Offline
Last seen: 2 years 5 months ago
Joined: 2014-04-21 21:15
Re: Load an display a 32 bit (with alpha) png

With the Picasso96 functions now deprecated, what is the new V54 graphics version of this? All I get now, without the pdtBlitPixelArrayBuffer lines, is a blank box the size of the image.

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
Re: Load an display a 32 bit (with alpha) png

The LoadBitMapARGB() function rewritten using graphics.library functions:

  1. struct BitMap *LoadBitMapARGB(CONST_STRPTR filename, uint32 *width, uint32 *height) {
  2. Object *dtobject;
  3.  
  4. dtobject = IDataTypes->NewDTObject(filename,
  5. DTA_GroupID, GID_PICTURE,
  6. PDTA_ModeID, PMODE_V43,
  7. TAG_END);
  8.  
  9. if (dtobject != NULL) {
  10. struct BitMapHeader *bmh = NULL;
  11.  
  12. IDataTypes->GetDTAttrs(dtobject,
  13. PDTA_BitMapHeader, &bmh,
  14. TAG_END);
  15.  
  16. if (bmh != NULL) {
  17. struct BitMap *bm;
  18.  
  19. bm = IGraphics->AllocBitMapTags(bmh->bmh_Width, bmh->bmh_Height, 32,
  20. BMATags_PixelFormat, PIXF_A8R8G8B8,
  21. BMATags_BitmapInvisible, TRUE,
  22. TAG_END);
  23.  
  24. if (bm != NULL) {
  25. APTR lock;
  26. APTR mem;
  27. uint32 bpr;
  28. struct pdtBlitPixelArray pbpa;
  29.  
  30. lock = IGraphics->LockBitMapTags(bm,
  31. LBM_BaseAddress, &mem,
  32. LBM_BytesPerRow, &bpr,
  33. TAG_END);
  34.  
  35. pbpa.MethodID = PDTM_READPIXELARRAY;
  36. pbpa.pbpa_PixelData = mem;
  37. pbpa.pbpa_PixelFormat = PBPAFMT_ARGB
  38. pbpa.pbpa_PixelArrayMod = bpr;
  39. pbpa.pbpa_Left = 0;
  40. pbpa.pbpa_Top = 0;
  41. pbpa.pbpa_Width = bmh->bmh_Width;
  42. pbpa.pbpa_Height = bmh->bmh_Height;
  43. IIntuition->IDoMethodA(dtobject, (Msg)&pbpa);
  44.  
  45. IGraphics->UnlockBitMap(bm, lock);
  46.  
  47. IDataTypes->DisposeDTObject(dtobject);
  48.  
  49. *width = bmh->bmh_Width;
  50. *height = bmh->bmh_Height;
  51. return bm;
  52. }
  53. }
  54. IDataTypes->DisposeDTObject(dtobject);
  55. }
  56. return NULL;
  57. }
mritter0
mritter0's picture
Offline
Last seen: 2 years 5 months ago
Joined: 2014-04-21 21:15
Re: Load an display a 32 bit (with alpha) png

Thank you. I was close, but I was supplying the tag values for LockBitMapTags() instead of "setting/getting" them for the lines below.

Log in or register to post comments