B4J=true
Group=Default Group
ModulesStructureVersion=1
Type=StaticCode
Version=6.78
@EndOfDesignText@
'BC BitmapCreator routines, Static code module
Sub Process_Globals

End Sub

'extract the Red part
Public Sub ExtractRed (Image As B4XBitmap,  Value As Double) As B4XBitmap
	Private x, y As Int
	Private col0, col1 As ARGBColor
	Private Fact As Double
	Private bmcImage, bmcResult As BitmapCreator
	
	bmcImage.Initialize(Image.Width, Image.Height)
	bmcImage.CopyPixelsFromBitmap(Image)
	bmcResult.Initialize(Image.Width, Image.Height)
	
	Fact = Value / 100
	For y = 0 To Image.Height -1
		For x = 0 To Image.Width -1
			bmcImage.GetARGB(x, y, col0)
			col1.a = col0.a
			col1.r = col0.r
			col1.g = col0.g * Fact
			col1.b = col0.b * Fact
			bmcResult.SetARGB(x, y, col1)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

'extract the Green part
Public Sub ExtractGreen (Image As B4XBitmap,  Value As Double) As B4XBitmap
	Private x, y As Int
	Private col0, col1 As ARGBColor
	Private Fact As Double
	Private bmcImage, bmcResult As BitmapCreator
	
	bmcImage.Initialize(Image.Width, Image.Height)
	bmcImage.CopyPixelsFromBitmap(Image)
	bmcResult.Initialize(Image.Width, Image.Height)
	
	Fact = Value / 100
	For y = 0 To Image.Height -1
		For x = 0 To Image.Width -1
			bmcImage.GetARGB(x, y, col0)
			col1.a = col0.a
			col1.r = col0.r * Fact
			col1.g = col0.g 
			col1.b = col0.b * Fact
			bmcResult.SetARGB(x, y, col1)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

'extract the Blue part
Public Sub ExtractBlue (Image As B4XBitmap,  Value As Double) As B4XBitmap
	Private x, y As Int
	Private col0, col1 As ARGBColor
	Private Fact As Double
	Private bmcImage, bmcResult As BitmapCreator
	
	bmcImage.Initialize(Image.Width, Image.Height)
	bmcImage.CopyPixelsFromBitmap(Image)
	bmcResult.Initialize(Image.Width, Image.Height)
	
	Fact = Value / 100
	For y = 0 To Image.Height -1
		For x = 0 To Image.Width -1
			bmcImage.GetARGB(x, y, col0)
			col1.a = col0.a
			col1.r = col0.r * Fact
			col1.g = col0.g * Fact
			col1.b = col0.b 
			bmcResult.SetARGB(x, y, col1)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

'remove the Red part
Public Sub RemoveRed (Image As B4XBitmap,  Value As Double) As B4XBitmap
	Private x, y As Int
	Private col0, col1 As ARGBColor
	Private Fact As Double
	Private bmcImage, bmcResult As BitmapCreator
	
	bmcImage.Initialize(Image.Width, Image.Height)
	bmcImage.CopyPixelsFromBitmap(Image)
	bmcResult.Initialize(Image.Width, Image.Height)
	
	Fact = Value / 100
	For y = 0 To Image.Height -1
		For x = 0 To Image.Width -1
			bmcImage.GetARGB(x, y, col0)
			col1.a = col0.a
			col1.r = col0.r * Fact
			col1.g = col0.g
			col1.b = col0.b 
			bmcResult.SetARGB(x, y, col1)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

'remove the Green part
Public Sub RemoveGreen (Image As B4XBitmap,  Value As Double) As B4XBitmap
	Private x, y As Int
	Private col0, col1 As ARGBColor
	Private Fact As Double
	Private bmcImage, bmcResult As BitmapCreator
	
	bmcImage.Initialize(Image.Width, Image.Height)
	bmcImage.CopyPixelsFromBitmap(Image)
	bmcResult.Initialize(Image.Width, Image.Height)
	
	Fact = Value / 100
	For y = 0 To Image.Height -1
		For x = 0 To Image.Width -1
			bmcImage.GetARGB(x, y, col0)
			col1.a = col0.a
			col1.r = col0.r
			col1.g = col0.g * Fact
			col1.b = col0.b 
			bmcResult.SetARGB(x, y, col1)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

