QB64 Phoenix Edition
from png tile, create symmetrical screen image - 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: from png tile, create symmetrical screen image (/showthread.php?tid=3874)

Pages: 1 2


from png tile, create symmetrical screen image - hsiangch_ong - 08-20-2025

i have a png file.  that will serve as a tile.  this tile will be flipped.  horizontally and vertically.  to create a symmetric image.  that will be larger than my display screen.

in other words.  for 2x2 tile.  first the original tile.  then next to it horizontally.  it is flipped horizontally.  then the two tiles just below.  are the same thing.  but both flipped vertically.  so that the 2x2 image is symmetrical.  then this 2x2 image.  is used to create another image.  which is larger than the display screen.

the display screen is 1366x768.  the png image will be much smaller than this.  usually below 200 pixels in both dimensions.  i round off on purpose to even numbers.

how do i crop this large image.  so the display screen is symmetrical all around?  horizontally as well as vertically?

i have this program.  if i'm lucky.  it falls into place like expected.  but sometimes it doesn't do it right horizontally.  or doesn't do it right vertically.

Code: (Select All)
'by hsiangch_ong 20-aug-2025
OPTION _EXPLICIT

DIM AS LONG scr, scrout, scr1, wd, ht, wd1, ht1, xx, yy, u, j, ll
DIM AS _BYTE flipx, flipy
DIM AS INTEGER doxflip
DIM afile$, bfile$, apath$

REDIM sf(1 TO 1) AS STRING

'change the following path to what you want in your system.
'especially if you're on macos.  (i forgot which is the precise user home directory.)
'copy the provided png files to this directory.
'this program's output is the same directory.
$IF LINUX THEN
apath$ = ENVIRON$("HOME") + "/Pictures/backf"
$ELSE
apath$ = ENVIRON$("USERPROFILE") + "/Pictures/backf"
$END IF
afile$ = _FILES$(apath$)
DO UNTIL afile$ = ""
    IF RIGHT$(afile$, 4) = ".png" THEN
        ll = ll + 1
        REDIM _PRESERVE sf(1 TO ll) AS STRING
        sf(ll) = apath$ + "/" + afile$
    END IF
    afile$ = _FILES$
LOOP

FOR j = 1 TO ll
    scr = _LOADIMAGE(sf(j), 32)
    IF scr >= -1 THEN
        _MESSAGEBOX "Backflip", "Failed to load image:" + CHR$(13) + sf(j), "error"
        SYSTEM
    END IF

    wd = _WIDTH(scr)
    ht = _HEIGHT(scr)
    wd1 = wd
    ht1 = ht
    doxflip = 0
    DO UNTIL wd1 >= 1366
        doxflip = doxflip + 1
        wd1 = wd1 + wd
    LOOP
    DO UNTIL ht1 >= 768: ht1 = ht1 + ht: LOOP

    scr1 = _NEWIMAGE(wd1, ht1, 32)
    scrout = _NEWIMAGE(1366, 768, 32)
    IF scr1 >= -1 THEN
        _FREEIMAGE scr
        _MESSAGEBOX "Backflip", "There isn't enough memory for an image that large!", "error"
        SYSTEM
    END IF
    IF scrout >= -1 THEN
        _FREEIMAGE scr1
        _FREEIMAGE scr
        _MESSAGEBOX "Backflip", "There isn't enough memory for two images!", "error"
        SYSTEM
    END IF

    u = INSTR(sf(j), ".")
    afile$ = LEFT$(sf(j), u - 1) + "-neu.png"
    _TITLE "Backflip - SAVING " + afile$

    flipx = 0
    flipy = 0
    FOR yy = 0 TO ht1 STEP ht
        FOR xx = 0 TO wd1 STEP wd
            IF flipy THEN
                IF flipx THEN
                    _PUTIMAGE (xx + wd - 1, yy + ht - 1)-(xx, yy), scr, scr1
                ELSE
                    _PUTIMAGE (xx, yy + ht - 1)-(xx + wd - 1, yy), scr, scr1
                END IF
            ELSE
                IF flipx THEN
                    _PUTIMAGE (xx + wd - 1, yy)-(xx, yy + ht - 1), scr, scr1
                ELSE
                    _PUTIMAGE (xx, yy)-(xx + wd - 1, yy + ht - 1), scr, scr1
                END IF
            END IF
            flipx = NOT flipx
        NEXT
        IF doxflip MOD 2 > 0 THEN flipx = NOT flipx
        flipy = NOT flipy
    NEXT

    wd = (wd1 - 1366) \ 2
    ht = (ht1 - 768) \ 2
    _PUTIMAGE (0, 0)-(1365, 767), scr1, scrout, (wd, ht)-(wd + 1365, ht + 767)
    _SAVEIMAGE afile$, scrout
    _FREEIMAGE scrout
    _FREEIMAGE scr1
    _FREEIMAGE scr
    PRINT "Saved: "; afile$
