Sub GetColours (bmp As B4XBitmap) As List
Dim l As List
l.Initialize
Dim x As Int
Dim bc As BitmapCreator = CreateBC(bmp)
For x = 0 To bc.mWidth - 1 'Create a list of all the colors in the bitmap
For y = 0 To bc.mHeight - 1
l.add (Bit.ToHexString (bc.GetColor(x,y)))
Next
Next
l = RemoveDuplicates (l)
Return l
End Sub
Sub RemoveDuplicates(pList As List) As List 'Get rid of the duplicates
If pList = Null Or Not(pList.IsInitialized) Then Return pList
Dim lstNew As List : lstNew.Initialize
Dim objItem As Object
For i = 0 To pList.Size - 1
objItem = pList.Get(i)
If lstNew.IndexOf(objItem) = - 1 Then
lstNew.Add(objItem)
End If
Next
Return lstNew
End Sub
Oush! Great suggestion with using the map - FAR better.Use a map instead of a list. Color will be the key. You won't need to check for duplicates.
In any case in the value of each key you can insert the number of times that color is used
But if you want to use a Litst, the duplicate check list you can do it while loading colors and not with a second loop
Sub Class_Globals
Private Root As B4XView
Private xui As XUI
Private ImageView1 As B4XView
Private ImageView2 As B4XView
End Sub
Public Sub Initialize
B4XPages.GetManager.LogEvents = True
End Sub
'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
Root = Root1
Root.LoadLayout("MainPage")
End Sub
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
Private Sub Button1_Click
Dim bmp As B4XBitmap
Dim colourlist As Map
colourlist.Initialize
bmp = ImageView1.GetBitmap
bmp = bmp.Resize (320, 240, True)
bmp = BinColors (bmp) 'Change bitmap to 16 colours
colourlist = GetColours (bmp)
bmp = bmp.Resize (ImageView2.Width, ImageView2.Height,True) 'resize and display image
ImageView2.SetBitmap (bmp)
Log (colourlist) 'Always the same no matter what bitmap I use
End Sub
Private Sub CreateBC(bmp As B4XBitmap) As BitmapCreator
Dim bc As BitmapCreator
bc.Initialize(bmp.Width / bmp.Scale, bmp.Height / bmp.Scale)
bc.CopyPixelsFromBitmap(bmp)
Return bc
End Sub
Public Sub BinColors (bmp As B4XBitmap) As B4XBitmap
Dim bc As BitmapCreator = CreateBC(bmp)
Dim argb As ARGBColor
For x = 0 To bc.mWidth - 1
For y = 0 To bc.mHeight - 1
bc.GetARGB(x, y, argb)
argb.r = argb.r - (argb.r Mod 128)
argb.g = argb.g - (argb.g Mod 128)
argb.b = argb.b - (argb.b Mod 128)
bc.SetARGB(x, y, argb)
Next
Next
Return bc.Bitmap
End Sub
Sub GetColours (bmp As B4XBitmap) As Map
Dim m As Map
m.Initialize
Dim x As Int
Dim bc As BitmapCreator = CreateBC(bmp)
For x = 0 To bc.mWidth - 1 'Create a list of all the colors in the bitmap
For y = 0 To bc.mHeight - 1
m.Put (Bit.ToHexString (bc.GetColor(x,y)), Bit.ToHexString (bc.GetColor(x,y)))
Next
Next
Return m
End Sub
Use File - Export or zip, or if it is a B4XPages project use the comment link at the top of B4XMainPage.Trying to upload a demo project - 3k - getting this.
For x = 0 To bc.mWidth - 1
For y = 0 To bc.mHeight - 1
bc.GetARGB(x, y, argb)
argb.r = argb.r - (argb.r Mod 128) '<-- results in 0 or 128
argb.g = argb.g - (argb.g Mod 64) '<--- will result in 0,64,128 or 192
argb.b = argb.b - (argb.b Mod 128) '<-- results in 0 or 128
bc.SetARGB(x, y, argb)
Next
Next
Brilliant thank's @JordiCP and everyone else. That seems to have done the trick nicely.The routine you are using produces exactly 8 colors, since each component is reduced to 0 or 128, that is, 2 possible values, so pow(2,3)=8
If you want exactly 16 colors, one of the possibilities is to give a higher 'weight' to the green component, which is the one that usually holds more color information
B4X:For x = 0 To bc.mWidth - 1 For y = 0 To bc.mHeight - 1 bc.GetARGB(x, y, argb) argb.r = argb.r - (argb.r Mod 128) '<-- results in 0 or 128 argb.g = argb.g - (argb.g Mod 64) '<--- will result in 0,64,128 or 192 argb.b = argb.b - (argb.b Mod 128) '<-- results in 0 or 128 bc.SetARGB(x, y, argb) Next Next
So, you'll have 2*4*2 = 16 possible colors