Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
TextToImage and DisplayImage
#1
Code: (Select All)
SCREEN _NEWIMAGE(800, 700, 32)
_SCREENMOVE 250, 0
FOR i = 1 TO 4
    HW(i) = TextToImage("Hello World", 16, &HFFFFFF00, 0, i)
NEXT


CLS
PRINT "The first thing to showcase with these two routines is just how simple it is to turn"
PRINT "text into an image with TextToImage."
SLEEP
PRINT
PRINT "First, let's print it forwards:"
_PUTIMAGE (250, 48), HW(1)
SLEEP
PRINT
PRINT "Then, let's print it backwards:"
_PUTIMAGE (250, 80), HW(2)
SLEEP
PRINT
PRINT "Then, let's print it up to down:"
_PUTIMAGE (270, 112), HW(3)
SLEEP
LOCATE 8, 40: PRINT "And let's finish with down to up:"
_PUTIMAGE (580, 112), HW(4)
SLEEP
LOCATE 20, 1
PRINT
PRINT
PRINT "TextToImage simply transforms text into an image for us, with a few built in options"
PRINT "to it for the direction we want we text to print."
PRINT "It's as simple as a call with:"
PRINT "    Handle = TextToImage(text$, fonthandle, fontcolor, backgroundcolor, mode"
PRINT
PRINT "        text$ is the string which we want to print.  (In this case 'Hello World'"
PRINT "        fonthandle is the handle of the font which we _LOADFONT for use."
PRINT "            (In this case, I choose the default _FONT 16.)"
PRINT "        fontcolor is the color which we want our text in.  (Here, it's YELLOW.)"
PRINT "        backgroundcolor is the background which we want for the text time.  (Clear this time.)"
PRINT "        mode is how we decide to print forwards, backwards, up to down, or down to up."
PRINT
PRINT "Once we have an image handle, we can use that image just the same as we can with any other."
PRINT "For those who don't need to do anything more than display the text as an image,"
PRINT "feel free to use it as I have in the first part of this program with _PUTIMAGE."
PRINT
PRINT "Trust me -- TextToImage works just fine with _PUTIMAGE."
PRINT
PRINT "But....   If you need more..."
SLEEP

CLS , 0

PRINT "There's always DisplayImage to help you out!"
DisplayImage HW(1), 300, 30, 1, 1, 0, 1
PRINT
PRINT "Display your image at a scale!"
SLEEP
PRINT
PRINT "Twice as wide! ";
DisplayImage HW(1), 300, 60, 2, 1, 0, 1
SLEEP
PRINT "Twice as tall! "
DisplayImage HW(1), 500, 60, 1, 2, 0, 1
SLEEP
PRINT
PRINT "At an angle!"
DisplayImage HW(1), 280, 90, 1, 1, -45, 1
SLEEP
PRINT: PRINT: PRINT: PRINT: PRINT
PRINT "Make it rotate!"
_DELAY .2
_KEYCLEAR
DO
    LINE (355, 155)-STEP(100, 100), &HFF000000, BF
    DisplayImage HW(1), 400, 200, 1, 1, angle, 0

    angle = (angle + 1) MOD 360
    _LIMIT 30
    _DISPLAY
LOOP UNTIL _KEYHIT
_AUTODISPLAY
PRINT
PRINT
PRINT
PRINT
PRINT "You can basically use DisplayImage just as you'd normally use RotoZoom, EXCEPT..."
SLEEP
PRINT "You can choose which CORNER of the image you want to display at your coordinates."
PRINT
LINE (350, 350)-STEP(100, 100), -1, B
CIRCLE (400, 400), 10, -1
SLEEP
PRINT "Top Left corner! ";
DisplayImage HW(1), 400, 400, 2, 2, 0, 1
SLEEP
PRINT "Bottom Left corner! ";
DisplayImage HW(1), 400, 400, 2, 2, 0, 2
SLEEP
PRINT "Top Right corner! ";
DisplayImage HW(1), 400, 400, 2, 2, 0, 3
SLEEP
PRINT "Bottom Right corner! "
DisplayImage HW(1), 400, 400, 2, 2, 0, 4
SLEEP
_FREEIMAGE HW(1)
HW(1) = TextToImage("Hello World", 16, &HFFFF0000, &HFF0000FF, 1)
PRINT "Or Centered!"
DisplayImage HW(1), 400, 400, 2, 2, 0, 0
CIRCLE (400, 400), 10, -1
SLEEP