NEXT
PRINT "COMPLETED"
_TITLE "Backflip - COMPLETED"
_DELAY 3
SYSTEM
use your own png files.  it's recommended they are smaller than 200x200.  unless you have a much larger screen than mine.

originally the output of this program.  was jpeg format.  converted with imagemagick.  because qb64 phoenix doesn't offer jpeg saving with compression.

.zip   hsiangch_ong-backflip-batch.zip (Size: 128.21 KB / Downloads: 32)


RE: from png tile, create symmetrical screen image - bplus - 08-20-2025

I think you want this, just a guess:

The simplest way "to crop" image and load the screen with that section is to use the Snipping Tool of your choice and get a snapshot of just the image you want for your screen.

Then Screen with _Newimage the dimensions proportional to the image you just snipped 
say the snip is 100 X 150 you can Screen _NewImage(100*m, 150*m, 32) ' <<< use 32 for full set of RGB
 colors. Let M be your multiplication factor or Scaling, say 5 to get 500 x 750 or 5 times the size of the snip.
Of course as you get bigger and bigger the pixels will get bigger for each point in original snip.

Anyway with 
Screen _NewImage(100*M, 150*M, 32)
' Load image
MyImage& = _Loadimage("MySnip.png")
_PutImage , MyImage&, 0  ' fills the screen without distorting horizontal and vertical dimensions still gunna get pixelation though

Use the another M factor or scale factor to make way less smaller "tiles" of image and use with _PutImage to tile screen with image and keep all dimensions proportional you can flip vertically or horizontally but only square images can you rotate 90 degrees with _PutImage without more problems that would need math to solve.


RE: from png tile, create symmetrical screen image - SMcNeill - 08-20-2025

Isn't this just a case of using _PUTIMAGE to turn/rotate the original as desired.

Start with the original image.

Divide your screen into 4 sections.

If you consider the top left to be the original then _PUTIMAGE that original in the top left, as is.

Then _PUTIMAGE that time in the top right, but reverse the coordinates.   _PUTIMAGE (midpointX,0)-(endpointX,midpointY),originalimage, (endX,0)- 
(startX,_height).   

Notice how I flipped my startX and endX in that image, to create a mirror from left to right?   Now just do the same with your bottom two quadrants and you're done.  It's that simple, unless I'm missing what you're trying to say here.


RE: from png tile, create symmetrical screen image - SMcNeill - 08-20-2025

Basically just this simple process:

Code: (Select All)
Randomize Timer

DisplayScreen = _NewImage(1920, 1080, 32) 'make this whatever size you like
ImageScreen = _NewImage(Rnd * 320 + 320, Rnd * 240 + 240, 32) 'my image, which is by definition any size I want it to be -- that's why it's a random size here.

Screen DisplayScreen
_Dest ImageScreen