'remove the Blue part
Public Sub RemoveBlue (Image As B4XBitmap,  Value As Double) As B4XBitmap
	Private x, y As Int
	Private col0, col1 As ARGBColor
	Private Fact As Double
	Private bmcImage, bmcResult As BitmapCreator
	
	bmcImage.Initialize(Image.Width, Image.Height)
	bmcImage.CopyPixelsFromBitmap(Image)
	bmcResult.Initialize(Image.Width, Image.Height)
	
	Fact = Value / 100
	For y = 0 To Image.Height -1
		For x = 0 To Image.Width -1
			bmcImage.GetARGB(x, y, col0)
			col1.a = col0.a
			col1.r = col0.r
			col1.g = col0.g
			col1.b = col0.b * Fact
			bmcResult.SetARGB(x, y, col1)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

'calculates the gray scale value to generate a gray scaled image
Public Sub GrayScale (Image As B4XBitmap) As B4XBitmap
	Private x, y, Gray As Int
	Private col0, col1 As ARGBColor
	Private bmcImage, bmcResult As BitmapCreator
	
	bmcImage.Initialize(Image.Width, Image.Height)
	bmcImage.CopyPixelsFromBitmap(Image)
	bmcResult.Initialize(Image.Width, Image.Height)
	
	For y = 0 To Image.Height -1
		For x = 0 To Image.Width -1
			bmcImage.GetARGB(x, y, col0)
			col1.a = col0.a
			Gray = col0.r * 0.21 + col0.g * 0.72 + 0.07 * col0.b
			col1.r = Gray
			col1.g = Gray
			col1.b = Gray
			bmcResult.SetARGB(x, y, col1)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

'calculates the mean scale value to generate a mean scaled image
Public Sub MeanScale (Image As B4XBitmap) As B4XBitmap
	Private x, y, Mean As Int
	Private col0, col1 As ARGBColor
	Private bmcImage, bmcResult As BitmapCreator
	
	bmcImage.Initialize(Image.Width, Image.Height)
	bmcImage.CopyPixelsFromBitmap(Image)
	bmcResult.Initialize(Image.Width, Image.Height)
	
	For y = 0 To Image.Height -1
		For x = 0 To Image.Width -1
			bmcImage.GetARGB(x, y, col0)
			col1.a = col0.a
			Mean = (col0.r + col0.g + col0.b) / 3
			col1.r = Mean
			col1.g = Mean
			col1.b = Mean
			bmcResult.SetARGB(x, y, col1)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

'calculates the sepia scale value to generate a mean scaled image
Public Sub SepiaScale (Image As B4XBitmap) As B4XBitmap
	Private x, y, SepiaR, SepiaG, SepiaB As Int
	Private col0, col1 As ARGBColor
	Private bmcImage, bmcResult As BitmapCreator
	
	bmcImage.Initialize(Image.Width, Image.Height)
	bmcImage.CopyPixelsFromBitmap(Image)
	bmcResult.Initialize(Image.Width, Image.Height)
	
	For y = 0 To Image.Height -1
		For x = 0 To Image.Width -1
			bmcImage.GetARGB(x, y, col0)
			col1.a = col0.a
			SepiaR = Min(255, 0.393 * col0.r + 0.769 * col0.g + 0.189 * col0.b)
			SepiaG = Min(255, 0.349 * col0.r + 0.686 * col0.g + 0.168 * col0.b)
			SepiaB = Min(255, 0.272 * col0.r + 0.534 * col0.g + 0.131 * col0.b)
			col1.r = SepiaR
			col1.g = SepiaG
			col1.b = SepiaB
			bmcResult.SetARGB(x, y, col1)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

'calculates the mean scale value to generate a mean scaled image
Public Sub BlackAndWhite (Image As B4XBitmap, Threshold As Int) As B4XBitmap
	Private x, y, Mean, BWCol As Int
	Private col0, col1 As ARGBColor
	Private bmcImage, bmcResult As BitmapCreator
	
	bmcImage.Initialize(Image.Width, Image.Height)
	bmcImage.CopyPixelsFromBitmap(Image)
	bmcResult.Initialize(Image.Width, Image.Height)
	
	For y = 0 To Image.Height -1
		For x = 0 To Image.Width -1
			bmcImage.GetARGB(x, y, col0)
			col1.a = col0.a
			Mean = (col0.r + col0.g + col0.b) / 3
			If Mean >= Threshold Then
				BWCol = 255
			Else
				BWCol = 0
			End If			
			col1.r = BWCol
			col1.g = BWCol
			col1.b = BWCol
			bmcResult.SetARGB(x, y, col1)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

