putimage()
#1
Hey Walter,

Have you had anyone reporting a potential problem with '_putimage()'?

I am suspecting that it's 'putimage'... but I could be wrong...

Reason I haven't made mention before, because most of the examples that most users share, are created using primitive graphics commands. I tried using png files yesterday (20 Sept) and figured I must have either typed an incorrect handle or file name...

I am trying to use png sprites but always get an 'in valid handle' error. I even cut-n-paste the command directly from the 'help' and it still fails. I've tried many types of files; Used variations of upper/lower case filenames. I even used the same sprites in other editors and they all display just fine.

I suspect the issue may not be the filename or file type, but an issue with a combination of putimage and Linux (or Linux and 64bit)

Just curious.

J
May your journey be free of incident.

Live long and prosper.
Reply
#2
@johnno56

I have not heard of anyone having issues with the _PUTIMAGE statement.

Many of my demos on this forum uses the _PUTIMAGE statement, and they run fine for me. I also use *.PNG images most of the time, which I prefer most of the time, especially when transparency is involved.

Here are some demos that use these two features:

Bad TV Reception with Rolling:
http://www.thejoyfulprogrammer.com/qb64/...hp?tid=967

Spinning RGB Sub-Pixel Color Wheel:
http://www.thejoyfulprogrammer.com/qb64/...hp?tid=520

Background Shifting in a Circle Motion:
http://www.thejoyfulprogrammer.com/qb64/...php?tid=15



If you haven't figured out the issue, and you would like some help without having to post it on the forum, please feel free to PM it to me.
Dedicated to empowering computer programming hobbyists, tinkerers, amateurs, and enthusiasts.
profile for Walter Whitman at Stack Overflow, Q&A for professional and enthusiast programmers


Reply
#3
The 'shifting background' ran without issue.

The 'TV Reception' returned 'unhandled error #258' in line 117.

The 'Colour Wheel' returned 'unhandled error #258' in line 138

My conclusion: All 3 used _putimage() but the only one that worked was the one that did not use png's. So therefore: _putimage() seems to work but not when using files. (on Linux - I cannot test for windows)

J
May your journey be free of incident.

Live long and prosper.
Reply
#4
_PUTIMAGE doesn't care about file types at all.  BMP, PNG, GIF -- it doesn't know or track any of that information for us.  All _PUTIMAGE does is copy information from one image and puts it somewhere else.  

_LOADIMAGE may be failing for you, for some odd reason, which is what the "invalid handle" message is telling you, but it's not an issue with _PUTIMAGE itself.

For a very simple test, try the following:

image& = _LOADIMAGE("yourimage.PNG",32)
_DELAY .2 'Allow initial screen time to display
SCREEN image& 'swap over to the image screen -- if it loaded at all into memory!

If your image fails to swap over to the visible screen, the issue is in the _LOADIMAGE routine and not the _PUTIMAGE command.

Several things can make _LOADIMAGE fail to work properly with PNG files...

First issue I can think of off the top of my head is a glitch in the CRC check routine which plagued some of the older versions of QB64-GL.  Grab the latest version from the repo, extract and install it, and see if that corrects the issue.  I remember pushing a fix which cleared up that issue for us, but I can't tell you exactly when that was now.  If the version of QB64 you are using is older than that patch, it's probably the reason why the PNG files are failing to work properly for you.

Second issue may be screen mode or image color format.  _LOADIMAGE doesn't work AT ALL with 256 color images, currently.  I keep meaning to go in and work on that for us, but there's always so much other stuff to do in life that I just haven't gotten around to it, and apparently neither has any of the other people who help develop the language.  _LOADIMAGE, as it exists currently, automatically changes all images to 32-bit files, which makes them fail to work properly in 256 color screens.  The only fix currently is to swap your program over to 32-bit images or else to decode the PNG format and import it yourself manually.  

If the problem isn't one of those two issues, I'll be rather surprised.  _PUTIMAGE has been tested extensively on Linux, Windows, and Mac and hasn't had any issues since I went in and patched the STEP routines for it several months back.  (They weren't working either, so a command like _PUTIMAGE (x,y)-STEP(100,100) would always fail -- but that's also been patched and corrected in the newest versions of QB64.)

