Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
pan around a large image for video creation
#1
i have written a program which could be used to "pan around" in a much-larger image.  it creates png file frames that could be rendered to video with "ffmpeg" or other video-creation program.

however, this is a bit complicated to explain.  first the source code.

Code: (Select All)
'by mnrvovrfc Dec-2024
OPTION _EXPLICIT

DIM AS LONG fo, thiscr, loadscr, x1, y1, x2, y2, g
DIM AS LONG ww, w, j, ll, wd, ht
DIM AS DOUBLE xx, yy, xd, yd
DIM afile$, bfile$, a$, e$, l$, fl AS _BYTE
DIM endl AS STRING * 1
endl = CHR$(10)

REDIM sf(1 TO 1) AS STRING

afile$ = "grantraveler.txt"
IF NOT _FILEEXISTS(afile$) THEN
    PRINT "Without this file, I cannot do anything."
    END
END IF
ll = 0
fo = FREEFILE
OPEN afile$ FOR INPUT AS fo
IF NOT EOF(fo) THEN LINE INPUT #fo, bfile$
IF NOT EOF(fo) THEN LINE INPUT #fo, l$
DO UNTIL EOF(fo)
    LINE INPUT #fo, a$
    IF a$ <> "" THEN
        ll = ll + 1
        REDIM _PRESERVE sf(1 TO ll) AS STRING
        sf(ll) = a$
    END IF
LOOP
CLOSE fo
IF bfile$ = "" THEN
    PRINT "Nothing to do!"
    END
END IF
IF LEFT$(UCASE$(bfile$), 6) = "$HOME/" THEN
$IF WIN THEN
    bfile$ = ENVIRON$("USERPROFILE") + "\" + MID$(bfile$, 7)
$ELSE
    bfile$ = ENVIRON$("HOME") + MID$(bfile$, 6)
$END IF
END IF
IF NOT _FILEEXISTS(bfile$) THEN
    PRINT "File NOT found: "; bfile$
    END
END IF
IF ll = 0 THEN
    PRINT "Do NOT use this program if you do NOT know what it does."
    END
END IF
IF l$ = "" THEN l$ = "unknown"
w = 1
e$ = sf(w)
wd = vselect2(e$, 1, fl)
IF fl THEN wd = 0
ht = vselect2(e$, 2, fl)
IF fl THEN ht = 0
IF wd = 0 OR ht = 0 THEN
    PRINT "Cannot go on with improper values for wanted width and height given."
    END
END IF
x1 = vselect2(e$, 3, fl)
IF fl THEN x1 = 0
y1 = vselect2(e$, 4, fl)
IF fl THEN y1 = 0
x2 = vselect2(e$, 5, fl)
IF fl THEN x2 = 0
y2 = vselect2(e$, 6, fl)
IF fl THEN y2 = 0
g = vselect2(e$, 7, fl)
IF fl THEN g = 0
IF g < 1 THEN
    PRINT "Number of frames must be greater than zero."
    END
END IF

loadscr = _LOADIMAGE(bfile$, 32)
IF loadscr >= -1 THEN
    PRINT "Could not load image: "; bfile$
    END
END IF
thiscr = _NEWIMAGE(wd, ht, 32)
SCREEN thiscr
ww = 0
DO UNTIL w > ll
    _TITLE "Grantraveler" + STR$(w) + "- " + l$
    xd = (x2 - x1) / g
    yd = (y2 - y1) / g
    xx = x1
    yy = y1
    FOR j = 1 TO g
        ww = ww + 1
        IF j = g - 1 THEN _TITLE "Grantraveler" + STR$(w) + " - COMPLETED"
$IF WIN THEN
        bfile$ = ENVIRON$("USERPROFILE") + "\Pictures\" + l$ + Zeroes$(ww, 4) + ".png"
$ELSE
        bfile$ = ENVIRON$("HOME") + "/Pictures/" + l$ + Zeroes$(ww, 4) + ".png"
$END IF
        _PUTIMAGE (0, 0), loadscr, thiscr, (FIX(xx), FIX(yy))-STEP(wd, ht)
        _DISPLAY
        _SAVEIMAGE bfile$, thiscr
        xx = xx + xd
        yy = yy + yd
        IF _KEYDOWN(27) THEN EXIT FOR
    NEXT
    IF _KEYDOWN(27) THEN EXIT DO
    DO
        w = w + 1
        IF w > ll THEN EXIT DO
        e$ = sf(w)
    LOOP UNTIL INSTR(e$, ";")
    IF w > ll THEN EXIT DO
    x1 = vselect2(e$, 1, fl)
    IF fl THEN x1 = 0
    y1 = vselect2(e$, 2, fl)
    IF fl THEN y1 = 0
    x2 = vselect2(e$, 3, fl)
    IF fl THEN x2 = 0
    y2 = vselect2(e$, 4, fl)
    IF fl THEN y2 = 0
    g = vselect2(e$, 5, fl)
    IF fl THEN g = 0
    IF g < 1 THEN
        PRINT "Number of frames must be greater than zero."
        END
    END IF
