Page 1 of 1

New 2D drawing mode: AlphaAdjust

Posted: Sun Jun 20, 2021 7:51 pm
by Seymour Clufley
Something that comes up a lot in my work is the need to use one image as the alpha mask for another. Unfortunately, none of PB's drawing modes are ideal for this. AlphaChannel simply sets the alpha without regard for the target alpha (new alpha is absolute, not relative to original), and AlphaClip paints on top of the source rather than adjust its alpha. I would like a drawing mode that adjusts the target alpha by the source alpha. An appropriate name for it would be AlphaAdjust or AlphaMultiply. Just now, the only way to do this is by using CustomFilterCallback (see demo below), which is very slow compared to a native drawing mode.

Demo of what it would do:

Code: Select all

Procedure RI(simg.i)
	iw = ImageWidth(simg)
	ih = ImageHeight(simg)
	
	win = OpenWindow(#PB_Any,0,0,iw,ih,"Report image",#PB_Window_BorderLess|#PB_Window_ScreenCentered)
	
	imgad = ImageGadget(#PB_Any,0,0,iw,ih,ImageID(simg))
	
	escapekey = 1
	spacekey = 2
	returnkey = 3
	AddKeyboardShortcut(win,#PB_Shortcut_Escape,escapekey)
	AddKeyboardShortcut(win,#PB_Shortcut_Space,spacekey)
	AddKeyboardShortcut(win,#PB_Shortcut_Return,returnkey)
	
	killtime = ElapsedMilliseconds()+timelimit
	Repeat
		we = WindowEvent()
		If we
			If we=#PB_Event_Menu
				Break
			EndIf
		Else
			Delay(10)
		EndIf
		If timelimt>0 And ElapsedMilliseconds()>killtime : Break : EndIf
	ForEver
	
	CloseWindow(win)
EndProcedure


Procedure.l AlphaAdjust(x, y, SourceColor.l, TargetColor.l)
  new_alpha.d = Alpha(TargetColor) / 255 * Alpha(SourceColor)
  ProcedureReturn RGBA(Red(TargetColor),Green(TargetColor),Blue(TargetColor),new_alpha)
EndProcedure


iw = 400
ih = 400

; create the alpha adjuster...
alpha_img = CreateImage(#PB_Any,iw,ih,32,#PB_Image_Transparent)
StartDrawing(ImageOutput(alpha_img))
DrawingMode(#PB_2DDrawing_AlphaBlend)
For x = 0 To iw Step 40
  alp.d = 255 - (255 / iw * x)
  Box(x,0,40,ih,RGBA(0,0,0,alp))
Next x
StopDrawing()

; create a solid red image
img = CreateImage(#PB_Any,iw,ih,32,RGBA(255,0,0,255))
; apply the alpha adjuster to it...
StartDrawing(ImageOutput(img))
DrawingMode(#PB_2DDrawing_CustomFilter) : CustomFilterCallback(@AlphaAdjust())
DrawAlphaImage(ImageID(alpha_img),0,0)
StopDrawing()

; draw the adjusted image over a solid blue background...
demo_img = CreateImage(#PB_Any,iw,ih,32,#Blue)
StartDrawing(ImageOutput(demo_img))
DrawAlphaImage(ImageID(img),0,0)
StopDrawing()

RI(demo_img)