Ooops
July 09, 2020, 10:49:35 AM

Author Topic: MaxGUI RGB and "Graphics" aRGB / RGBa  (Read 180 times)

Offline _PJ_

  • Jr. Member
  • **
  • Posts: 77
MaxGUI RGB and "Graphics" aRGB / RGBa
« on: June 03, 2020, 05:21:09 PM »
I am trying to ensure that the same RGB int (alpha channel is not considered) can be applied to an image ( as converted to PixMap and then using both WritePixel as well as ClearPixels) from the MaxGUI functionality.

I typically maintain RGB int with only 24 (3x8) bits:  R channel lowbyte, B highbyte but this does not seem to continue with the

Furthermore, when LockImage priduces a PixMap, it is not possible then to set the PixMap byte format, and there is no parameter for this in CreateImage either.




Sorry the example here got kinda messy as I added to it in trying to realise solution - I tried reordering the bytes in ConvertToImageRGB as well as changing aa between 0 and 255

___

I know that it's not an issue with DRAWING the canvas, since if I replace

   ClearPixels(p, NewRGB)

with a literal

   ClearPixels(p, -1 )
then it does, as expected turn full-white.

_______________________________________

Please can anyone offer any insight into the channel format for default "Image" created within BMax NG? Or otherwise how best to resolve this?


Code: [Select]
SuperStrict

Import MaxGUI.Drivers
Import MaxGUI.Localization
Import BRL.Standardio

Global R:Byte=0
Global G:Byte=0
Global B:Byte=0

Global RGB:Int = ((R Shl 0) & 255)|((G Shl 8) & 255)|((B Shl 0) & 255)

Global hwnd:TGADGET = CreateWindow("test",0,0,96,96,Null,WINDOW_TITLEBAR)

Global panel:TGadget = CreatePanel(0,0,16,16,hwnd)
Global canvas:Tgadget =CreateCanvas(32,0,16,16,hwnd)
Global button:Tgadget = CreateButton("Col",64,0,16,16,hwnd)

Global CLOSE:Byte =False

While Not(CLOSE)
EventHandler
Wend
End

Function EventHandler()
WaitEvent()

Select EventID()
Case EVENT_KEYDOWN
If (EventData() = KEY_ESCAPE)
CLOSE = True
End If

Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE
CLOSE = True
Case EVENT_GADGETACTION
If (EventSource()=button)
If (RequestColor(R,G,B))
R = RequestedRed()
G = RequestedGreen()
B = RequestedBlue()

RGB = ((R & 255) Shl 0) |((G & 255) Shl 8)|((B & 255) Shl 0)

UpdateCanvasImage
UpdatePanel
RedrawGadget hwnd
End If
End If
End Select
End Function

Function UpdateCanvasImage()
Local i:TImage = CreateImage(16,16)
Local p:TPixmap= LockImage(i)

Local newRGB:Int = ConvertToImageRGB(RGB)

ClearPixels(p, NewRGB)
UnlockImage i

SetGraphics CanvasGraphics(canvas)
DrawImage i,0,0
Flip
RedrawGadget(canvas)
End Function

Function UpdatePanel()
Local rr:Byte = (RGB Shr 0) & 255
Local gg:Byte = (RGB Shr 8) & 255
Local bb:Byte = (RGB Shr 16)& 255

SetGadgetColor(panel,rr,gg,bb,True)
RedrawGadget panel
End Function

Function ConvertToImageRGB:Int(RGB:Int)
Local rr:Byte = (RGB Shr 0) & 255
Local gg:Byte = (RGB Shr 8) & 255
Local bb:Byte = (RGB Shr 16)& 255

Local aa:Byte = 255

Local NewRGB:Int = bb Shr 0 | gg Shr 8 | rr Shr 16| aa Shr 24
Return NewRGB
End Function

Offline Derron

  • Hero Member
  • *****
  • Posts: 3034
Re: MaxGUI RGB and "Graphics" aRGB / RGBa
« Reply #1 on: June 03, 2020, 05:49:05 PM »
Function CreateImage:TImage( width,height,frames=1,flags=-1 )

As you see, it does not contain any "color format". Maybe it is omitted because of "TImage" being the thing sent to the GPU - while its pixel data is stored in the pixmap stored in it.



Function CreatePixmap:TPixmap( width,height,format,align_bytes=4 )

As you see here, it contains a "format" ...



So ... why is there a format? Some image formats (or texture formats) might favour a different color channel order than "RGBA".


To find out what format a a "loaded image" has you can simply print the pixmaps format value:


