If you need an image to test it out, go to http://weavesilk.com/ and create one.
This code isn't as versatile as it could be. I basically created it to turn a Weavesilk image into something I could use as a sprite. Feel free to modify it however you need.
; MakeSpriteImage( filepath.s, size = 128 )
; Loads the image with the specified filepath, trims off any excess black around the edges, and converts it to a square image with the size specified. The image will have a one-pixel border added.
; Note that the output images are best used with additive blending (eg. MaterialBlendingMode( test_material, #PB_Material_Add ) ).
Code: Select all
UsePNGImageDecoder()
UsePNGImageEncoder()
Procedure.i MakeSpriteImage( filepath.s, size = 128 )
; Loads the image with the specified filepath, trims off any excess black around the edges, and converts it to a square image with the size specified. The image will have a one-pixel border added.
; Note that the output images are best used with additive blending (eg. MaterialBlendingMode( test_material, #PB_Material_Add ) ).
; Returns the image number on success and a zero on failure.
If size < 8 : ProcedureReturn 0 : EndIf ; If the specified size is less than 8x8 then abort with a zero return.
source_image = LoadImage( #PB_Any, filepath.s )
If source_image = 0 : ProcedureReturn 0 : EndIf ; If the source image could not be loaded then abort with a zero return.
; Get the dimensions of the source image.
max_x = ImageWidth( source_image ) - 1
max_y = ImageHeight( source_image ) - 1
If max_x = -1 : ProcedureReturn 0 : EndIf ; If the source image was empty then abort with a zero return.
; -- Trim off any black borders. If the source image was blank then this block will clean up and abort with a zero value returned.
StartDrawing( ImageOutput( source_image ) )
trim_left = -1 ; Set the default for trim_left to flag an error if it is not modified.
For x = 0 To max_x
For y = 0 To max_y
If ( Point( x, y ) & $00ffffff ) <> $00000000 ; If the color channels are not the color black (ignoring the alpha channel) then we have found our trim point.
trim_left = x
Break 2
EndIf
Next
Next
If trim_left <> -1 ; If the image was not completely blank then continue and create the 'border_trim_image'. If it was blank then 'border_trim_image' will hold a zero.
; Get trim for top border.
For y = 0 To max_y
For x = 0 To max_x
If ( Point( x, y ) & $00ffffff ) <> $00000000 ; If the color channels are not the color black (ignoring the alpha channel) then we have found our trim point.
trim_top = y
Break 2
EndIf
Next
Next
; Get trim for right border.
For x = max_x To 0 Step -1
For y = 0 To max_y
If ( Point( x, y ) & $00ffffff ) <> $00000000 ; If the color channels are not the color black (ignoring the alpha channel) then we have found our trim point.
trim_right = x
Break 2
EndIf
Next
Next
; Get trim for bottom border.
For y = max_y To 0 Step -1
For x = 0 To max_x
If ( Point( x, y ) & $00ffffff ) <> $00000000 ; If the color channels are not the color black (ignoring the alpha channel) then we have found our trim point.
trim_bottom = y
Break 2
EndIf
Next
Next
If ( trim_left < trim_right ) And ( trim_top < trim_bottom ) ; Double check that the image wasn't blank or that the scan didn't fail for some reason.
border_trim_image = GrabDrawingImage( #PB_Any, trim_left, trim_top, trim_right - trim_left + 1, trim_bottom - trim_top + 1 ) ; Grab the image with the border trimmed off it.
EndIf
EndIf
StopDrawing()
FreeImage( source_image ) ; We are finished with the source image either way, so get rid of it.
If border_trim_image = 0 : ProcedureReturn 0 : EndIf ; If the source image was blank or GrabDrawingImage failed then abort with a zero return value.
; --
; Get the dimensions of the border trim image.
width = ImageWidth( border_trim_image )
height = ImageHeight( border_trim_image )
size2 = size - 2 ; Get the size we need for the image resize. This needs to account for a one-pixel border around the outside. The border prevents artifacts when the sprite is transformed.
; Resize the image to fit within our target size. The aspect ratio is preserved.
If ( width = size2 ) And ( height = size2 ) ; Image is already the size we need, so do nothing here.
ElseIf width = height ; Image is square.
result = ResizeImage( border_trim_image, size2, size2 ) ; Resize the image uniformly.
ElseIf width > height ; Width is greater than height.
size2_float.d = size2 * ( height / width ) ; We need this expression to be a floating point one, so send the output to a float.
result = ResizeImage( border_trim_image, size2, size2_float.d ) ; Resize the image factoring in that height is narrower than width.
Else ; Height is greater than width.
size2_float.d = size2 * ( width / height ) ; We need this expression to be a floating point one, so send the output to a float.
result = ResizeImage( border_trim_image, size2_float.d, size2 ) ; Resize the image factoring in that width is narrower than height.
EndIf
If result = 0 : FreeImage( border_trim_image ) : ProcedureReturn 0 : EndIf ; If something went wrong with the resize then clean up and abort with a zero returned.
output_image = CreateImage( #PB_Any, size, size, 24 ) ; Create the output image. Since we will be using additive blending for our sprites, we don't need the alpha channel.
If output_image = 0 : FreeImage( border_trim_image ) : ProcedureReturn 0 : EndIf ; If something went wrong with the output image creation then clean up and abort with a zero returned.
; Draw the border trim image onto the output image with a one pixel border.
StartDrawing( ImageOutput( output_image ) )
DrawImage( ImageID( border_trim_image ), ( size - ImageWidth( border_trim_image ) ) / 2, ( size - ImageHeight( border_trim_image ) ) / 2 )
StopDrawing()
FreeImage( border_trim_image ) ; Clean up the border trim image.
ProcedureReturn output_image ; Returns the new sprite image.
EndProcedure
Procedure.i SaveSpriteImage( image, filepath.s )
; Save the specified sprite image to the specified filepath.
; Returns non-zero on success and a zero on failure.
ProcedureReturn SaveImage( image, filepath.s, #PB_ImagePlugin_PNG )
EndProcedure
; ; -- Test code - Use your own image filepaths --
; image = MakeSpriteImage( "C:\Users\axe73\Desktop\My Files\Business Projects\NFT Art\Glyph Maze 4x4\Glyph Maze 4x4 App\media\tracer-sprite-1.png" )
; If image : Debug "OK" : SaveSpriteImage( image, "C:\Users\axe73\Desktop\My Files\Business Projects\NFT Art\Glyph Maze 4x4\Glyph Maze 4x4 App\media\tracer-sprite-1-2.png" ) : EndIf