QB64 Phoenix Edition
Image fitment sub - Printable Version

+- QB64 Phoenix Edition (https://staging.qb64phoenix.com)
+-- Forum: QB64 Rising (https://staging.qb64phoenix.com/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://staging.qb64phoenix.com/forumdisplay.php?fid=3)
+---- Forum: Utilities (https://staging.qb64phoenix.com/forumdisplay.php?fid=8)
+---- Thread: Image fitment sub (/showthread.php?tid=468)



Image fitment sub - OldMoses - 05-22-2022

Here's a rehash of a little SUB I use when I have unpredictable sized, or aspect ratio'ed images to place in a predefined area. I call it Image_Resize. With the parameters, set a window area, identify source and destination, then set justifications (up, down, left, right, center). It does all the _PUTIMAGE figuring and then puts it, sized for best fit to the area.

A rehash because I originally posted it in the old forum, but I spruced up the example/demo code. Adding an image nesting and a swelling routine. The SUB itself has some of that cryptic looking branchless code, which was able to remove around 16 lines of SELECT CASE stuff, but I'm insufferably proud of that and haven't been able to break it yet. Blush 

While it doesn't do rotations, there's always Rotozoom'ing to a temporary handle for that and I saw no reason to try and reinvent that wheel.

Code: (Select All)
'Size and justify an image to fit in a predefined space using branchless equations. by OldMoses

_TITLE "Image Sizing demo #2"
SCREEN _NEWIMAGE(1024, 512, 32)
DO: LOOP UNTIL _SCREENEXISTS
_SCREENMOVE 5, 5

lim& = &H01011111 '                                             phantom line style
c~& = &H7FFFFFFF '                                              phantom line color
_PRINTMODE _KEEPBACKGROUND

'create test patterns, one wider & one taller (comment out if using your own images)
W& = _NEWIMAGE(750, 480, 32)
_DEST W&
COLOR , &HFFFF0000
CLS
FOR x = 100 TO 90 STEP -1
    CIRCLE (150, 240), x, &HFF0000FF
    CIRCLE (375, 240), x, &HFF0000FF
    CIRCLE (600, 240), x, &HFF0000FF
NEXT x

T& = _NEWIMAGE(480, 750, 32)
_DEST T&
COLOR , &HFF008000
CLS
FOR x = 1 TO 10
    LINE (100 + x, 100 + x)-(380 - x, 380 - x), &HFFFF0000, B
    LINE (100 + x, 470 + x)-(380 - x, 650 - x), &HFFFF0000, B
NEXT x
_PRINTSTRING (120, 120), "||||||||"
_PRINTSTRING (120, 490), "________"

'Or load images of your choosing in lieu of test patterns, and comment out the above patterns
'W& = _LOADIMAGE("", 32)
'T& = _LOADIMAGE("", 32)

_DEST 0

CLS
x% = 400: y% = 20: x1% = 650: y1% = 300 '                       use predetermined part of the screen (400, 20)-(650, 300)
LINE (x%, y%)-(x1%, y1%), c~&, B , lim& '                       show target area
Image_Resize x%, y%, x1%, y1%, W&, 0, "c", "u" '                justify up, wide image
_PRINTSTRING (0, 512 - 32), "area=(400, 20)-(650, 300) wide image, top justified (any key to continue)"
_PRINTSTRING (0, 512 - 16), "Syntax: Image_Resize 400, 20, 650, 300, W&, 0, " + CHR$(34) + "c" + CHR$(34) + ", " + CHR$(34) + "u" + CHR$(34)
SLEEP

CLS
LINE (x%, y%)-(x1%, y1%), c~&, B , lim& '                       show target area
Image_Resize x%, y%, x1%, y1%, T&, 0, "r", "c" '                justify right, tall image
_PRINTSTRING (0, 512 - 32), "area=(400, 20)-(650, 300) tall image, right justified (any key to continue)"
_PRINTSTRING (0, 512 - 16), "Syntax: Image_Resize 400, 20, 650, 300, T&, 0, " + CHR$(34) + "r" + CHR$(34) + ", " + CHR$(34) + "c" + CHR$(34)
SLEEP

CLS
x% = 0: y% = 0: x1% = _WIDTH - 1: y1% = _HEIGHT - 1 '           use full screen
Image_Resize x%, y%, x1%, y1%, W&, 0, "c", "u" '                justify up, wide image
_PRINTSTRING (0, 512 - 32), "area=full screen, wide image, top justified (any key to continue)"
_PRINTSTRING (0, 512 - 16), "Syntax: Image_Resize 0, 0, _WIDTH - 1, _HEIGHT - 1, W&, 0, " + CHR$(34) + "c" + CHR$(34) + ", " + CHR$(34) + "u" + CHR$(34)
SLEEP

CLS
Image_Resize x%, y%, x1%, y1%, T&, 0, "l", "c" '                justify left, tall image
_PRINTSTRING (400, 512 - 32), "area=full screen, tall image, left justified (any key to continue)"
_PRINTSTRING (400, 512 - 16), "Syntax: Image_Resize 0, 0, _WIDTH - 1, _HEIGHT - 1, T&, 0, " + CHR$(34) + "l" + CHR$(34) + ", " + CHR$(34) + "c" + CHR$(34)
SLEEP

CLS
Image_Resize x%, y%, x1%, y1%, W&, 0, "c", "d" '                justify down, wide image
_PRINTSTRING (0, 512 - 32), "area=full screen, wide image, bottom justified (any key to continue)"
_PRINTSTRING (0, 512 - 16), "Syntax: Image_Resize 0, 0, _WIDTH - 1, _HEIGHT - 1, W&, 0, " + CHR$(34) + "c" + CHR$(34) + ", " + CHR$(34) + "d" + CHR$(34)
SLEEP

CLS
x% = 25: y% = 450: x1% = 250: y1% = 512 '                       use predetermined part of the screen (25, 450)-(250, 580)
LINE (x%, y%)-(x1%, y1%), c~&, B , lim& '                       show target area
Image_Resize x%, y%, x1%, y1%, W&, 0, "c", "c" '                justify center, wide image
_PRINTSTRING (0, 0), "area=(25, 450)-(250, 512) wide image, center justified (any key to continue)"
_PRINTSTRING (0, 16), "Syntax: Image_Resize 25, 450, 250, 512, W&, 0, " + CHR$(34) + "c" + CHR$(34) + ", " + CHR$(34) + "c" + CHR$(34)
SLEEP

CLS
LINE (x%, y%)-(x1%, y1%), c~&, B , lim& '                       show target area
Image_Resize x%, y%, x1%, y1%, T&, 0, "c", "c" '                justify center, tall image
_PRINTSTRING (0, 0), "area=(25, 450)-(250, 512) tall image, center justified (any key to continue)"
_PRINTSTRING (0, 16), "Syntax: Image_Resize 25, 450, 250, 512, T&, 0, " + CHR$(34) + "c" + CHR$(34) + ", " + CHR$(34) + "c" + CHR$(34)
SLEEP

'nesting sub images in others
CLS
tmp& = _COPYIMAGE(T&)
_DEST tmp&
LINE (_SHR(_WIDTH(tmp&), 1), 0)-(_WIDTH(tmp&) - 1, _SHR(_HEIGHT(tmp&), 1)), c~&, B , lim&
Image_Resize _SHR(_WIDTH(tmp&), 1), 0, _WIDTH(tmp&) - 1, _SHR(_HEIGHT(tmp&), 1), W&, tmp&, "c", "c"
_DEST 0
Image_Resize 0, 0, 1024, 512, tmp&, 0, "r", "c"
_FREEIMAGE tmp&
_PRINTSTRING (0, 0), "area=full screen, wide image IN tall image, right justified (any key to continue)"
_PRINTSTRING (0, 16), "Example code:"
_PRINTSTRING (0, 32), "tmp& = _COPYIMAGE(T&)"
_PRINTSTRING (0, 48), "_DEST tmp&"
_PRINTSTRING (0, 64), "Image_Resize _SHR(_WIDTH(tmp&), 1), 0, _WIDTH(tmp&) - 1, _SHR(_HEIGHT(tmp&), 1), W&, tmp&, " + CHR$(34) + "c" + CHR$(34) + ", " + CHR$(34) + "c" + CHR$(34)
_PRINTSTRING (0, 80), "_DEST 0"
_PRINTSTRING (0, 96), "Image_Resize 0, 0, 1024, 512, tmp&, 0, " + CHR$(34) + "r" + CHR$(34) + ", " + CHR$(34) + "c" + CHR$(34)
_PRINTSTRING (0, 112), "_FREEIMAGE tmp&"
SLEEP

'expanding and moving an image around the screen
FOR swell% = 0 TO 256
    CLS
    Image_Resize swell%, swell%, swell% * 2, swell% * 2, W&, 0, "c", "u"
    _LIMIT 100
    _DISPLAY
NEXT swell%
_PRINTSTRING (0, 0), "Example code:"
_PRINTSTRING (0, 16), "FOR swell% = 0 TO 256"
_PRINTSTRING (0, 32), "    CLS"
_PRINTSTRING (0, 48), "    Image_Resize swell%, swell%, swell% * 2, swell% * 2, W&, 0, " + CHR$(34) + "c" + CHR$(34) + ", " + CHR$(34) + "u" + CHR$(34)
_PRINTSTRING (0, 64), "    _LIMIT 100"
_PRINTSTRING (0, 80), "    _DISPLAY"
_PRINTSTRING (0, 96), "NEXT swell%"

'and you get the idea...

END

SUB Image_Resize (xpos AS INTEGER, ypos AS INTEGER, xlim AS INTEGER, ylim AS INTEGER, i AS LONG, d AS LONG, xj AS STRING, yj AS STRING)

    'Syntax: upper left x, upper left y, lower right x, lower right y, image handle, destination handle, horizontal justification, vertical justification
    'horizontal justifications= "l" left, "c" center, "r" right
    'vertical justifications= "u" up, "c" center, "d" down
    DIM AS INTEGER xs, ys, xp, yp, xl, yl
    DIM AS SINGLE rt, xrt, yrt
    xrt = (xlim - xpos) / _WIDTH(i) '                           width of area divided by width of image
    yrt = (ylim - ypos) / _HEIGHT(i) '                          height of area divided by height of image
    rt = -xrt * (xrt < yrt) - yrt * (yrt <= xrt) '              pick the smaller of the two ratios to fit area
    xs = _WIDTH(i) * rt '                                       final image size ratio in x
    ys = _HEIGHT(i) * rt '                                      final image size ratio in y

    xp = -xpos * (xj = "l") - (_SHR(xlim - xpos, 1) + xpos - _SHR(xs, 1)) * (xj = "c") - (xlim - xs) * (xj = "r")
    xl = xp + xs
    yp = -ypos * (yj = "u") - (_SHR(ylim - ypos, 1) + ypos - _SHR(ys, 1)) * (yj = "c") - (ylim - ys) * (yj = "d")
    yl = yp + ys
    _PUTIMAGE (xp, yp)-(xl, yl), i, d

END SUB 'Image_Resize