'calculates the inverse color
Public Sub Inverse (Image As B4XBitmap) As B4XBitmap
	Private x, y As Int
	Private col0, col1 As ARGBColor
	Private bmcImage, bmcResult As BitmapCreator
	
	bmcImage.Initialize(Image.Width, Image.Height)
	bmcImage.CopyPixelsFromBitmap(Image)
	bmcResult.Initialize(Image.Width, Image.Height)
	
	For y = 0 To Image.Height -1
		For x = 0 To Image.Width -1
			bmcImage.GetARGB(x, y, col0)
			col1.a = col0.a
			col1.r = 255 - col0.r
			col1.g = 255 - col0.g
			col1.b = 255 - col0.b
			bmcResult.SetARGB(x, y, col1)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

'flips an image
'Orientation 0 = horizontally  1 = vertically  2 = both
Public Sub Flip(Image As B4XBitmap, Orientation As Int) As B4XBitmap
	Private xf, yf, x, y As Int
	Private col0 As ARGBColor
	Private bmcImage, bmcResult As BitmapCreator
	
	bmcImage.Initialize(Image.Width, Image.Height)
	bmcImage.CopyPixelsFromBitmap(Image)
	bmcResult.Initialize(Image.Width, Image.Height)
	Select Orientation
		Case 0
			For y = 0 To Image.Height - 1
				For x = 0 To Image.Width - 1
					bmcImage.GetARGB(x, y, col0)
					bmcResult.SetARGB(x, y, col0)
				Next
			Next
		Case 1
			For y = 0 To Image.Height - 1
				For x = 0 To Image.Width - 1
					xf = Image.Width - 1 - x
					bmcImage.GetARGB(x, y, col0)
					bmcResult.SetARGB(xf, y, col0)
				Next
			Next
		Case 2
			For y = 0 To Image.Height - 1
				For x = 0 To Image.Width - 1
					yf = Image.Height - 1 - y
					bmcImage.GetARGB(x, y, col0)
					bmcResult.SetARGB(x, yf, col0)
				Next
			Next
		Case 3
			For y = 0 To Image.Height - 1
				For x = 0 To Image.Width - 1
					xf = Image.Width - 1 - x
					yf = Image.Height - 1 - y
					bmcImage.GetARGB(x, y, col0)
					bmcResult.SetARGB(xf, yf, col0)
				Next
			Next
	End Select
	Return bmcResult.Bitmap
End Sub

'fills a gradient
'Orientation = TOP_BOTTOM, BOTTOM_TOP, LEFT_RIGHT, RIGHT_LEFT, TL_BR, TR_BL, BL_TR, BR_TL and RECTANGLE.
Public Sub FillGradient(Colors() As Int, Rect As B4XRect, Orientation As String) As B4XBitmap
	Private bmp As B4XBitmap
	
	Select Orientation
		Case "TOP_BOTTOM"
			bmp = FillGradientTB(Colors, Rect)
		Case "BOTTOM_TOP"
			bmp = FillGradientBT(Colors, Rect)
		Case "LEFT_RIGHT"
			bmp = FillGradientLR(Colors, Rect)
		Case "RIGHT_LEFT"
			bmp = FillGradientRL(Colors, Rect)
		Case "TL_BR"
			bmp = FillGradientTLBR(Colors, Rect)
	End Select
	Return bmp
End Sub

Private Sub FillGradientTB(Colors() As Int, Rect As B4XRect) As B4XBitmap
	Private k, x, y As Int
	Private col, col1, col2 As ARGBColor
	Private y1, fr, fg, fb As Double
	Private bmcResult As BitmapCreator
	
	bmcResult.Initialize(Rect.Width, Rect.Height)

	y1 = Rect.Height / (Colors.Length - 1)
	For y = 0 To Rect.Height - 1
		k = Min(Floor(y / y1), Colors.Length - 2)
		bmcResult.ColorToARGB(Colors(k), col1)
		bmcResult.ColorToARGB(Colors(k + 1), col2)
		fr = (col2.r - col1.r) / y1
		fg = (col2.g - col1.g) / y1
		fb = (col2.b - col1.b) / y1
		col.a = col1.a
		col.r = col1.r + fr * (y - y1 * k)
		col.g = col1.g + fg * (y - y1 * k)
		col.b = col1.b + fb * (y - y1 * k)
		For x = 0 To Rect.Width - 1
			bmcResult.SetARGB(x, y, col)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