Try a fresh download from the repository and see if the issue still persists for you and let us know how things turn out. I hope that's all it'll take to correct the issue for you, and if not, I'll take time and dig back into the internals once again and make certain that one of the latest patches hasn't broken something unintentionally.  We're careful to test changes before we push things live into the repo, but glitches happen sometimes and I'll be the first to admit to that.  (Heck, I even broke the whole QB64 dirty build system itself for a few weeks last year when I swapped out the config file system for us, so I definitely know we're not beyond the point of breaking one thing while working on another...)

===========================
EDIT:  Just caught up to my emails and push notifications... Felippe pushed a patch into the repo yesterday which should allow us to start using _LOADIMAGE with 256 color images once again.  Just another reason to grab a copy of the latest build and test it out -- it should correct both issues (the CRC/Addler check issue for PNG files and now also the 256 color image issue) and might very well take care of whatever glitch you're experiencing.  If not, let us know and we'll do some further testing and see what the problem might be on Linux systems with regards to PNG format files. Wink
Reply
#5
Ran the test program and it failed with an 'invalid handle'. I do not use 256 sprites, only 32bit.

The qb64 version I am using is not current. I don't know it's version number but I installed it in April of this year. I have downloaded the current version and the latest repository version. Neither will install. Error message "bash: ./setup_lnx.sh: /bin/bash^M: bad interpreter: No such file or directory" Neither installation attempt were as 'root'. As the 'setup' does not require a parameter, I would have to assume, that the script is trying to access/download information that does not exist. I am sorry for 'opening this can of worms'. Something told me I should have stayed in bed this morning... lol (just out of curiosity, I'll try to run the Windows version via Wine - if qb64 runs then it should tell me if it is a qb64 problem or a Linux problem... maybe...)

J

ps: Just downloaded and ran the Windows version and it too returned the same error when running the same test program. 'Invalid handle'. Just to add further confusion, I just ran the open_gl sample - it too uses loadimage and putimage, and it ran flawlessly (Windows version) as did also the "April" Linux version - I'm so confused - my brain hurts.
May your journey be free of incident.

Live long and prosper.
Reply
#6
If you downloaded from Galleon's site, the Linux line endings are messed up.  We've reported the issue to him several times already, but he still hasn't gotten around to fixing it.  All you should need to do to fix the issue is to run the following command from the same folder with the qb64 install scripts:

Code:
find . -name '*.sh' -exec sed -i "s/\r//g" {} \;

After that, the setup should work as intended for you with:

Code:
./setup_lnx.sh

A few quick questions with the issue you're seeing:  Are you certain the image files are in the correct directory?  And do you have read/write access to that directory?

Most of the time, programs are written so that they're in the same directory that QB64.exe is in, and archives like Walt's image rolling demo which extract to their own subfolder won't work until you either change the paths or move the files to the proper folder.  This might also be the source of your issues, so double check to make certain that everything is where it's supposed to be.  From what you say, it sounds as if it's really a case of the file not being found and loading at all, instead of an issue with _PUTIMAGE.  Give me a little time and I'll work up a nice test program for you and we might be able to narrow down what the root problem is a bit better.  Smile
Reply
#7
In regards to installation: The command worked like a treat and the "setup" ran and installed qb64 as designed. Many thanks for that... Much appreciated.

Directories: I have tried running the test program with the sprites in the same directory as the ".bas" file and also using the proper 'path' as well. I am fairly certain that the folder and files concerned have the appropriate permissions. The permissions are ok. I then deliberately modified the folder and files to "create, delete and access" (folder and files) for all users and re-ran the test with the same results as before... *sigh*

It still puzzles me that a simple test program will not work but the qb64 sample program does. Both contain the same commands. The only difference that I did notice is that the sample program used a "jpg" image. I will modify the test program to incorporate a jpg instead of a png... fingers crossed... Nope. jpg didn't work either... my brain hurts again... low caffeine levels!!!

J
May your journey be free of incident.

Live long and prosper.
Reply
#8
Walking Man demo with one of Johnno's sdlbas code translations:

"walking720x146.png"


Code:
_TITLE "Walking Man trans by bplus started 2018-06-30"
'QB64 version 2017 1106/82 (the day before they switched to version 1.2)
CONST xmax = 800
CONST ymax = 600
SCREEN _NEWIMAGE(xmax, ymax, 32)
_SCREENMOVE 360, 60

walk& = _LOADIMAGE("walking720x146.png") ' 8 positions at 90 x 146   walk& is same as slot number
manW = 90 'width of man image
manH = 146 'height of man image
manN = 0 'man number 0 to 7 as walks ie, manN = (manN + 1) mod 8
manY = (ymax - manH) \ 2 'place top man image at manY always as walks across the screen
manX = -manW 'start off screen by 1 manW  manX is x location on screen of man

WHILE 0 = 0
   CLS
   ' blt(1, x*90, 0, 90, 146, movex, 45)
   '
   '   blt(sprite number,starting x position, starting y position, image width, image height, destination x, and y)
   '
   '   (I prefer a strip of characters. Others may use a 'grid' of characters.)
   '
   '   Sprite #1 is the 'walking' strip of characters
   '
   '   when x = 0 it will grab the first image locate at x*90 with a width of 90px and a height of 146px
   '   and display it at 'movex'x and 45y. Perform a short delay; increment to the next image; If the
   '   image grabbed is greater than 7 (the last image) then reset the image count to 0 (first image).
   '   move the curent image 5 pixels to the right. If the image moves off screen, make it reappear on
   '   the other side. Continue doing this until the escape key is pressed.


   '' _PUTIMAGE [STEP] [(dx1, dy1)-[STEP][(dx2, dy2)]][, sourceHandle&][, destHandle&][, ][STEP][(sx1, sy1)[-STEP][(sx2, sy2)]][_SMOOTH]

   'THE SKINNY: (notice the unintuitive positions of source handle and destination handle)
   'destination coordinates:  (x, y)-(x2, y2)  <<<< syntax
   'then source (image) handle (walk),
   'then destination handle = 0 for screening, then coordinates of image in
   'finally source coordinates off image of image handle:  (x, y)-(x2, y2)  <<<< syntax

   _PUTIMAGE (manX, manY)-STEP(manW, manH), walk&, 0, (manN * 90, 0)-STEP(manW, manH)
   manN = (manN + 1) MOD 8 'increase image index until hit 7 then back to 0
   manX = manX + 10
   IF manX >= xmax THEN manX = -manW 'move man back to left side of screen when hit right side
   _DISPLAY 'like   waitvbl(100) in sdlbas
   _LIMIT 10 'like wait(100) this limits displays to 10 per second
WEND




I just noticed the title of this thread is misleading; the () after _PUTIMAGE implies that _PUTIMAGE is a function, it is NOT.

QB64 requires (x, y) - [STEP](x2, y2) syntax for all graphic coordinate locating, don't mistake that "(" for the coordinate as a "(" for a function.

_PUTIMAGE is made overly complicated when showing all the acceptable forms it can be called

Basically there are 4 main components:
1) the destination coordinates for the _PUT using [step] (x, y)-[Step](x2, y2) syntax
2) the handle of the source
3) the handle of the destination handle, the screen is 0
4) the source coordinates using [step] (x, y)-[Step](x2, y2) syntax

