29 August 2014, 20:11 | #1 |
XoXo/Tasko Developer
Join Date: Dec 2013
Location: Munich
Age: 48
Posts: 450
|
pngflux.library, load and draw PNG w/ alphachannel
Hi
I just finished v 2.3 of my pngflux.library, which can load and draw PNG files with alphachannel support. http://images.quicktunnels.net/pngflux_v1.0.zip http://images.quicktunnels.net/pngflux_v2.3.zip Please try it. Developer files for ASM and C are included (C includes by Thomas Rapp). Library sourcecode will be released after some finetuning. Thanks to Peter Keunecke for help with PNG decrunching and filtering. From the readme: Code:
=============================================================== CENTRAL FEATURES =============================================================== The library currently has five functions: Load() -> you supply a filenamen and pngflux does the rest Draw() -> you supply the object returned by Load(), a rastport and an x and y coordinate and pngflux does the rest DrawClip() -> you supply the object returned by Load(), a rastport and an x and y coordinate and additionally an x and y coordinate in the image and the width and height of the part to draw DrawArray()-> same as DrawClip() but 'draws' the part into an RGB array that you may provide GetAttr() -> you supply the object and an attribute number and you get the value associated with that number. Currently supported attributest are: PNGFA_ARGBData -> get a pointer to the RAW ARGB data. You may read the Width and the Height of the loaded image directly from public fields of the object. When you do not need the image anymore, just dispose it with exec.library FreeVec(). Errors that happen at loading may be examined with dos.library IoErr(), even such as when there is not enough memory. Last edited by AGS; 31 August 2014 at 21:06. |
29 August 2014, 21:23 | #2 |
Registered User
Join Date: Jan 2002
Location: Germany
Posts: 6,985
|
C includes attached.
IMHO you should not rely on the presence of cybergraphics.library but rather supply a function which works on a RGB array. You do this internally anyway, don't you? Additionally the draw function should alow to use only a part of the image, i.e. pngfDraw(object,src_x,src_y,rp,dest_x,dest_y,width,height). |
29 August 2014, 21:29 | #3 |
XoXo/Tasko Developer
Join Date: Dec 2013
Location: Munich
Age: 48
Posts: 450
|
Big thanks! Yes, I am working on an RGB array, but read it in from the screen with cgx and then after work put it back with WritePixelArray(). Is there another way that takes layers into respect?
Yes, I planned for a func that allows to draw a part of an image. |
30 August 2014, 10:01 | #4 | |
Registered User
Join Date: Jan 2002
Location: Germany
Posts: 6,985
|
Quote:
What I mean is that the main drawing function of your library should be pngfDrawToArray (src_obj, src_x, src_y, dest_array, dest_mod, dest_x, dest_y, w, h) Then you can easily make a function pngfDrawRect (src_obj, src_x, src_y, dest_rp, dest_x, dest_y, w, h) which does alloc array ReadPixelArray pngfDrawToArray WritePixelArray free array and the draw function which is just a special case of the above pngfDraw (src_obj, dest_rp, dest_x, dest_y) = pngfDrawRect (src_obj, 0, 0, dest_rp, dest_x, dest_y, src_obj->pfo_Width, src_obj->pfo_Height) The latter two should just fail if cybergraphics is not available, but the first one should always work, even on a plain OCS machine. |
|
30 August 2014, 10:18 | #5 |
XoXo/Tasko Developer
Join Date: Dec 2013
Location: Munich
Age: 48
Posts: 450
|
How can one apply an RGB array onto screen on an OCS machine?
|
30 August 2014, 10:27 | #6 |
Registered User
Join Date: Jan 2002
Location: Germany
Posts: 6,985
|
One can dither it down to 16 colors or HAM. Or save it as .jpg or .png.
|
30 August 2014, 10:54 | #7 |
XoXo/Tasko Developer
Join Date: Dec 2013
Location: Munich
Age: 48
Posts: 450
|
I don't understand. Drawing a part of the picture to an array? How would that involve the alphachannel?
|
30 August 2014, 13:00 | #8 |
Registered User
Join Date: Jan 2002
Location: Germany
Posts: 6,985
|
Imagine you want to make a chess game. You have one picture which shows the play field and another picture which contains all the chess pieces. Now you want to draw the black queen, so you take the left top edge of this piece and the width and height of a piece and draw only this part of the picture into the play field. Of course the picture with the chess pieces has an alpha channel. Each pixel has an alpha value, so it does not matter whether you draw the entire picture or only part of it.
Now why into an array? I didn't look into your library code, but I imagine that you do something like this: 1. you load the PNG image and create a PNGFObject. This is not much more than an ARGB array, so let's call it array1. 2. the draw function first has to get the pixel data from the screen. Therefore it allocates a temporary array and uses ReadPixelArray to read the data from the RastPort into this array. Lets call it array2. 3. now it applies the alpha blending, i.e. it combines array1 into array2 using the alpha value from array1. 4. to get the data back into the screen, it uses WritePixelArray to write array2 into the RastPort. All I want to suggest is to encapsulate step 3 into a seperate function so that the user can supply array2 wherever he gets it from. |
30 August 2014, 13:08 | #9 |
XoXo/Tasko Developer
Join Date: Dec 2013
Location: Munich
Age: 48
Posts: 450
|
Ok, I built another draw func: pngfDrawClip()
Code:
pngflux.library/pngfDrawClip pngflux.library/pngfDrawClip NAME pngfDrawClip -- draws a part of a PNG loaded with pngfLoad() into a RastPort with respect to the alphachannel SYNOPSIS pngfDrawClip(pngfobject, rp, x, y, sourcex, sourcey, w, h) a0 a1 d0 d1 d2 d3 d4 d5 void pngfDrawClip(struct PNGFObject *, struct RastPort *, WORD, WORD, UWORD, UWORD, UWORD, UWORD); FUNCTION Same as the pngfDraw() function but allows to specify a part of the image to be drawn. INPUTS pngfobject - pngflux object loaded with pngfLoad() rp - pointer to a RastPort structure x - x coordinate whereto draw the PNG image y - y coordinate whereto draw the PNG image sourcex - x coordinate in image sourcey - y coordinate in image w - width of part to draw h - height of part to draw SEE ALSO pngflux.library/pngfDraw() |
30 August 2014, 13:18 | #10 |
Registered User
Join Date: Jan 2002
Location: Germany
Posts: 6,985
|
Yes, array2 replaces rp in the function call. Rp already contains something, too. That's what alpha blending is all about.
|
30 August 2014, 13:24 | #11 |
XoXo/Tasko Developer
Join Date: Dec 2013
Location: Munich
Age: 48
Posts: 450
|
Currently I keep the array2 buffer in the size of one line of the image allocated within the object. Would it be fast enough to allocate it only when drawing, on the fly? (consider a lot of little objects like in a GUI)
Last edited by AGS; 30 August 2014 at 13:38. |
30 August 2014, 15:31 | #12 |
Registered User
Join Date: Jan 2002
Location: Germany
Posts: 6,985
|
I am quite sure that calling AllocVec and FreeVec once for each call to pngfDraw is a lot faster than calling ReadPixelArray and WritePixelArray for each row in the picture.
|
30 August 2014, 16:26 | #13 |
XoXo/Tasko Developer
Join Date: Dec 2013
Location: Munich
Age: 48
Posts: 450
|
Ah! And what about memory consumption for a picture of let us say screen size?
|
30 August 2014, 17:48 | #14 |
Registered User
Join Date: Jul 2008
Location: Poland
Posts: 662
|
Hello,
is this library faster than loading directly from libpng ? |
30 August 2014, 18:02 | #15 |
XoXo/Tasko Developer
Join Date: Dec 2013
Location: Munich
Age: 48
Posts: 450
|
Maybe. I am optimizing it and implementing the behaviour that Thomas mentioned.
It is written 100% in ASM. I don't know much about libpng. |
30 August 2014, 19:20 | #16 |
Registered User
Join Date: Jul 2008
Location: Poland
Posts: 662
|
Good, pngflux is not based on libpng (like dataypes) as I was thinking.
Tried with netsurf and works but it doesn't like 2 images (attached). Also colors are wrong but thats because ns needs ABGR attribute. I belive it is a matter of time when you add it. |
30 August 2014, 19:35 | #17 |
XoXo/Tasko Developer
Join Date: Dec 2013
Location: Munich
Age: 48
Posts: 450
|
It's now even faster as Thomas wrote that it is much faster when I draw the pic not line by line but in one batch.
|
30 August 2014, 19:56 | #18 |
XoXo/Tasko Developer
Join Date: Dec 2013
Location: Munich
Age: 48
Posts: 450
|
Yes, it's really fast, much faster than before. But I need some help: How do I calculate the starting byte in my image (ARGB) from having the x and y coordinate in it?
Ah! Probably this: X + (Y - 1) * width_in_bytes .... I try it Last edited by AGS; 30 August 2014 at 20:08. Reason: correction of the formula |
30 August 2014, 20:31 | #19 | |
Registered User
Join Date: Jan 2002
Location: Germany
Posts: 6,985
|
Quote:
correct is: Y * bytes_per_row + X * bytes_per_pixel usually bytes_per_row = bytes_per_pixel * width X and Y counting from 0 on the top left edge (therefore Y-1 cannot be right). |
|
30 August 2014, 20:38 | #20 |
XoXo/Tasko Developer
Join Date: Dec 2013
Location: Munich
Age: 48
Posts: 450
|
I have this:
d2 = x in image d3 = y in image Code:
ext.l d3 beq .add_imagex subq.w #1,d3 ; y in image - 1 move.l pfo_Width(a0),d7 mulu.w d7,d3 ; * width .add_imagex ext.l d2 add.l d2,d3 ; + x lsl.l #2,d3 ; * 4 bytes (ARGB) ah! -> Code:
move.l pfo_Width(a0),d7 mulu.w d7,d3 ; * width ext.l d2 lsl.l #2,d2 ; * 4 bytes (ARGB) add.l d2,d3 ; + x Last edited by AGS; 30 August 2014 at 20:42. Reason: better code added |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Looking for 2P PD Western Draw Game! | hansel75 | Looking for a game name ? | 2 | 13 April 2013 14:10 |
Anyone have Draw 4D Pro? | Pyromania | request.Apps | 3 | 31 December 2007 19:35 |
How to draw a (rubbish) zipstick with 10 shapes | killergorilla | Nostalgia & memories | 54 | 30 March 2007 04:25 |
Default draw | Retro1234 | support.Other | 1 | 02 July 2006 17:14 |
What ever happened to Draw Studio 2? | Pyromania | Amiga scene | 3 | 08 November 2002 02:32 |
|
|