Page 1 of 1

How do I take an image in memory and promote/convert it to a sprite?

Posted: Wed Apr 30, 2025 2:53 am
by Carm3D
I have an ImageID ready to go.. it's got a lovely alpha channel. How to I make a sprite out of it?

Re: How do I take an image in memory and promote/convert it to a sprite?

Posted: Wed Apr 30, 2025 3:03 am
by Carm3D
Nevermind... I figured it out 5 minutes after posting this. (Facepalm)

Re: How do I take an image in memory and promote/convert it to a sprite?

Posted: Wed Apr 30, 2025 6:38 am
by jacdelad
Post your result, maybe someone else finds this thread.

Re: How do I take an image in memory and promote/convert it to a sprite?

Posted: Wed Apr 30, 2025 10:48 am
by Carm3D
This procedure loads a premade greyscale Sprite Sheet and creates a sprite of whatever colour I choose, with the greyscale converted to the sprite's alpha channel.

You can see there is a 2nd set of RGB values and an "LEDMode" that isn't utilized yet. This will be for painting an alternate colour in the hot core of the colour channel for a vibrant LED effect.

Code: Select all

Procedure Disp_Sprite_Creator(Filename.s, LEDMode.b, MColR.a, MColG.a, MColB.a, AColR.a, AColG.a, AColB.a)
	UsePNGImageDecoder()
	DispImage = LoadImage(#PB_Any, "Data\" + Filename)
	If DispImage = 0
		ErrorDelivery = "Failed to load sprite sheet " + Filename + "."
		EndProgram()
	EndIf

	Protected ImgWidth.w = ImageWidth(DispImage)
	Protected ImgHeight.w = ImageHeight(DispImage)
	Debug "Sprite Sheet Size = " + Str(ImgWidth) + " x " + Str(ImgHeight)
	Protected WorkImage = CreateImage(#PB_Any, ImgWidth, ImgHeight, 32)
	Protected x.w
	Protected y.w
	Protected ColorPixel.l
	Protected AlphaPixel.c
	Protected WorkSprite.i

	If StartDrawing(ImageOutput(WorkImage))
		DrawingMode(#PB_2DDrawing_AllChannels)
		DrawImage(ImageID(DispImage), 0, 0)
		For y = 0 To (ImgHeight - 1)
			For x = 0 To (ImgWidth - 1)
				ColorPixel = Point(x, y)
				AlphaPixel = Red(ColorPixel)
				Plot(x, y, RGBA(MColR, MColG, MColB, AlphaPixel))
			Next
		Next
		StopDrawing()
	Else
		ErrorDelivery = "Failed to draw on new sprite " + Filename
		EndProgram()
		ProcedureReturn #False
	EndIf
	;SaveImage(WorkImage, "Debug_Output_" + Filename + ".png", #PB_ImagePlugin_PNG, 32)
	WorkSprite = CreateSprite(#PB_Any, ImgWidth, ImgHeight, #PB_Sprite_AlphaBlending)
	If WorkSprite = 0
		ErrorDelivery = "CreateSprite() failed on WorkImage " + WorkImage + "  (" + Filename + ")"
		EndProgram()
	EndIf
	StartDrawing(SpriteOutput(WorkSprite))
	DrawingMode(#PB_2DDrawing_AllChannels)
	DrawImage(ImageID(WorkImage), 0, 0)
	StopDrawing()

	FreeImage(DispImage)
	DispImage = 0
	FreeImage(WorkImage)
	WorkImage = 0

	Debug "Sprite Creation successful"
	ProcedureReturn WorkSprite
EndProcedure

Re: How do I take an image in memory and promote/convert it to a sprite?

Posted: Wed Apr 30, 2025 11:06 am
by miso
I would use linear interpolation. There are a lot of uses, in this example full white on your grayscale would represent your color, 128 gray would represent half its rgb values:

Code: Select all

;LERP
Procedure.f LERP(a.f,b.f,t.f)
   ProcedureReturn(((1.0-t.f)*a) + (b*t))
   ;ProcedureReturn(a + t*(b-a))
 EndProcedure
   
 ;INVERTED LERP
 Procedure.f INVLERP(a.f,b.f,v.f)
   If a=b : ProcedureReturn(1) : EndIf
   ProcedureReturn((v-a) / (b-a))
 EndProcedure
 
 ;REMAP
 ;(input minimum, input maximum, output minimum,output maximum, input value)
 Procedure.f remap(iMin.f,iMAX.f, oMin.f, oMax.f, v.f)  
   Define t.f
   t.f = INVLERP(iMin,iMAX,v)
   ProcedureReturn(LERP(oMin,oMax,t))
 EndProcedure
 
 
 grayscalevalue = 128
 
 targetred = 128
 targetgreen = 100
 targetblue = 255
 
 productred = remap(0,255,0,targetred,grayscalevalue)
 productgreen = remap(0,255,0,targetgreen,grayscalevalue)
 productblue = remap(0,255,0,targetblue,grayscalevalue)
  
 Debug productred
 Debug productgreen
 Debug productblue