'Now, let's just draw some pattern on the imagescreen so we can flip/rotate it
For x = 0 To _Width(ImageScreen) Step _Width(ImageScreen) / 8
For y = 0 To _Height(ImageScreen) Step _Height(ImageScreen) / 6
Line (x, y)-Step(_Width(ImageScreen) / 8, _Height(ImageScreen) / 6), _RGB32(Rnd * 256, Rnd * 256, Rnd * 256), BF
Next
Next
_Dest DisplayScreen

'Now let's do our mirroring

'first the original
_PutImage (0, 0)-(_Width / 2, _Height / 2), ImageScreen, DisplayScreen, (0, 0)-(_Width(ImageScreen), _Height(ImageScreen))
'and a SLEEP so we can see it in all its glory
Sleep

'and then let's mirror it on the right and SLEEP to view it
_PutImage (_Width / 2, 0)-(_Width, _Height / 2), ImageScreen, DisplayScreen, (_Width(ImageScreen), 0)-(0, _Height(ImageScreen))
Sleep

'and then let's do the other two quadrants
_PutImage (0, _Height / 2)-(_Width / 2, _Height), ImageScreen, DisplayScreen, (0, _Height(ImageScreen))-(_Width(ImageScreen), 0)
Sleep
_PutImage (_Width / 2, _Height / 2)-(_Width, _Height), ImageScreen, DisplayScreen, (_Width(ImageScreen), _Height(ImageScreen))-(0, 0)
Sleep

Now note that this has a set of black lines which work as a divider to show our quadrants for us. This is not a glitch and is intentional on my part, just to highlight the flipping/mirroring which we do with _PUTIMAGE in each quadrant.

How'd I get it in there? And how would one remove it?

Correct my endpoints!! I'm using putimage from 0 to _WIDTH and from 0 to _HEIGHT, while the image uses coordinates from 0 to _WIDTH -1, 0 to _HEIGHT -1! I'm deliberately tossing a blank pixel that doesn't exist into my putimage statements here to create that blank line which you see in the center of the quadrants. I doubt you'd actually want that for yourself, so adjust those values by that offset.

For example a screen that is 640 x 480 pixels in size has coordinates from 0 to 639, 0 to 479 and NOT from 0 to 640 and 0 to 480. I'm not adjusting for that 0-offset here and I'm using it for an extra pixel to make those blank lines for highlight of each quadrant. You'll want to take that offset into account for seamless mirroring/flipping.

Unless I'm completely missing what you're trying to do here, somehow. Wink


RE: from png tile, create symmetrical screen image - hsiangch_ong - 08-21-2025

thank you for all the replies.

i was trying to achieve something like the picture below.

i ended up modifying the program i posted here.  so a large png file was created into disk.  like over 3000x2000 or alike.  so it could be edited in gimp the way i wanted.

[Image: beads-test.jpg]


RE: from png tile, create symmetrical screen image - Pete - 08-21-2025

Dammit menn, this is a programmers forum, not a quilting circle!!!!

Pete Big Grin


RE: from png tile, create symmetrical screen image - bplus - 08-21-2025

(08-21-2025, 12:38 AM)hsiangch_ong Wrote: thank you for all the replies.

i was trying to achieve something like the picture below.

i ended up modifying the program i posted here.  so a large png file was created into disk.  like over 3000x2000 or alike.  so it could be edited in gimp the way i wanted.

[Image: beads-test.jpg]

Oh THAT's what you were looking for, cool!


RE: from png tile, create symmetrical screen image - bplus - 08-21-2025

Quote:Dammit menn, this is a programmers forum, not a quilting circle!!!!

Don't you know QB stands for Quilting Bee!
Code: (Select All)
_Title "PutImage Demo 7" ' b+ 2025-08-21
' modify demo 5 by tiling screen with an image and 3 rotations

Screen _NewImage(800, 600, 32) ' screen width, height, 32 is _RGBA colors
_Delay .2
Logo& = _LoadImage("qb64.png")