Private Sub FillGradientBT(Colors() As Int, Rect As B4XRect) As B4XBitmap
	Private k, x, y As Int
	Private col, col1, col2 As ARGBColor
	Private y1, fr, fg, fb As Double
	Private bmcResult As BitmapCreator
	
	bmcResult.Initialize(Rect.Width, Rect.Height)

	y1 = Rect.Height / (Colors.Length - 1)
'	For y = 0 To Rect.Height - 1
	For y = Rect.Height - 1 To 0 Step -1
		k = Min(Floor(y / y1), Colors.Length - 2)
		bmcResult.ColorToARGB(Colors(k), col1)
		bmcResult.ColorToARGB(Colors(k + 1), col2)
		fr = (col2.r - col1.r) / y1
		fg = (col2.g - col1.g) / y1
		fb = (col2.b - col1.b) / y1
		col.a = col1.a
		col.r = col1.r + fr * (y - y1 * k)
		col.g = col1.g + fg * (y - y1 * k)
		col.b = col1.b + fb * (y - y1 * k)
		For x = 0 To Rect.Width - 1
			bmcResult.SetARGB(x, y, col)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

Private Sub FillGradientLR(Colors() As Int, Rect As B4XRect) As B4XBitmap
	Private k, x, y As Int
	Private col, col1, col2 As ARGBColor
	Private x1, fr, fg, fb As Double
	Private bmcResult As BitmapCreator
	
	bmcResult.Initialize(Rect.Width, Rect.Height)
	
	x1 = Rect.Width / (Colors.Length - 1)
	For x = 0 To Rect.Width - 1
		k = Min(Floor(x / x1), Colors.Length - 2)
		bmcResult.ColorToARGB(Colors(k), col1)
		bmcResult.ColorToARGB(Colors(k + 1), col2)
		fr = (col2.r - col1.r) / x1
		fg = (col2.g - col1.g) / x1
		fb = (col2.b - col1.b) / x1
		col.a = col1.a
		col.r = col1.r + fr * (x - x1 * k)
		col.g = col1.g + fg * (x - x1 * k)
		col.b = col1.b + fb * (x - x1 * k)
		For y = 0 To Rect.Height - 1
			bmcResult.SetARGB(x, y, col)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

Private Sub FillGradientRL(Colors() As Int, Rect As B4XRect) As B4XBitmap
	Private k, x, y As Int
	Private col, col1, col2 As ARGBColor
	Private x1, fr, fg, fb As Double
	Private bmcResult As BitmapCreator
	
	bmcResult.Initialize(Rect.Width, Rect.Height)
	
	x1 = Rect.Width / (Colors.Length - 1)
	For x = 0 To Rect.Width - 1
		k = Min(Floor(x / x1), Colors.Length - 2)
		bmcResult.ColorToARGB(Colors(k), col2)
		bmcResult.ColorToARGB(Colors(k + 1), col1)
		fr = (col2.r - col1.r) / x1
		fg = (col2.g - col1.g) / x1
		fb = (col2.b - col1.b) / x1
		col.a = col1.a
		col.r = col1.r + fr * (x - x1 * k)
		col.g = col1.g + fg * (x - x1 * k)
		col.b = col1.b + fb * (x - x1 * k)
		For y = 0 To Rect.Height - 1
			bmcResult.SetARGB(x, y, col)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