The full designation for the coordinates can be abbreviated or skipped depending if you want to fill the whole destination with the whole source or just parts of one or the other.


Since we know the image height and width inside the sheet of many images we can use the STEP option with the [step] (x, y)-[Step](x2, y2) syntax, in the example above, we STEP(imageW, imageH).

Reminder:  STEP(x, y)  just moves x, y amounts relative to the last x, y position used in a graphics command.
eg to make a rectangle with width of 100 and height of 50 at point x, y
you can
LINE (x, y) - (x + 100, y + 50), , B
or you can
LINE (x, y) - STEP(100, 50),  , B
B += x
Reply
#9
More fun with a font sheet:

Remember Cybermonkey's font .bmp
.bmp   Cyber font.bmp (Size: 191.3 KB / Downloads: 41)

Here is some font printing with it:
Code:
_TITLE "Cyber font test.bas by bplus started 2018-06-30"
'from Rotate Image.bas started bplus 2018-06-17
'QB64 version 2017 1106/82 (the day before they switched to version 1.2)
CONST xmax = 800
CONST ymax = 600
DIM SHARED pi
pi = _PI

SCREEN _NEWIMAGE(xmax, ymax, 32)
_SCREENMOVE 360, 60
backImage& = _LOADIMAGE("Stars.png")
DIM SHARED cf&, cfW, cfH
cf& = _LOADIMAGE("Cyber font.bmp")
cfW = 40
cfH = 34

_PUTIMAGE , backImage&, 0
bx = 100: by = 100: bw = 600: bh = 25
M$ = "bplus was here! June 30, 2018"
LINE (bx, by)-STEP(bw, bh), _RGB32(128, 0, 0), BF
cfMessage M$, bx, by, bw, bh
M$ = "bplus gives this demo a B?"
bx = 50: by = 300: bw = 700: bh = 100
LINE (bx, by)-STEP(bw, bh), _RGB32(128, 255, 255), BF
cfMessage M$, bx, by, bw, bh


SUB cfMessage (message$, xBox, yBox, wBox, hBox)
   lm = LEN(message$)
   bm = .125 * hBox
   px = lm * (cfW + bm) + 2 * bm
   py = cfH + 2 * bm
   xScale = wBox / px
   yScale = hBox / py
   FOR i = 1 TO LEN(message$)
       c$ = MID$(message$, i, 1)
       cfLetter c$, xBox + (i - 1) * (cfW + bm) * xScale + bm, yBox + bm, xScale, yScale
   NEXT

END SUB

SUB cfLetter (L$, x, y, xScale, yScale)
   _CLEARCOLOR _RGB32(0, 0, 0), cf&
   lNum = INSTR("ABCDEFGHIJKLMNOPQRSTUVWXYZ!'()-.?:0123456789, ", UCASE$(L$))
   IF lNum = 0 THEN EXIT SUB ' couldn't find it
   lNum = lNum - 1
   lRow = lNum \ 8 '5 + rows
   lCol = lNum MOD 8 '8 chars per row
   lW = 40
   lH = 34
   _PUTIMAGE (x, y)-STEP(lW * xScale, lH * yScale), cf&, 0, (lCol * lW, lRow * lH)-STEP(lW - 1, lH - 1)
END SUB



And Johnno to declare the transparent color of your image use _CLEARCOLOR (see wiki: http://qb64.org/wiki/Main_Page) and also demo'd above ie comment it out and see what happens.
B += x
Reply
#10
Oh I guess the font looks better directly over the background without fitting into a box (and it doesn't always fit).

B += x
Reply