Code: BlitzMax
  1. local p:TPixmap = LockImage(MyImage)
  2. Select p.format
  3.   Case PF_A8  print "PF_A8"
  4.   Case PF_I8  print "PF_I8"
  5.   Case PF_RGB888  print "PF_RGB888"
  6.   Case PF_BGR888  print "PF_BGR888"
  7.   Case PF_RGBA8888  print "PF_RGBA8888"
  8.   Case PF_BGRA8888  print "PF_BGRA8888"
  9.   Default  print "unknown format"
  10. End Select
  11.  


So what could you do with it?

There is
Function ConvertPixmap:TPixmap( pixmap:TPixmap,format )
(or its direct method: MyPixmap.Convert(format))

It converts a pixmap from a different format into the one you need.

So you could something like this:

Code: BlitzMax
  1. Local img:TImage = LoadImage("myurl.png")
  2. if img and LockImage(img).format <> PF_RGBA8888
  3.   img = LoadImage( LockImage(img).Convert(PF_RGBA8888), img.flags ) 'pixmap can be used as "url" too, reuse flags used during intial load
  4. endif
  5.  
(you could even replace the "pixmaps" in the image to retain references to images but I think this is advanced stuff most probably complicating the answer more than it helps.)


And you can use above gained knowledge ... to create an empty/new image and check what format is used there :D

bye
Ron

Offline _PJ_

  • Jr. Member
  • **
  • Posts: 77
Re: MaxGUI RGB and "Graphics" aRGB / RGBa
« Reply #2 on: June 03, 2020, 06:23:05 PM »
Hi Derron.
I understand the pixel formats and why they are used. In fact, the project I am working on uses based on a 7 bit image format ( a la ZX spectrum  colour palette) - my problem here, is that the results of ClearPixels are not as I expect when passing an RGB value in the format that I assumed would be RGB888 or RGBa8888
_
Converting PixcMap is not ideal in this scenario, since doing so would create a new Instance and lose the association with the parent Image.

Thanks for providing the "PixMap.Format" method.

When I used this to retrieve the Format for the pixMap from the LockedImage, it informed me the Format is RGBA8888
Which in my ideal world, would mean

(R Shl 0)|(G Shl 8)|(B Shl 16)
Which is identical to the default GUI format and how I had expected...
But I was still having issues...

Firstly, the result was always black, so I presumed this was due to any colour channels being invisible as result of transparent alpha - so I forced an alpha channel of 255

(R Shl 0)|(G Shl 8)|(B Shl 16)|(255 Shl 24)

This helped - I was seeing colour! But... the Red and Blue were swapped. So I realised it would need to be

(B Shl 0)|(G Shl 8)|(R Shl 16)|(255 Shl 24)

Finally - It was working as intended!
___
That's when I found out::
I should have just paid more attention to the docs which specify::
Quote
The 32 bit argb value contains the following components:

bits 24-31 pixel alpha
bits 16-23 pixel red
bits 8-15 pixel green
bits 0-7 pixel blue
( Which I would rather call a BGRa value, to be honest, but at least, this has been a learning process for me!)



Offline Derron

  • Hero Member
  • *****
  • Posts: 3034
Re: MaxGUI RGB and "Graphics" aRGB / RGBa
« Reply #3 on: June 03, 2020, 06:41:05 PM »
Yes i did bgra too in my software image drawing stuff / imagehelper file at github.com/GWRon/dig.git

@pixmaps
You could replace the pixmaps within a TImage...alternatively you could read the pixels of the pixmap and split into r,g,b,a, join back as needed and writepixel it to the pixmap back.


Bye
Ron

Offline _PJ_

  • Jr. Member
  • **
  • Posts: 77
Re: MaxGUI RGB and "Graphics" aRGB / RGBa
« Reply #4 on: June 03, 2020, 06:50:38 PM »
Yes i did bgra too in my software image drawing stuff / imagehelper file at github.com/GWRon/dig.git

@pixmaps
You could replace the pixmaps within a TImage...alternatively you could read the pixels of the pixmap and split into r,g,b,a, join back as needed and writepixel it to the pixmap back.


Bye
Ron
Thank you - but it's fine, all solved now. Once I knew the ClearPixels required BGRa - I just created an override for ClearPixels so I can use the same values for WritePixel or ClearPixMap or any of the MaxGUI functions.

So aside from the one in the function definition here, I could Replace ClearPixels with ClearPixMap calls throughout the source!
Code: [Select]
Function ClearPixelMap(PixMap:TPixMap, RGB:Int)
 Local BGRa:Int = ((RGB Shr 0) & 255) Shl 16 | ((RGB Shr 8) & 255) Shl 8 |  ((RGB Shr 16) & 255) Shl 0 | 255 shl 24
 ClearPixels(PixMap,BGRa)
End Function

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal