QB64 Phoenix Edition
_Putimage Question. - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://qb64phoenix.com/forum/forumdisplay.php?fid=3)
+---- Forum: Help Me! (https://qb64phoenix.com/forum/forumdisplay.php?fid=10)
+---- Thread: _Putimage Question. (/showthread.php?tid=4297)

Pages: 1 2


_Putimage Question. - Pete - 01-04-2026

I decided instead of making and placing two hardware accelerated up and down triangles to a Screen 0 routine, I'd just make one, pointing up, then draw a bar, and place it on top of the bar. So now I just invert it and place the inverted image at the bottom of the bar. Since I will need to change the coordinates in the routine, I needed to make some algorithms to handle those changes. Now all of that went smoothly, because I started out using a 120, 120 , 32 _NewImage screen with the triangle in the upper left corner. So after I finished, I thought I'd see what would happen if I reduced the size of the _NewImage screen to approximately the size of the triangle image. Well, here is the results...

Note: Press a key after the tiny image screen pops up to continue the routine.
Code: (Select All)
Width 80, 25: _Font 16
fw = _FontWidth: fh = _FontHeight
t = _NewImage(fw * 2, fh, 32) ' INCREASE _NEWIMAGE SCREEN SIZE TO SHRINK TRIANGLE TO: t = _NewImage(120, 120, 32)
Rem t = _NewImage(120, 120, 32)
Screen t ' Remark or remove this line and Sleep: Screen 0 to hide image creation.
_Dest t
' Draw a triangle.
a = 6: c = 0
For i = 0 To 6
    Line (a, c)-(a + i * 2, c)
    a = a - 1
    c = c + 1
Next
tri& = _CopyImage(t, 33)
Sleep: Screen 0 ' Remark or remove this line and Screen t to hide image creation.
_Dest 0
_FreeImage t
col = 32: row = 5: BarLength = 8
Locate row, col + 2: Print "__________Row"; row
Locate row + 8, col + 2: Print "__________Row"; row + 8
Locate row + 1, col
For j = 1 To BarLength
    Locate , col: Print Chr$(219)
Next
sx1 = col * fw - fw - 2: sy1 = fh \ 2 - 2
sx2 = sx1 + c * 2 * fw: sy2 = sy1 + i * fh + 3
TopTriangle = row * fh - fh ' 1st num is row in Screen 0.
xfactor = fh * (i - 1) - TopTriangle
BottomTriangle = BarLength * fh
Do
    _Limit 30
    _PutImage (sx1, sy1 + TopTriangle)-(sx2, sy2 + TopTriangle), tri&
    _PutImage (sx1, sy2 - xfactor + BottomTriangle)-(sx2, sy1 - xfactor + BottomTriangle), tri& ' Invert image.
Loop

This is the SAME except for using a larger _NewImage screen, and works as intended. Again, press a key after SLEEP.
Code: (Select All)
Width 80, 25: _Font 16
fw = _FontWidth: fh = _FontHeight
t = _NewImage(120, 120, 32) ' Using a larger image source prevents the image from stretching in _PutImage. ???
Screen t ' Remark or remove this line and Sleep: Screen 0 to hide image creation.
_Dest t
' Draw a triangle.
a = 6: c = 0
For i = 0 To 6
    Line (a, c)-(a + i * 2, c)
    a = a - 1
    c = c + 1
Next
tri& = _CopyImage(t, 33)
Sleep: Screen 0 ' Remark or remove this line and Screen t to hide image creation.
_Dest 0
_FreeImage t
col = 32: row = 5: BarLength = 8
Locate row, col + 2: Print "__________Row"; row
Locate row + 8, col + 2: Print "__________Row"; row + 8
Locate row + 1, col
For j = 1 To BarLength
    Locate , col: Print Chr$(219)
Next
sx1 = col * fw - fw - 2: sy1 = fh \ 2 - 2
sx2 = sx1 + c * 2 * fw: sy2 = sy1 + i * fh + 3
TopTriangle = row * fh - fh ' 1st num is row in Screen 0.
xfactor = fh * (i - 1) - TopTriangle
BottomTriangle = BarLength * fh
Do
    _Limit 30
    _PutImage (sx1, sy1 + TopTriangle)-(sx2, sy2 + TopTriangle), tri&
    _PutImage (sx1, sy2 - xfactor + BottomTriangle)-(sx2, sy1 - xfactor + BottomTriangle), tri& ' Invert image.
Loop

So we get two BIG ASCII triangles in the first code! Well, I know _PutImage has a stretch feature, and apparently I triggered it, which probably has something to do with not directing the code to identify both the source and destination coordinates, but I'm a bit lost here on how to accomplish this, if that's the situation.

Now if you change the _NewImage size as remarked or just RUN THE SECOND CODE, you would get what I intended. The same output, but with the triangles UNSTRETCHED.

So it works for me when I use the larger source screen, but I figure why pass on the chance to learn something about the _PutImage  properties and uses from those who regularly work in graphics.

Pete


RE: _Putimage Question. - bplus - 01-04-2026

Not seeing THE QUESTION here?

OK You can control the size of image by defining the box you want the image to appear on screen (_dest) the first part of arguments before first comma
ie _putimage (x, y) - (x1,y1), ...

You can also use _putimage to draw your arrow upside down! (messing with the source box coodinates, see keyword of day: _putimage).


RE: _Putimage Question. - Pete - 01-04-2026

Okay, let's say I wanted to use the smaller _NewImage screen. How would I code _PutImage so it wouldn't get stretched using the smaller _NewImage screen? Again, it doesn't get stretched if I use the second code, which uses a larger _NewImage screen, and in both the image gets drawn in the same place, the upper left corner.

Oh, I already did invert the image. Try both code snippets. It's just I don't understand the relationship between the size of the _NewImage Screen and the stretched vs non stretched output using exactly the same _PutImage code and coordinates.

Pete


RE: _Putimage Question. - bplus - 01-04-2026

I don't ever recall trying _PutImage on screen 0 nor using hardware code 33 so your code is confusing as hell to me.

OH! there was a Sleep! I had to press to see the print and scroll!


RE: _Putimage Question. - bplus - 01-04-2026

OK here is your first code fixed for smaller traingles:
Code: (Select All)
Width 80, 25: _Font 16
fw = _FontWidth: fh = _FontHeight
t = _NewImage(fw * 2, fh, 32) ' INCREASE _NEWIMAGE SCREEN SIZE TO SHRINK TRIANGLE TO: t = _NewImage(120, 120, 32)
Rem t = _NewImage(120, 120, 32)
Screen t ' Remark or remove this line and Sleep: Screen 0 to hide image creation.
_Dest t
' Draw a triangle.
a = 6: c = 0
For i = 0 To 6
    Line (a, c)-(a + i * 2, c)
    a = a - 1
    c = c + 1
Next
tri& = _CopyImage(t, 33)
Sleep: Screen 0 ' Remark or remove this line and Screen t to hide image creation.
_Dest 0
_FreeImage t
col = 32: row = 5: BarLength = 8
Locate row, col + 2: Print "__________Row"; row
Locate row + 8, col + 2: Print "__________Row"; row + 8
Locate row + 1, col
For j = 1 To BarLength
    Locate , col: Print Chr$(219)
Next
sx1 = col * fw - fw - 2: sy1 = fh \ 2 - 2
sx2 = sx1 + c * 2 * fw: sy2 = sy1 + i * fh + 3
TopTriangle = row * fh - fh ' 1st num is row in Screen 0.
xfactor = fh * (i - 1) - TopTriangle
BottomTriangle = BarLength * fh
Do
    _Limit 30
    _PutImage (sx1 - 4, sy1 + TopTriangle)-Step(24, 16), tri&  '<<<<<<<<<<<<
    _PutImage (sx1 - 4, sy2 - xfactor + BottomTriangle)-Step(24, -16), tri& '<<Invert image.
Loop

I just moved the top,lft corner over -4 to center triangles then -STEP(width tri, height tri)

dang _Putimage works in Screen 0 and with hardware image, IT! (IT! = Imagine That!)


RE: _Putimage Question. - Pete - 01-04-2026

Ah, you found a way to shrink it back to the original size, but...

Run the code again, but use t = _NewImage(120, 120, 32). It will still make our triangle in the upper left corner on the source image screen, but for some reason (I don't understand why) changing to a larger _NewImage screen ALSO changes the size of the triangle, and in both our codes.

So I tried messing around with: _PutImage (sx1, sy1 + TopTriangle)-(sx2, sy2 + TopTriangle), tri&, 0, (0, 0)-(15, 15) hoping the (0, 0)-(15, 15) would mean get just the area of _NewImage from the top-left to the width and height of the image, but no bueno! It still gave me the exact save stretch effect in the smaller _NewImage screen code. Sad

It's cool _PutImage can do so many things, but until I get a better understanding of what exactly is needed to use it correctly in those various situations I'm probably just going to use my method, and just always draw a bloated _NewImage screen to avoid problems when I'm also inverting an image.

I like that your example uses STEP, which I haven't used before. I see how it works, but I don't understand it.

Pete


RE: _Putimage Question. - SMcNeill - 01-04-2026

The thing is, you're only seeing a small portion of the actual imagine you're putting on the screen.

Code: (Select All)
**********************
*P                   *
*                    *
*                    *
*                    *
*                    *
*                    *
*                    *
*                    *
**********************

Now, let's say the above is your arrow on a 120x120 image. Do you notice how you're only actually displaying a very small corner of that image?  The vast majority is going to be black space.   But it's still there.   When you put that on a 360x360 image, you're basically just going to blow that P up to triple the size and have a ton of blank space.



Code: (Select All)
*****
*P  *
*   *
*****

Now compare the first image to the second one here.  Notice how that P now has a completely different area of white space around it it?  When you put this small image on the same 360x360 screen, it's not going to triple the size.  It's going to go from the 30x30 screen above and blow it up 12 times as wide and tall to fit the same 360x360 screen.

That's basically what you're doing here and why you're getting the results you are.

The smaller you screen, the more it's going to have to stretch to fill the area you want it to fill.

(Edit and why those code boxes aren't preserving the spaces properly is a mystery to me.  Grrrr)


RE: _Putimage Question. - bplus - 01-04-2026

(01-04-2026, 06:07 PM)Pete Wrote: Ah, you found a way to shrink it back to the original size, but...

Run the code again, but use t = _NewImage(120, 120, 32). It will still make our triangle in the upper left corner on the source image screen, but for some reason (I don't understand why) changing to a larger _NewImage screen ALSO changes the size of the triangle, and in both our codes.

So I tried messing around with: _PutImage (sx1, sy1 + TopTriangle)-(sx2, sy2 + TopTriangle), tri&, 0, (0, 0)-(15, 15) hoping the (0, 0)-(15, 15) would mean get just the area of _NewImage from the top-left to the width and height of the image, but no bueno! It still gave me the exact save stretch effect in the smaller _NewImage screen code. Sad

It's cool _PutImage can do so many things, but until I get a better understanding of what exactly is needed to use it correctly in those various situations I'm probably just going to use my method, and just always draw a bloated _NewImage screen to avoid problems when I'm also inverting an image.
Still
_PutImage (sx1, sy1 + TopTriangle)-(sx2, sy2 + TopTriangle), tri&, 0, (0, 0)-(15, 15)
seem right idea, I wonder why didn't work for you? (only showing 2/3's width triangle though).

I like that your example uses STEP, which I haven't used before. I see how it works, but I don't understand it.

Pete

Here is the fix for the larger screen, take only the part you want from the source, else it shows the whole source which changes the tri's to dots (I think) because it's bigger screen to fit in little space.

Code: (Select All)
Width 80, 25: _Font 16
fw = _FontWidth: fh = _FontHeight
't = _NewImage(fw * 2, fh, 32)

' INCREASE _NEWIMAGE SCREEN SIZE TO SHRINK TRIANGLE TO: t = _NewImage(120, 120, 32)
t = _NewImage(120, 120, 32)

Screen t ' Remark or remove this line and Sleep: Screen 0 to hide image creation.
_Dest t
' Draw a triangle.
a = 6: c = 0
For i = 0 To 6
    Line (a, c)-(a + i * 2, c)
    a = a - 1
    c = c + 1
Next
tri& = _CopyImage(t, 33)
Sleep: Screen 0 ' Remark or remove this line and Screen t to hide image creation.
_Dest 0
_FreeImage t
col = 32: row = 5: BarLength = 8
Locate row, col + 2: Print "__________Row"; row
Locate row + 8, col + 2: Print "__________Row"; row + 8
Locate row + 1, col
For j = 1 To BarLength
    Locate , col: Print Chr$(219)
Next
sx1 = col * fw - fw - 2: sy1 = fh \ 2 - 2
sx2 = sx1 + c * 2 * fw: sy2 = sy1 + i * fh + 3
TopTriangle = row * fh - fh ' 1st num is row in Screen 0.
xfactor = fh * (i - 1) - TopTriangle
BottomTriangle = BarLength * fh
Do
    _Limit 30
    _PutImage (sx1, sy1 + TopTriangle)-Step(24, 16), tri&, 0, (0, 0)-(23, 15) '<<<<<<<<<<<<
    _PutImage (sx1, sy2 - xfactor + BottomTriangle)-Step(24, -16), tri&, 0, (0, 0)-(23, 15) '<<
Loop

Seems like you had the right idea with
_PutImage (sx1, sy1 + TopTriangle)-(sx2, sy2 + TopTriangle), tri&, 0, (0, 0)-(15, 15)
but wrong numbers, triangle is 24 wide

Update: this is where it went wrong:  (sx2, sy2 + TopTriangle), you were making the destination box way too big.


RE: _Putimage Question. - bplus - 01-04-2026

Code: (Select All)
' Draw a triangle.
a = 6: c = 0
For i = 0 To 6
    Line (a, c)-(a + i * 2, c)
    a = a - 1
    c = c + 1
Next
 Oh that triangle is only 12 wide 6 down!

Revised for actual size of triangle:
Code: (Select All)
Width 80, 25: _Font 16
fw = _FontWidth: fh = _FontHeight
't = _NewImage(fw * 2, fh, 32)

' INCREASE _NEWIMAGE SCREEN SIZE TO SHRINK TRIANGLE TO: t = _NewImage(120, 120, 32)
t = _NewImage(120, 120, 32)

Screen t ' Remark or remove this line and Sleep: Screen 0 to hide image creation.
_Dest t
' Draw a triangle.
a = 6: c = 0
For i = 0 To 6
    Line (a, c)-(a + i * 2, c)
    a = a - 1
    c = c + 1
Next
tri& = _CopyImage(t, 33)
Sleep: Screen 0 ' Remark or remove this line and Screen t to hide image creation.
_Dest 0
_FreeImage t
col = 32: row = 5: BarLength = 8
Locate row, col + 2: Print "__________Row"; row
Locate row + 8, col + 2: Print "__________Row"; row + 8
Locate row + 1, col
For j = 1 To BarLength
    Locate , col: Print Chr$(219)
Next
sx1 = col * fw - fw - 2: sy1 = fh \ 2 - 2
sx2 = sx1 + c * 2 * fw: sy2 = sy1 + i * fh + 3
TopTriangle = row * fh - fh ' 1st num is row in Screen 0.
xfactor = fh * (i - 1) - TopTriangle
BottomTriangle = BarLength * fh
Do
    _Limit 30
    _PutImage (sx1, sy1 + TopTriangle)-Step(12, 6), tri&, 0, (0, 0)-(11, 6) '<<<<<<<<<<<<
    _PutImage (sx1, sy2 - xfactor + BottomTriangle)-Step(12, -6), tri&, 0, (0, 0)-(11, 6) '<<
Loop



RE: _Putimage Question. - Pete - 01-04-2026

WOOHOO!!!
Code: (Select All)
Width 80, 25: _Font 16

fw = _FontWidth: fh = _FontHeight
't = _NewImage(120, 120, 32) ' Using a larger image source prevents the image from stretching in _PutImage. ???
t = _NewImage(16, 16, 32)
Rem Screen t ' Remark or remove this line and Sleep: Screen 0 to hide image creation.
_Dest t
' Draw a triangle.
a = 6: c = 0: w = a * 2: h = a
For i = 0 To 6
    Line (a, c)-(a + i * 2, c)
    a = a - 1
    c = c + 1
Next
tri& = _CopyImage(t, 33)
Rem Sleep: Screen 0 ' Remark or remove this line and Screen t to hide image creation.
_Dest 0
_FreeImage t
col = 32: row = 5: BarLength = 8
Locate row, col + 2: Print "__________Row"; row
Locate row + 8, col + 2: Print "__________Row"; row + 8
Locate row + 1, col
For j = 1 To BarLength
    Locate , col: Print Chr$(219)
Next
sx1 = col * fw - fw - 2: sy1 = fh \ 2 - 2
sx2 = sx1 + c * 2 * fw: sy2 = sy1 + i * fh + 3
TopTriangle = row * fh - fh ' 1st num is row in Screen 0.
xfactor = fh * (i - 1) - TopTriangle
BottomTriangle = BarLength * fh - fh \ 2 + 2
Do
    _Limit 30
    _PutImage (sx1, sy1 + TopTriangle), tri&, 0, (0, 0)-(w, h)
    _PutImage (sx1, sy2 - xfactor + BottomTriangle), tri&, 0, (0, h)-(w, 0) ' Invert image.
Loop


Mark figured out a solution using Step that worked with both _NewImage sizes, although in one a pixel was missing, but that just takes fiddling more with the variables. Since I haven't figured out the mechanics of step yet, I just decided to apply Steve and Mark's reasoning to what I do know, and got lucky!

My initial approach, which I've used without problems on non-inverted hardware images, needed to be modified because I thought to flip the image I needed to include both the source and destination values. Like Mark stated, I made the destination part too big! Since I'm not changing (stretching) the image, I just eliminated that part in the first (non-inverted) image and for the inversion method I just swapped sy1 to sy2, as before, but... and here's the magic... made the destination left-bottom to right-top. In other words, read it upside down.

+1 to Steve for the image size stretching info, which, and correct me if I missed something, I believe only applies to cases where we stretch the destination box.

+2 to Mark for catching the destination box problem and coding an alternative step method!

Pete