Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Recursively extracting sprites
#1
I was working on a way to extract individual sprites (or images) from a sprite sheet. Most sprite sheets found on the Internet are not neatly organized in same sized rectangular areas across the sheet.

At first I tried to design a line follower that would trace around sprites to find their area. That was like herding cats.

It then occurred to me that a flood fill like recursive routine may work. It does! The code below is a quick hack to show the concept in action. You'll need the image to see the code in action.

There's still some issues to work out but I thought someone might like to play with the code as is.

Code: (Select All)
' Parse a sprite sheet concept
'
' Issues to overcome:
' - Individual pixels are seen as separate sprites (the last 5 sprites in image)
'   Somehow the code needs to intelligently decide that these pixels belong to a sprite
'

TYPE XY
    x AS INTEGER
    y AS INTEGER
END TYPE

DIM Min AS XY '                    minimum x,y values seen
DIM Max AS XY '                    maximum x,y values seen
DIM Background AS _UNSIGNED LONG ' background color to use as border
DIM Pixel AS _UNSIGNED LONG '      pixel color
DIM SourceSheet AS LONG '          source image containing sprites
DIM TargetSheet AS LONG '          target image to write found sprites to
DIM x AS INTEGER '                 horizontal coordinate counter
DIM y AS INTEGER '                 vertical coordinate counter

SourceSheet = _LOADIMAGE("demon.png", 32) '                              load source sprite sheet
TargetSheet = _NEWIMAGE(_WIDTH(SourceSheet), _HEIGHT(SourceSheet), 32) ' create target sprite sheet
SCREEN _NEWIMAGE(781, 720, 32) '                                         create view screen
CLS
Background = _RGB32(255, 0, 255) '                                       background border color (bright magenta)
_SOURCE SourceSheet '                                                    get pixel data from source image

y = 0 '     reset vertical counter
DO
    x = 0 ' reset horizontal counter
    DO

        ' scan right until a pixel is found

        Pixel = POINT(x, y) '          get pixel color
        IF Pixel <> Background THEN '  is this pixel part of a sprite?

            ' A pixel has been found

            Min.x = x ' set starting point of min/max x,y values seen
            Max.x = x
            Min.y = y
            Max.y = y

            GrabSprite x, y, SourceSheet, TargetSheet, Background ' recursively get sprite

            ' Now the sprite has been written to the target image and the min/max x,y coordinates are known
            ' Grab the written sprite as you wish and then remove it from the target sheet

            ' This nethod would work just as well if for instance the mouse pointer was used to click
            ' anywhere inside of a sprite to extract it.

            ' Quick code to show the concept in action

            _DEST 0
            _PUTIMAGE (0, 0), SourceSheet
            _PUTIMAGE (0, 360), TargetSheet
            LOCATE 1, 1
            PRINT Max.x - Min.x, Max.y - Min.y ' current sprite dimensions
            _LIMIT 5 ' slow down to see progress
        END IF
        x = x + 1
    LOOP UNTIL x = _WIDTH(SourceSheet)
    y = y + 1
LOOP UNTIL y = _HEIGHT(SourceSheet)



SUB GrabSprite (x AS INTEGER, y AS INTEGER, s AS LONG, t AS LONG, Border AS _UNSIGNED LONG)

    ' Recursively grabs an image within the border color specified (proof of concept)
    ' (Based on flood fill)

    ' x,y - pixel coordinate
    ' s   - source image
    ' t   - target image
    ' b   - border (background) color

    SHARED Min AS XY
    SHARED Max AS XY
    DIM Pixel AS _UNSIGNED LONG

    IF x = -1 OR y = -1 OR x = _WIDTH(s) OR y = _HEIGHT(s) THEN EXIT SUB ' leave if x,y outside of source image
    _SOURCE s '                             get from source image
    Pixel = POINT(x, y) '                   get pixel color
    IF Pixel = Border THEN EXIT SUB '       leave if pixel is border color
    _DEST t '                               draw on target image
    PSET (x, y), Pixel '                    copy pixel to target image
    _DEST s '                               draw on source image
    PSET (x, y), Border '                   remove pixel from source image

    MinMax x, y, Min, Max '                 get x and y extremes seen

    GrabSprite x - 1, y, s, t, Border '     examine surrounding pixels
    GrabSprite x + 1, y, s, t, Border
    GrabSprite x, y - 1, s, t, Border
    GrabSprite x, y + 1, s, t, Border
    GrabSprite x - 1, y - 1, s, t, Border
    GrabSprite x - 1, y + 1, s, t, Border
    GrabSprite x + 1, y - 1, s, t, Border
    GrabSprite x + 1, y + 1, s, t, Border

END SUB


SUB MinMax (x AS INTEGER, y AS INTEGER, min AS XY, max AS XY)

    IF x < min.x THEN
        min.x = x
    ELSEIF x > max.x THEN
        max.x = x
    END IF
    IF y < min.y THEN
        min.y = y
    ELSEIF y > max.y THEN
        max.y = y
    END IF

END SUB


Attached Files Image(s)
   
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply


Messages In This Thread
Recursively extracting sprites - by TerryRitchie - 03-03-2024, 05:56 AM
RE: Recursively extracting sprites - by Pete - 03-03-2024, 07:45 AM
RE: Recursively extracting sprites - by GareBear - 03-03-2024, 03:21 PM
RE: Recursively extracting sprites - by Pete - 03-03-2024, 06:09 PM
RE: Recursively extracting sprites - by bplus - 03-03-2024, 07:43 PM
RE: Recursively extracting sprites - by Pete - 03-03-2024, 08:18 PM
RE: Recursively extracting sprites - by Pete - 03-03-2024, 10:03 PM
RE: Recursively extracting sprites - by bplus - 03-04-2024, 12:21 AM



Users browsing this thread: 2 Guest(s)