CLS

PRINT "With TextToImage, you can turn text into an image...  It's that simple!"
PRINT
PRINT "With DisplayImage, you have a ton of options for how to display ANY image"
PRINT "   (NOT just for use with text images!!)"
PRINT
PRINT "Scale them, stretch them, rotate them, position them by various corners..."
PRINT
PRINT "Between these two routines, I generally don't need anything else when working"
PRINT "   with images in my programs.  ;)"
PRINT
PRINT
PRINT "And that's THE END of this demo.  Post any questions you have on the forums for me!"





' (Image As Long, x As Integer, y As Integer, xscale As Single, yscale As Single,
'  angle As Single, mode As _Byte)




FUNCTION TextToImage& (text$, font&, fc&, bfc&, mode AS _BYTE)
    'text$ is the text that we wish to transform into an image.
    'font& is the handle of the font we want to use.
    'fc& is the color of the font we want to use.
    'bfc& is the background color of the font.

    'Mode 1 is print forwards
    'Mode 2 is print backwards
    'Mode 3 is print from top to bottom
    'Mode 4 is print from bottom up
    'Mode 0 got lost somewhere, but it's OK.  We check to see if our mode is < 1 or > 4 and compensate automatically if it is to make it one (default).

    IF mode < 1 OR mode > 4 THEN mode = 1
    dc& = _DEFAULTCOLOR: bgc& = _BACKGROUNDCOLOR
    D = _DEST
    F = _FONT
    T2Idown = CSRLIN: T2Iright = POS(0)
    IF font& <> 0 THEN _FONT font&
    IF mode < 3 THEN
        'print the text lengthwise
        w& = _PRINTWIDTH(text$): h& = _FONTHEIGHT
    ELSE
        'print the text vertically
        FOR i = 1 TO LEN(text$)
            IF w& < _PRINTWIDTH(MID$(text$, i, 1)) THEN w& = _PRINTWIDTH(MID$(text$, i, 1))
        NEXT
        h& = _FONTHEIGHT * (LEN(text$))
    END IF

    TextToImage_temp& = _NEWIMAGE(w&, h&, 32)
    TextToImage = TextToImage_temp&
    _DEST TextToImage_temp&
    IF font& <> 0 THEN _FONT font&
    COLOR fc&, bfc&

    SELECT CASE mode
        CASE 1
            'Print text forward
            _PRINTSTRING (0, 0), text$
        CASE 2
            'Print text backwards
            temp$ = ""
            FOR i = 0 TO LEN(text$) - 1
                temp$ = temp$ + MID$(text$, LEN(text$) - i, 1)
            NEXT
            _PRINTSTRING (0, 0), temp$
        CASE 3
            'Print text upwards
            'first lets reverse the text, so it's easy to place
            temp$ = ""
            FOR i = 0 TO LEN(text$) - 1
                temp$ = temp$ + MID$(text$, LEN(text$) - i, 1)
            NEXT
            'then put it where it belongs
            FOR i = 1 TO LEN(text$)
                fx = (w& - _PRINTWIDTH(MID$(temp$, i, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
                _PRINTSTRING (fx, _FONTHEIGHT * (i - 1)), MID$(temp$, i, 1)
            NEXT
        CASE 4
            'Print text downwards
            FOR i = 1 TO LEN(text$)
                fx = (w& - _PRINTWIDTH(MID$(text$, i, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
                _PRINTSTRING (fx, _FONTHEIGHT * (i - 1)), MID$(text$, i, 1)
            NEXT
    END SELECT
    _DEST D
    COLOR dc&, bgc&
    _FONT F
    LOCATE T2Idown, T2Iright
END FUNCTION

SUB DisplayImage (Image AS LONG, x AS INTEGER, y AS INTEGER, xscale AS SINGLE, yscale AS SINGLE, angle AS SINGLE, mode AS _BYTE)
    'Image is the image handle which we use to reference our image.
    'x,y is the X/Y coordinates where we want the image to be at on the screen.
    'angle is the angle which we wish to rotate the image.
    'mode determines HOW we place the image at point X,Y.
    'Mode 0 we center the image at point X,Y
    'Mode 1 we place the Top Left corner of oour image at point X,Y
    'Mode 2 is Bottom Left
    'Mode 3 is Top Right
    'Mode 4 is Bottom Right

    DIM AS INTEGER px(3), py(3), w, h, w1, h1
    DIM sinr AS SINGLE, cosr AS SINGLE, i AS _BYTE
    w = _WIDTH(Image): h = _HEIGHT(Image)
    w1 = w * xscale: h1 = h * yscale
    SELECT CASE mode
        CASE 0 'center
            px(0) = -w1 / 2: py(0) = -h1 / 2: px(3) = w1 / 2: py(3) = -h1 / 2
            px(1) = -w1 / 2: py(1) = h1 / 2: px(2) = w1 / 2: py(2) = h1 / 2
        CASE 1 'top left
            px(0) = 0: py(0) = 0: px(3) = w1: py(3) = 0
            px(1) = 0: py(1) = h1: px(2) = w1: py(2) = h1
        CASE 2 'bottom left
            px(0) = 0: py(0) = -h1: px(3) = w1: py(3) = -h1
            px(1) = 0: py(1) = 0: px(2) = w1: py(2) = 0
        CASE 3 'top right
            px(0) = -w1: py(0) = 0: px(3) = 0: py(3) = 0
            px(1) = -w1: py(1) = h1: px(2) = 0: py(2) = h1
        CASE 4 'bottom right
            px(0) = -w1: py(0) = -h1: px(3) = 0: py(3) = -h1
            px(1) = -w1: py(1) = 0: px(2) = 0: py(2) = 0
    END SELECT
    sinr = SIN(angle / 57.2957795131): cosr = COS(angle / 57.2957795131)
    FOR i = 0 TO 3
        x2 = (px(i) * cosr + sinr * py(i)) + x: y2 = (py(i) * cosr - px(i) * sinr) + y
        px(i) = x2: py(i) = y2
    NEXT
    _MAPTRIANGLE (0, 0)-(0, h - 1)-(w - 1, h - 1), Image TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
    _MAPTRIANGLE (0, 0)-(w - 1, 0)-(w - 1, h - 1), Image TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
END SUB
Reply
#2
Wow, Steve that really blew my mind!
I never realized such things could be done, without actually creating a graphic image of the text manually!
Reply
#3
Those are my two "go to" little text routines, for 90% of the stuff I do a lot of the time. Unless I need fancy flourishes, or distinct fonts, I find it just as simple to toss text into the TextToImage routine, then scale/rotate it as wanted via DisplayImage, and be done with it. It saves having to include resource files and such so I can specify font size with _LOADFONT, and lets me keep the program all together in one little BAS file.

I'm glad you enjoyed the little demo! Feel free to make use of either of the routines anytime you might wish -- they're completely free for public usage. Wink
Reply
#4
Updated to fix scaling issue.
Reply
#5
This is very cool! Nice work and thanks for sharing. ??
Reply
#6
Hi Steve - love this lesson, thank you for same. When I run the program I think I'm getting different result to your description of the "corners" where Hello World is printing. Where your direction is saying the phrase is printing at the Top Left, I'm getting that printing at the Bottom R. All of them seem to be at a different corner:

Expected Display           Actual Display
 Top Left                         Bottom Right
 Bottom Left                   Top Right
 Top Right                       Bottom Left
 Bottom Right                  Top Left
 

Not sure if it's something to do with what I have done at my end running this program but thought I'd bring it to you attention in case we see it again in the BIBLE
Reply
#7
It's printing as it should be.   Let's choose a point (100, 100).  Now, if we print with the Top Left position of the text at that point, the text is going to go as you describe -- down and to the right.  To visualize this easily, take an index card or piece of paper and place the Top Left corner of that page in the center of your table or laptop lid...  Where is that piece of paper in relation to that center point?  To the Bottom and Right of it.  

The point you designate is the starting point of where the corner goes, not the finish point.  Wink
Reply
#8
hey Steve, I know this is going to be a new command in the next release, but are you SaveImage routines somewhere on this forum?  I just found a need for them to generate an animated gif
Reply
#9
I never fixed them to do animated GIF files; just static BASIC ones, which covered most folks needs.

https://qb64phoenix.com/forum/showthread.php?tid=20 <-- Here they are though, if you still need them.
Reply
#10
Thanks Steve, that was quick.  In regards to GIFs, you don't really need special QB64 routines to make them, you can install ImageMagick, take a screenshot (saveimage) of every frame in your program, then SHELL to imagemagick to splice them all together into an animation that you can share around
Reply




Users browsing this thread: 2 Guest(s)