Private Sub FillGradientTLBR(Colors() As Int, Rect As B4XRect) As B4XBitmap
	Private k, x, y As Int
	Private col, col1, col2 As ARGBColor
	Private fr, fg, fb, Diagonal, Diagonal1, Distance As Double
	Private xb, yb, xc, yc, m As Double
	Private bmcResult As BitmapCreator
	
	bmcResult.Initialize(Rect.Width, Rect.Height)
	
	Diagonal = Sqrt(Rect.Width * Rect.Width + Rect.Height * Rect.Height)
	Diagonal1 = Diagonal/ (Colors.Length - 1)
	
	xb = Rect.Width
	yb = Rect.Height
	m = yb / xb
	
	For y = 0 To Rect.Height - 1
		For x = 0 To Rect.Width - 1
			xc = (x + m * y) / (1 + m * m)
			yc = -(xc - x) / m + y
			Distance = Sqrt(xc * xc + yc * yc)
			k = Distance / Diagonal1
			bmcResult.ColorToARGB(Colors(k), col1)
			bmcResult.ColorToARGB(Colors(k + 1), col2)
			fr = (col2.r - col1.r) / Diagonal1
			fg = (col2.g - col1.g) / Diagonal1
			fb = (col2.b - col1.b) / Diagonal1
			col.a = col1.a
			col.r = col1.r + fr * (Distance - k * Diagonal1)
			col.g = col1.g + fg * (Distance - k * Diagonal1)
			col.b = col1.b + fb * (Distance - k * Diagonal1)
			bmcResult.SetARGB(x, y, col)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

Public Sub FillGradientRadial(Colors() As Int, Rect As B4XRect) As B4XBitmap
	Private k, xc, yc, x, y As Int
	Private col, col1, col2 As ARGBColor
	Private r, Radius, fr, fg, fb As Double
	Private bmcResult As BitmapCreator
	
	bmcResult.Initialize(Rect.Width, Rect.Height)
		
	xc = Rect.Width / 2
	yc = Rect.Height / 2
	Radius = Sqrt(xc * xc + yc * yc) / (Colors.Length - 1)
	For x = 0 To Rect.Width - 1
		For y = 0 To Rect.Height - 1
			r = Sqrt((x - xc) * (x - xc) + (y - yc) * (y - yc))
			k = Min(Floor(r / Radius), Colors.Length - 2)
			bmcResult.ColorToARGB(Colors(k), col1)
			bmcResult.ColorToARGB(Colors(k + 1), col2)
			fr = (col2.r - col1.r) / Radius
			fg = (col2.g - col1.g) / Radius
			fb = (col2.b - col1.b) / Radius
			col.a = col1.a
			col.r = col1.r + fr * (r - Radius * k)
			col.g = col1.g + fg * (r - Radius * k)
			col.b = col1.b + fb * (r - Radius * k)
			bmcResult.SetARGB(x, y, col)
		Next
	Next
	Return bmcResult.Bitmap
End Sub

'Rotates the given bitmap by the given number of degrees
'Degrees values 90, -90, 180, 270 
Private Sub RotateBitmap(SourceBitmap As B4XBitmap, Degrees As Int) As B4XBitmap
	Private x, y As Int
	
	If Degrees <> Abs(90) And Degrees <> 180 And Degrees <> 270 Then
		Log("RotateBitmap routine, wrong number of degrees")
		Return SourceBitmap
	End If
	
	Private bmcSource, bmcDest As BitmapCreator
	bmcSource.Initialize(SourceBitmap.Width, SourceBitmap.Height)
	bmcSource.CopyPixelsFromBitmap(SourceBitmap)
	
	Select Case Degrees
		Case 90
			bmcDest.Initialize(SourceBitmap.Height, SourceBitmap.Width)
			For x = 0 To SourceBitmap.Height - 1
				For y = 0 To SourceBitmap.Width - 1
					bmcDest.SetColor(y, x, bmcSource.GetColor(x, y))
				Next
			Next
		Case -90, 270
			bmcDest.Initialize(SourceBitmap.Height, SourceBitmap.Width)
			For x = 0 To SourceBitmap.Height - 1
				For y = 0 To SourceBitmap.Width - 1
					bmcDest.SetColor(y, x, bmcSource.GetColor(x, y))
				Next
			Next
		Case 180
			bmcDest.Initialize(SourceBitmap.Width, SourceBitmap.Height)
			bmcDest.Initialize(SourceBitmap.Height, SourceBitmap.Width)
			For x = 0 To SourceBitmap.Height - 1
				For y = 0 To SourceBitmap.Width - 1
					bmcDest.SetColor(x, SourceBitmap.Width - 1 - y, bmcSource.GetColor(x, y))
				Next
			Next
	End Select
End Sub