scale = 1 ' we are going to magnify the image by .755 and preserve the ratio of width to height
scaleW = scale * _Width(Logo&) '
scaleH = scale * _Height(Logo&)

' make an image Tile by
' put image, the actual size, into the middle of our screen

' then flip image mirror on x and y axis
_PutImage (_Width / 2, _Height / 2 - scaleH)-Step(scaleW, scaleH), Logo&, 0
_PutImage (_Width / 2, _Height / 2 - scaleH)-Step(-scaleW, scaleH), Logo&, 0
_PutImage (_Width / 2, _Height / 2 + scaleH)-Step(scaleW, -scaleH), Logo&, 0
_PutImage (_Width / 2, _Height / 2 + scaleH)-Step(-scaleW, -scaleH), Logo&, 0

myTile& = _NewImage(2 * scaleW, 2 * scaleH)
_PutImage (0, 0), 0, myTile&, (_Width / 2 - scaleW, _Height / 2 - scaleH)-Step(2 * scaleW, 2 * scaleH)
Cls
_PutImage (0, 0), myTile&, 0 ' check tile  'OK
For y = 0 To 600 Step 100
    For x = 0 To 800 Step 100
        _PutImage (x, y)-Step(100, 100), myTile&, 0
    Next
Next
Sleep

   

qb64.png
   


RE: from png tile, create symmetrical screen image - bplus - 08-21-2025

Note: the above code only works if double the image width and height still fits the screen eg testing

2 Tile Crop 2.png
   

Result with above code:
   


Now this image is too big to fit screen when doubke its width and height, so had to modify code a tiny bit:
2 Tile Crop.png
   
Code: (Select All)
_Title "PutImage Demo 7B different image" ' b+ 2025-08-21
' modify demo 5 by tiling screen with an image and 3 rotations

Screen _NewImage(800, 600, 32) ' screen width, height, 32 is _RGBA colors
_Delay .2
Logo& = _LoadImage("2 Tile Crop.png") ' this image when quadrupled exceeds screen size

scale = 1 ' we are going to magnify the image by .755 and preserve the ratio of width to height
scaleW = scale * _Width(Logo&) '
scaleH = scale * _Height(Logo&)

' make an image Tile by
' put image, the actual size, into the middle of our screen

' then flip image mirror on x and y axis
_PutImage (_Width / 2, _Height / 2 - scaleH)-Step(scaleW, scaleH), Logo&, 0
_PutImage (_Width / 2, _Height / 2 - scaleH)-Step(-scaleW, scaleH), Logo&, 0
_PutImage (_Width / 2, _Height / 2 + scaleH)-Step(scaleW, -scaleH), Logo&, 0
_PutImage (_Width / 2, _Height / 2 + scaleH)-Step(-scaleW, -scaleH), Logo&, 0
Sleep

myTile& = _NewImage(_Width, _Height)
_PutImage (0, 0), 0, myTile& ' >>> take out this part: , (_Width / 2 - scaleW, _Height / 2 - scaleH)-Step(2 * scaleW, 2 * scaleH)
Cls
_PutImage , myTile&, 0 ' check tile  'OK
Sleep
Cls
For y = 0 To 600 Step 200
    For x = 0 To 800 Step 200
        _PutImage (x, y)-Step(200, 200), myTile&, 0
    Next
Next
Sleep

result:    


RE: from png tile, create symmetrical screen image - hsiangch_ong - 08-22-2025

i like this solution.  the trade-off is that it stretches the tile.

if the input png file has a gradient.  or some other screen element.  that is "sensitive" to stretching.  it would be easily noticed.  that it looks dumb that it was stretched.  or it relies too much on "dither."

that's why my program.  purposely creates a "virtual" screen which is larger than the target display screen.  then tries to set things up.  so it crops only the display screen size.  it sets the tiles without stretching.

@bplus i am curious with one thing in your program.  you say something about scale variable.  but why set it to a different value?