LOOP
_KEYCLEAR
_AUTODISPLAY
SYSTEM


FUNCTION Zeroes$ (num AS LONG, numdig AS INTEGER)
    DIM b$, v AS LONG
    DIM AS INTEGER sg, hx
    IF num < 0 THEN sg = -1: num = num * -1
    IF numdig < 0 THEN hx = 1: numdig = numdig * -1 ELSE hx = 0
    IF hx THEN
        b$ = HEX$(num)
    ELSE
        b$ = LTRIM$(STR$(num))
    END IF
    v = numdig - LEN(b$)
    IF v > 0 THEN b$ = STRING$(v, 48) + b$
    IF sg = -1 THEN b$ = "-" + b$
    Zeroes$ = b$
END FUNCTION


FUNCTION sselect$ (a$, n AS LONG)
    DIM sret AS STRING
    DIM AS LONG u, v, w
    v = 1
    u = INSTR(a$, ";")
    IF u > 0 THEN
        w = n
        DO
            IF v > LEN(a$) THEN
                sret = ""
                EXIT DO
            ELSEIF u > 0 THEN
                sret = MID$(a$, v, u - v)
                v = u + 1
            ELSE
                sret = MID$(a$, v)
                v = LEN(a$) + 1
            END IF
            u = INSTR(v, a$, ";")
            w = w - 1
        LOOP WHILE w > 0
    ELSE
        sret = a$
    END IF
    sselect$ = sret
END FUNCTION


FUNCTION vselect2&& (a$, n AS LONG, e AS _BYTE)
    STATIC s AS STRING
    e = 0
    s = sselect$(a$, n)
    IF s = "" THEN e = 1
    vselect2&& = VAL(s)
END FUNCTION

the user will have to create a "grantraveler.txt" text file in the same directory as the executable.  it has at least three lines.  the first line is the full path to the png file to scan.  the second line is the filename part, which is a prefix in which a 4-digit series number will be attached.  the third line is a list of integers separated by semicolons.  the values must be placed in a specific order:

width;height;begin-x;begin-y;finish-x;finish-y;number-of-frames

"width" and "height" are the size of the still-image renders, which should be much smaller than the image file whose name was given on the first line of the response file.  "begin" and "finish" are graphic coordinates in basic or in a program such as gimp that allows looking them up.  this is important: the coordinates are the center of the still-image.  the entire image has to be inside the bounds of the large image because i didn't put in a case to render jet-black pixels to represent those off the large image.

there could be more lines which are like the third, but "width" and "height" should be left out.  in other words, the list should have five integers for lines below the third line of the response file.  only the third line should have seven integers, including "width" and "height" first of all.  the "begin" coordinates could be the same as the "finish" ones of the previous line to begin a linear path from the previous point of panning.

the first field could support unix-style "$HOME/" including forward slash for a quick "macro" of the user's home directory.

i have provided an example "grantraveler.txt" for the user to study.

the program could take a while to create the still-images depending on how many frames it was asked to create.  there is no interpolation; the path is stiffly linear and simple.

if you have "ffmpeg" installed, open a terminal and change to the directory containing the still-images.  the following line could be used to create a video:

Code: (Select All)
ffmpeg -f image2 -framerate 24 -i perturbhead%04d.png -s 683x384 perturbhead.mp4
i used the filename of the provided png file but of course change it to your own.  note the video dimensions exactly match the "width" and "height" requested in the response file.

could render ogg theora instead but the visual quality is often poor.  too often one has to force bitrate to get better quality but it's unpredictable.  i don't create mp4 for myself.  the line below is an example for ogg theora:

Code: (Select All)
ffmpeg -f image2 -framerate 24 -i perturbhead%04d.png -b:v 4000k -maxrate 4000k -s 683x384 perturbhead.ogv
sometimes could leave out "-maxrate" switch, or the other indicator.  rendering with less frames per second doesn't help and it would offend people who expect smooth animations wherever they look.

i'm not familiar with video-creation software like kdenlive, but it should be a piece of cake importing the still-image png files into a project, to then export to video.

i haven't gone into windows in a long while.  therefore, the code above might have to be corrected.  the user is free to change the paths for his/her own purposes.

Show Content


.zip   mnrvovrfc-grantraveler.zip (Size: 7.38 MB / Downloads: 4)
Reply




Users browsing this thread: 1 Guest(s)