Author Topic: Custom Edit Image, Save and Load with Turkey Hunt WIP Game  (Read 7412 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« on: December 30, 2021, 02:45:44 pm »
OK here's the story I started translating this guys tutorial for beginner Blitzmax here:
https://www.syntaxbomb.com/tutorials/learning-basic-for-total-beginners-blitzmax-ng/msg347053898/#msg347053898

Blitzmax code:
Code: [Select]
SuperStrict
Graphics 800,600
Global Land:TImage    = LoadImage("land.png")
Global Chicken:TImage = LoadImage("chicken.png")
Global Shot:TSound=LoadSound("fire.ogg")
Global cX:Int, cY:Int=300
Global mX:Int, mY:Int
Global Points:Int
Repeat
        Cls
        DrawImage Land    , 0 , 0
        'DrawImage Chicken , cX , cY
        '   comment out the original command, and use DrawRect instead:
        SetColor 111,0,0
        DrawRect cX, cY, 60,40
        cX = cX +2
        If GunFire() =True Then
                cX=-100
                Points=Points+1
        EndIf
        SetColor 255,255,255
        DrawRect mX-25, mY-1,50,3
        DrawRect mX-1, mY-25,3,50
        'HideMouse
        DrawText "Points: " + points, 700,550
        Flip
Until AppTerminate()
ShowMouse
 
 
Function GunFire:Int()
        mX=MouseX()
        mY=MouseY()   
        If MouseHit(1)
                PlaySound Shot
                If (mX>cX) And (mx<cX+60)
                        If (mY>cY) And (mY<cY+40)
                                ' collision
                                Return True
                        EndIf
                EndIf
        EndIf
        Return False
End Function

But the code didn't come with a chicken image so I thought I'd reuse the Turkey Cartoon from Turkey Run from Thanksgiving ie Turkey Day

OK but now the Turkey's background isn't working with the background for the Hunt. (I just used white to hide the turkey background mostly white in image in Turkey Day.)

So like Colonel Panic here: https://qb64forum.alephc.xyz/index.php?topic=4539.0
I got interested in custom editing and saving and loading a modified image.

So I reworked SMcNeill's quick demo for any image not just the screen got it working without _defalte$ _inflate with this code:
Code: QB64: [Select]
  1. _Title "Edit image test" 'b+ 2021-12-29 sure would like to take an image and the subject wo background colors
  2. ' from  C:\Users\marka\Desktop\QB64 work\000 work QB64\000 Test\More Saving Images
  3. ' file "Fast Image Save and Load.bas" by SMcNeill 2021-12-07
  4.  
  5.  
  6. ''Scn& = _NewImage(800, 600, 32)  'should not need these 2 lines if loadimage with 32
  7. ''Screen Scn&
  8. Dim image&: image& = _LoadImage("turkey run.jpg", 32) ' <<<<<<<<<<<<<<<<< Edit Image file name
  9. ''Print image& ' OK -12   guess I forgot to save file before trying so in QB64 folder instead of project folder
  10. ''Sleep
  11.  
  12. Dim Scn&: Scn& = _NewImage(_Width(image&), _Height(image&), 32)
  13. Screen Scn&
  14. _Source image& ' for using Point from image
  15.  
  16. ''_ClearColor Point(10, 10), image&  ' testing a know background point to make transparent
  17. ''_PutImage , image&, 0 '
  18. ''Print "Paint test, press any... ": Sleep
  19. ''_PutImage , image&, 0 '
  20. ''Paint (10, 10), &HFFFFFFFF, &HFF000000 ' nope "turkey run.jpg" has no pure black border enclosing the image
  21. ''End
  22.  
  23. Dim mx, my, outRed, outGrn, outBlu, outAlp, x, y
  24.     Cls ' must clear screen to see what was cleared from image if anything
  25.     _PutImage , image&, 0 '
  26.     While _MouseInput: Wend ' poll mouse to show me where I am at
  27.     mx = _MouseX: my = _MouseY
  28.     Line (mx - 3, my - 3)-(mx + 3, my + 3), , B ' eraser block  black & white frame around eraser
  29.     Line (mx - 4, my - 4)-(mx + 4, my + 4), &HFF000000, B ' eraser block
  30.     cAnalysis Point(mx, my), outRed, outGrn, outBlu, outAlp
  31.     Locate 1, 1: Print Space$((_Width - 1) / 8)
  32.     Locate 1, 1: Print outRed; outGrn; outBlu; outAlp
  33.         For y = my - 2 To my + 2
  34.             For x = mx - 2 To mx + 2
  35.                 _ClearColor Point(x, y), image&
  36.             Next
  37.         Next
  38.     End If
  39.     _Display
  40.     _Limit 100
  41. Cls 'get rid of mouse stuff before save image
  42. _PutImage , image&, 0
  43.  
  44. 'Dim M As _MEM: M = _MemImage(Scn&)
  45. 'Screengrab$ = Space$(M.SIZE)
  46. '_MemGet M, M.OFFSET, Screengrab$
  47.  
  48. 'The above will:
  49. 'Dim a mem block.  Point it to your screen's image.
  50. 'Set a string that size.
  51. 'Get the whole screen at once into that string.
  52.  
  53.  
  54. 'Then to save to disk all at once:
  55. 'Open "Test SaveLoad Image.bin" For Binary As #1
  56. 'Put #1, , Screengrab$
  57. 'Close
  58. 'Open the file, put the data in one chunk, close the file.
  59.  
  60. ' hopefully the above has been encoded properly into a Sub
  61. SaveCustomImage Scn&, "Test Save Turkey Run"
  62.  
  63. Print "Press any to test load image again... "
  64.  
  65. 'Loading is the same, in reverse:
  66. 'Open "Test SaveLoad Image.bin" For Binary As #1
  67. 'Get #1, , Screengrab$
  68. 'Close
  69. 'And putting the data back to screen is also done all in one command:
  70. '_MemPut M, M.OFFSET, Screengrab$
  71.  
  72. 'And hopefully the LoadCustomImage& Function gets the data back from file
  73. Dim image2&: image2& = LoadCustomImage&("Test Save Turkey Run")
  74. _PutImage , image2&, 0 ' put back on screen
  75.  
  76. Sub cAnalysis (c As _Unsigned Long, outRed, outGrn, outBlu, outAlp)
  77.     outRed = _Red32(c): outGrn = _Green32(c): outBlu = _Blue32(c): outAlp = _Alpha32(c)
  78.  
  79. 'this will create 2 files for Custom Image:
  80. '1) FileName$ + "CI_DIM" for image dimensions
  81. '2) FileName$ + "CI" for the Custom Image data
  82. Sub SaveCustomImage (imgHdl&, fileSaveBaseName$) ' for any image setup by _newimage
  83.     Dim As Long w, h: w = _Width(imgHdl&): h = _Height(imgHdl&)
  84.     Dim M As _MEM: M = _MemImage(imgHdl&) 'Dim a mem block.  Point it to your screen's image.
  85.     Dim screenGrab$: screenGrab$ = Space$(M.SIZE) 'Set a string that size.
  86.     'screenGrab$ = _Deflate$(screenGrab$)
  87.     _MemGet M, M.OFFSET, screenGrab$ 'Get the whole screen at once into that string.
  88.     Open fileSaveBaseName$ + ".CI_DIM" For Output As #1
  89.     Print #1, w
  90.     Print #1, h
  91.     Close #1
  92.     Open fileSaveBaseName$ + ".CI" For Binary As #1
  93.     Put #1, , screenGrab$
  94.     Close
  95.  
  96. ' Function returns Image Handle& (like _LoadFile)
  97. Function LoadCustomImage& (fileLoadBaseName$) ' reverse the Save
  98.     Dim As Long w, h
  99.     Open fileLoadBaseName$ + ".CI_DIM" For Input As #1 ' get dimensions of custom image
  100.     Input #1, w
  101.     Input #1, h
  102.     Close #1
  103.     Dim imgHdl&: imgHdl& = _NewImage(w, h, 32) 'setup space and handle for it
  104.     Dim M As _MEM: M = _MemImage(imgHdl&) ' put data into handle space reserved
  105.     Dim screenGrab$: screenGrab$ = Space$(M.SIZE)
  106.     Open fileLoadBaseName$ + ".CI" For Binary As #1 ' get data
  107.     'screenGrab$ = Space$(LOF(1))
  108.     Get #1, , screenGrab$
  109.     Close #1
  110.     'screenGrab$ = _Inflate$(screenGrab$)  ' doesn't work
  111.     _MemPut M, M.OFFSET, screenGrab$
  112.     LoadCustomImage& = imgHdl& ' finally assign the function
  113.  

Press escape when done erasing pixels and the image is saved and the loaded and displayed to test code in subs just as it was tested in Steve's original.

Then I ran the modified image in Turkey Hunt:
Code: QB64: [Select]
  1. _Title "Turkey Shoot" 'b+ 2021-12-29   translate from BlitzMax to QB64 and modify, source:
  2. '  https://www.syntaxbomb.com/tutorials/learning-basic-for-total-beginners-blitzmax-ng/msg347053898/#msg347053898
  3. '  from MidiMaster tutorial on BlitzMax started Dec 22, 2021
  4.  
  5. ' single comments are BlitzMax code
  6. '' double comments are added notes by bplus
  7.  
  8. 'SuperStrict
  9. Option _Explicit ' must Dimension variables with types before using
  10.  
  11. '' current default type is single suffix ! not needed which is low precision float
  12.  
  13. 'Graphics 800,600
  14. '' land.png the background is 1347 X 600 so let's use a screen in same proportion  shrink by 1.1225 so no distorion of background
  15. Screen _NewImage(1200, 534, 32) ' << the 32 allows RGBA color, this sets up customized graphics screen
  16. _ScreenMove 60, 100 '' centers screen in window
  17.  
  18. 'Global Land:TImage    = LoadImage("land.png")   '' dims 1347 x 600
  19. Dim Land&: Land& = _LoadImage("land.png")
  20.  
  21. 'Global Chicken:TImage = LoadImage("chicken.png")
  22. '' for Global use Shared keyword with Dim (or ReDim or Static for Subs to preserve values)
  23. ''Dim Shared Turkey&: Turkey& = _LoadImage("turkey run.jpg")
  24. '' remove background color OK this isn't the cleanest removal , BlizMax just drew a rectangle
  25. ''_Source Turkey&
  26. ''_ClearColor Point(10, 10), Turkey&
  27. ''_ClearColor Point(64, 22), Turkey&
  28. ''_ClearColor Point(86, 133), Turkey&
  29. ''_PutImage (0, 0), Turkey&, 0
  30.  
  31. ''Do ' find points to make transparent
  32. ''    While _MouseInput: Wend
  33. ''    Locate 1, 1: Print Space$(40)
  34. ''    Locate 1, 1: Print _MouseX, _MouseY, Point(_MouseX, _MouseY) \ 256, (Point(_MouseX, _MouseY) \ 256) \ 256, ((Point(_MouseX, _MouseY) \ 256) \ 256) \ 256
  35. ''    _Display
  36. ''    _Limit 100
  37. ''Loop
  38. ''End
  39. ''_ClearColor Point(10, 10), Turkey&
  40. ''_Source 0
  41.  
  42. ' the above block was replaced with a Custom Image Load
  43. Dim Shared Turkey&: Turkey& = LoadCustomImage&("Test Save Turkey Run")
  44. _ClearColor &HFF000000, Turkey&
  45. _PutImage (100, 100), Turkey&, 0 ' I want to see how our image looks from custom load
  46. Print "Here is our target, press any to continue..."
  47.  
  48.  
  49. Dim Shared TurkeyWidth&: TurkeyWidth& = 100 '     proportional to image
  50. Dim Shared TurkeyHeight&: TurkeyHeight& = 83
  51.  
  52. 'Global Shot:TSound=LoadSound("fire.ogg")
  53. Dim Shared Shot&: Shot& = _SndOpen("fire.ogg")
  54.  
  55. 'Global cX:Int, cY:Int=300
  56. 'Global mX:Int, mY:Int
  57. 'Global Points:Int
  58. ' in QB64 you can Dim with suffix or say Type in DIM ststement
  59. 'Since we are using a Turkey instead of a Chicken:
  60. Dim Shared As Long TurkeyX, TurkeyY, MX, MY, Points
  61. TurkeyY = 350 ' for now the other values are at 0
  62.  
  63.  
  64. 'start turkey on right side of screen, this image can only run left
  65. TurkeyX = _Width
  66.  
  67.  
  68. 'Repeat
  69. ' default drawing color is already white
  70.  
  71.     'Cls '' not needed in QB64
  72.  
  73.     'DrawImage Land    , 0 , 0
  74.     _PutImage , Land&, 0 ' stretch/shrink image to fit screen  This already CLS screen
  75.  
  76.     'DrawImage Chicken , cX , cY
  77.     '   comment out the original command, and use DrawRect instead:
  78.     '    SetColor 111,0,0
  79.     '    DrawRect cX, cY, 60,40
  80.  
  81.     _PutImage (TurkeyX, TurkeyY)-Step(TurkeyWidth&, TurkeyHeight&), Turkey&, 0 ' shrink image into Box
  82.  
  83.  
  84.     '    cX = cX +2
  85.     TurkeyX = TurkeyX - Rnd * 20
  86.  
  87.     'if turkey lives to run outside of screen replace it on left side
  88.     If TurkeyX + _Width(Turkey&) < 0 Then TurkeyX = _Width + 50
  89.  
  90.  
  91.     'If GunFire() =True Then
  92.     If GunFire& Then
  93.  
  94.         ' QB64 Bonus display turkey upside down!!!
  95.         _PutImage , Land&, 0 ' stretch/shrink image to fit screen
  96.         _PutImage (TurkeyX, TurkeyY)-Step(TurkeyWidth&, TurkeyHeight&), Turkey&, 0, (0, _Height(Turkey&))-Step(_Width(Turkey&), -_Height(Turkey&))
  97.         _Display
  98.         _Delay 1 ' ha, upside down
  99.  
  100.  
  101.         '        cX=-100
  102.         TurkeyX = _Width ' reset turkey to left side of screen
  103.  
  104.         Points = Points + 1 'same for both for next loop
  105.  
  106.     End If ' same
  107.  
  108.     'SetColor 255,255,255
  109.     'DrawRect mX-25, mY-1,50,3
  110.     'DrawRect mX-1, mY-25,3,50
  111.  
  112.     ' This is for mouse scope  (the gunFire call updates mouse info in loop)
  113.     Line (MX - 20, MY)-Step(40, 0), &HFF000000
  114.     Line (MX, MY - 20)-Step(0, 40), &HFF000000
  115.     Circle (MX, MY), 8
  116.     Circle (MX, MY), 14
  117.     ''HideMouse
  118.     'did this before starting loop
  119.  
  120.     'DrawText "Points: " + points, 700,550
  121.     _PrintString (10, 10), " Points:" + Str$(Points) + " "
  122.  
  123.     'Flip
  124.     _Display ' prevent blinking form CLS
  125.     _Limit 60 ' 30 frames per second at most!
  126.  
  127.     'Until AppTerminate()
  128. Loop Until _KeyDown(27) 'quit with escape, top right x click will also close window no matter what
  129. 'ShowMouse
  130. '_MouseShow not really needed
  131.  
  132.  
  133. 'Function GunFire:Int()
  134. '        mX=MouseX()
  135. '        mY=MouseY()
  136. '        If MouseHit(1)
  137. '                PlaySound Shot
  138. '                If (mX>cX) And (mx<cX+60)
  139. '                        If (mY>cY) And (mY<cY+40)
  140. '                                ' collision
  141. '                                Return True
  142. '                        EndIf
  143. '                EndIf
  144. '        EndIf
  145. '        Return False
  146. 'End Function
  147.  
  148. Function GunFire& () ' Long integer Type
  149.     While _MouseInput: Wend ' poll mouse updates the mouse information in keyWords starting with _Mouse...
  150.     MX = _MouseX: MY = _MouseY
  151.     If _MouseButton(1) Then ' Left mouse button is down, might want to wait until released but we delay in main loop if hit
  152.         _SndPlay Shot&
  153.         If (MX > TurkeyX) And (MX < TurkeyX + TurkeyWidth&) Then
  154.             If (MY > TurkeyY) And (MY < TurkeyY + TurkeyHeight&) Then
  155.                 ' collision
  156.                 ' return True value with Function name
  157.                 GunFire& = -1 ' anything not 0 is true
  158.             End If
  159.         End If
  160.     End If
  161.     'else function returns 0
  162.  
  163. ' Function returns Image Handle& (like _LoadFile)
  164. Function LoadCustomImage& (fileLoadBaseName$) ' reverse the Save
  165.     Dim As Long w, h
  166.     Open fileLoadBaseName$ + ".CI_DIM" For Input As #1 ' get dimensions of custom image
  167.     Input #1, w
  168.     Input #1, h
  169.     Close #1
  170.     Dim imgHdl&: imgHdl& = _NewImage(w, h, 32) 'setup space and handle for it
  171.     Dim M As _MEM: M = _MemImage(imgHdl&) ' put data into handle space reserved
  172.     Dim screenGrab$: screenGrab$ = Space$(M.SIZE)
  173.     Open fileLoadBaseName$ + ".CI" For Binary As #1 ' get data
  174.     Get #1, , screenGrab$
  175.     Close #1
  176.     _MemPut M, M.OFFSET, screenGrab$
  177.     LoadCustomImage& = imgHdl& ' finally assign the function
  178.  
  179.  

Which is nice start but begging for refinements ;-))

So my question (mostly to @SMcNeill) is can the sub and function be modified to use _deflate and _inflate from the Editing app?  I left in comments to the code I tried but the playback is ending up blank without any errors flagged, so I uncommented the working save and load that I could use in Turkey Hunt.

Oh here is a zip with code, images and exes for Windows 10-64. The sound and images are for forum use only for discussion.
* Turkey Hunt WIP 2021-12-30.zip (Filesize: 2.05 MB, Downloads: 152)

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« Reply #1 on: December 30, 2021, 03:25:25 pm »
Give this a quick test run:

Code: QB64: [Select]
  1. _Title "Edit image test" 'b+ 2021-12-29 sure would like to take an image and the subject wo background colors
  2. ' from  C:\Users\marka\Desktop\QB64 work\000 work QB64\000 Test\More Saving Images
  3. ' file "Fast Image Save and Load.bas" by SMcNeill 2021-12-07
  4.  
  5.  
  6. ''Scn& = _NewImage(800, 600, 32)  'should not need these 2 lines if loadimage with 32
  7. ''Screen Scn&
  8. Dim image&: image& = _LoadImage("turkey run.jpg", 32) ' <<<<<<<<<<<<<<<<< Edit Image file name
  9. ''Print image& ' OK -12   guess I forgot to save file before trying so in QB64 folder instead of project folder
  10. ''Sleep
  11.  
  12. Dim Scn&: Scn& = _NewImage(_Width(image&), _Height(image&), 32)
  13. Screen Scn&
  14. _Source image& ' for using Point from image
  15.  
  16. ''_ClearColor Point(10, 10), image&  ' testing a know background point to make transparent
  17. ''_PutImage , image&, 0 '
  18. ''Print "Paint test, press any... ": Sleep
  19. ''_PutImage , image&, 0 '
  20. ''Paint (10, 10), &HFFFFFFFF, &HFF000000 ' nope "turkey run.jpg" has no pure black border enclosing the image
  21. ''End
  22.  
  23. Dim mx, my, outRed, outGrn, outBlu, outAlp, x, y
  24.     Cls ' must clear screen to see what was cleared from image if anything
  25.     _PutImage , image&, 0 '
  26.     While _MouseInput: Wend ' poll mouse to show me where I am at
  27.     mx = _MouseX: my = _MouseY
  28.     Line (mx - 3, my - 3)-(mx + 3, my + 3), , B ' eraser block  black & white frame around eraser
  29.     Line (mx - 4, my - 4)-(mx + 4, my + 4), &HFF000000, B ' eraser block
  30.     cAnalysis Point(mx, my), outRed, outGrn, outBlu, outAlp
  31.     Locate 1, 1: Print Space$((_Width - 1) / 8)
  32.     Locate 1, 1: Print outRed; outGrn; outBlu; outAlp
  33.         For y = my - 2 To my + 2
  34.             For x = mx - 2 To mx + 2
  35.                 _ClearColor Point(x, y), image&
  36.             Next
  37.         Next
  38.     End If
  39.     _Display
  40.     _Limit 100
  41. Cls 'get rid of mouse stuff before save image
  42. _PutImage , image&, 0
  43.  
  44. 'Dim M As _MEM: M = _MemImage(Scn&)
  45. 'Screengrab$ = Space$(M.SIZE)
  46. '_MemGet M, M.OFFSET, Screengrab$
  47.  
  48. 'The above will:
  49. 'Dim a mem block.  Point it to your screen's image.
  50. 'Set a string that size.
  51. 'Get the whole screen at once into that string.
  52.  
  53.  
  54. 'Then to save to disk all at once:
  55. 'Open "Test SaveLoad Image.bin" For Binary As #1
  56. 'Put #1, , Screengrab$
  57. 'Close
  58. 'Open the file, put the data in one chunk, close the file.
  59.  
  60. ' hopefully the above has been encoded properly into a Sub
  61. SaveCustomImage Scn&, "Test Save Turkey Run"
  62.  
  63. Print "Press any to test load image again... "
  64.  
  65. 'Loading is the same, in reverse:
  66. 'Open "Test SaveLoad Image.bin" For Binary As #1
  67. 'Get #1, , Screengrab$
  68. 'Close
  69. 'And putting the data back to screen is also done all in one command:
  70. '_MemPut M, M.OFFSET, Screengrab$
  71.  
  72. 'And hopefully the LoadCustomImage& Function gets the data back from file
  73. Dim image2&: image2& = LoadCustomImage&("Test Save Turkey Run")
  74. _PutImage , image2&, 0 ' put back on screen
  75.  
  76. Sub cAnalysis (c As _Unsigned Long, outRed, outGrn, outBlu, outAlp)
  77.     outRed = _Red32(c): outGrn = _Green32(c): outBlu = _Blue32(c): outAlp = _Alpha32(c)
  78.  
  79. 'this will create 2 files for Custom Image:
  80. '1) FileName$ + "CI_DIM" for image dimensions
  81. '2) FileName$ + "CI" for the Custom Image data
  82. Sub SaveCustomImage (imgHdl&, fileSaveBaseName$) ' for any image setup by _newimage
  83.     Dim As Long w, h: w = _Width(imgHdl&): h = _Height(imgHdl&)
  84.     Dim M As _MEM: M = _MemImage(imgHdl&) 'Dim a mem block.  Point it to your screen's image.
  85.     Dim screenGrab$: screenGrab$ = Space$(M.SIZE) 'Set a string that size.
  86.     Dim compressed$
  87.     'screenGrab$ = _Deflate$(screenGrab$)
  88.     _MemGet M, M.OFFSET, screenGrab$ 'Get the whole screen at once into that string.
  89.     Open fileSaveBaseName$ + ".CI_DIM" For Output As #1
  90.     Print #1, w
  91.     Print #1, h
  92.     Close #1
  93.     Open fileSaveBaseName$ + ".CI" For Binary As #1
  94.     compressed$ = _Deflate$(screenGrab$)
  95.     Put #1, , screenGrab$
  96.     Close
  97.  
  98. ' Function returns Image Handle& (like _LoadFile)
  99. Function LoadCustomImage& (fileLoadBaseName$) ' reverse the Save
  100.     Dim As Long w, h
  101.     Open fileLoadBaseName$ + ".CI_DIM" For Input As #1 ' get dimensions of custom image
  102.     Dim compressed$
  103.     Input #1, w
  104.     Input #1, h
  105.     Close #1
  106.     Dim imgHdl&: imgHdl& = _NewImage(w, h, 32) 'setup space and handle for it
  107.     Dim M As _MEM: M = _MemImage(imgHdl&) ' put data into handle space reserved
  108.     Dim screenGrab$: screenGrab$ = Space$(M.SIZE)
  109.     Open fileLoadBaseName$ + ".CI" For Binary As #1 ' get data
  110.     'screenGrab$ = Space$(LOF(1))
  111.     compressed$ = Space$(LOF(1) - 8) 'You're not getting the whole length of your file -- you're getting what's left after the width and height are accounted for
  112.     Get #1, , compressed$
  113.     screenGrab$ = _Inflate$(compressed$)
  114.     Close #1
  115.     'screenGrab$ = _Inflate$(screenGrab$)  ' doesn't work
  116.     _MemPut M, M.OFFSET, screenGrab$
  117.     LoadCustomImage& = imgHdl& ' finally assign the function
  118.  

I was too lazy to supply an actual image for loading and testing, but everything looks proper to me with the above.  If it doesn't work, I'll be more thorough and see what the heck I did wrong with it, but I *think* the above is what you're looking for as far as compressing and decompressing the image file is concerned.



I think your basic problem was you forgot to account for your width and height offset in the file:

    'screenGrab$ = Space$(LOF(1))
    compressed$ = Space$(LOF(1) - 8) 'You're not getting the whole length of your file -- you're getting what's left after the width and height are accounted for
    Get #1, , compressed$
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« Reply #2 on: December 30, 2021, 03:53:31 pm »
Hi Steve,

Thanks but nope, didn't work, still blank in final test of load and show.

I did account for w x h of image in a separate file for creating a newImage handle with proper space.

But I save the compressed screenGrab$ string so when I load from Binary, I _inflate the string from Binary which should in my mind then be what it was before compressed and then ready to MemPut into _newImage handle created for that size.

Did you see that I saved the Width and Height of image in a different File .CI_DIM? This is so I could save just the pure image data in the .CI file. (CI is for Custom Image)

Update: For the record, Turkey Hunt will load the Edited image from your code With the supposedly compressed string with my code to load the image that assumes no compressed string!
« Last Edit: December 30, 2021, 04:09:19 pm by bplus »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« Reply #3 on: December 30, 2021, 04:11:52 pm »
I'm out for a pizza run into town ATM, but I'll dig into this with a fine tooth comb when I get home in a few hours and I'll post you an update later tonight.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« Reply #4 on: December 30, 2021, 04:15:16 pm »
Thanks, enjoy your pizza.

I'm trying Keto, tonight chicken thigh and buttered broccoli with bits of bacon and bacon grease, cashews for desert.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« Reply #5 on: December 30, 2021, 07:26:14 pm »
I'm embarassed to admit WHY what I posted didn't work for you.  By all rights, it *should* have, and yet, after actually loading an image and testing it, it didn't...

Here's why (feel free to GPL -- Giggle, Point, and Laugh) at me all you want):

    compressed$ = _Deflate$(screenGrab$)
    Put #1, , screenGrab$

Well, I compress my screen just peachy fine....
And then I promptly put the uncompressed information to file..... 

I also failed to notice that you'd decided to use 2 files for the images, so I wasn't even allocating the full space for the compressed data:

    compressed$ = Space$(LOF(1) - 8)

So, it's no wonder that the dang thing didn't decompress my uncompressed data, and then fail to work properly!

I can post the code with the relevant changes, if you need, but I thought you might want to go in and make them for yourself so you can see exactly where and why it doesn't work as I shared it.  Fix those little DUH-glitches, and it'll work and compress for you as it should.  ;)



Now, for my saving grace, I get to GPL at you for doing something just as bad:

    'screenGrab$ = _Deflate$(screenGrab$)
    _MemGet M, M.OFFSET, screenGrab$ 'Get the whole screen at once into that string.

Look at the order of those two statements as you have them written...

Let's compress our data, BEFORE we get it from the screen!!

Hang your head with me.  We'll both wear DUH-caps for a while this evening!  LOL!!
« Last Edit: December 30, 2021, 07:34:51 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« Reply #6 on: December 30, 2021, 07:51:42 pm »
Yep! That was quite blunderful of me.

@SMcNeill thanks so much for 2nd pair of eyes and straightening me out.  :)  << happy camper

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« Reply #7 on: December 31, 2021, 10:17:15 pm »
OK I was able to workup a satisfactory Edit of that Turkey Run image by building a Paint4 sub routine that paints around a given point if that point is "Near" in color to one specified. How near is near enough? You get to say how much RGB difference you will allow with Paint4's parameters ie Paint4 x, y, PaintColor, NearColor, 1-254

So I could turn this image:
 
turkey run snap.PNG


To this:
 
Turkey Run image fixed up by Edit Image with New Paint4.PNG


Without having to work through this:
 
Hard to clean up.PNG


Here the test code for Edit 2:
Code: QB64: [Select]
  1. _Title "Edit image test 2" 'b+ 2021-12-29 sure would like to take an image and the subject wo background colors
  2. ' from  C:\Users\marka\Desktop\QB64 work\000 work QB64\000 Test\More Saving Images
  3. ' file "Fast Image Save and Load.bas" by SMcNeill 2021-12-07
  4.  
  5. ' posted 2021-12-30 with question about _inflate, _deflate
  6. ' here: https://qb64forum.alephc.xyz/index.php?topic=4541.msg139518#msg139518
  7. ' fixed with _deflate, _inflate thanks SMcNeil!
  8.  
  9. ' "Edit image test 2" 2021-12-31 still working on that Turkey image I have created Paint4
  10. ' that should paint everything a color if it is near another color, hopefully this will
  11. ' eliminate all the light pixels around the border of the turkey.
  12. ' The turkey run image needs the print at the bottom blacked out or the image reframed smaller
  13. ' all the near white around the turkey made black so I cam use one _clearColor (black here).
  14.  
  15.  
  16. ''Scn& = _NewImage(800, 600, 32)  'should not need these 2 lines if loadimage with 32
  17. ''Screen Scn&
  18. Dim image&: image& = _LoadImage("turkey run.jpg", 32) ' <<<<<<<<<<<<<<<<< Edit Image file name
  19. 'Print image& ' OK -12   guess I forgot to save file before trying so in QB64 folder instead of project folder
  20. 'Sleep
  21.  
  22. Dim Scn&: Scn& = _NewImage(_Width(image&), _Height(image&), 32)
  23. Screen Scn&
  24. _Source image& ' for using Point from image
  25.  
  26. Dim mx, my, snap&
  27.  
  28. _Title "Escape finshes Blackout Then use Paint4"
  29. Cls ' must clear screen to see what was cleared from image if anything
  30. _PutImage , image&, 0 '
  31. snap& = _NewImage(_Width, _Height, 32)
  32. _PutImage , 0, snap&
  33.     _PutImage , snap&, 0
  34.     While _MouseInput: Wend ' poll mouse to show me where I am at
  35.     mx = _MouseX: my = _MouseY
  36.     Line (mx - 5, my - 5)-(mx + 5, my + 5), , B ' eraser block  black & white frame around eraser
  37.     Line (mx - 6, my - 6)-(mx + 6, my + 6), &HFF000000, B ' eraser block
  38.         _PutImage , snap&, 0 'clear mouse
  39.         Line (mx - 4, my - 4)-(mx + 4, my + 4), &HFF000000, BF
  40.         _Display
  41.         _PutImage , 0, snap& 'grab while mouse gone
  42.     End If
  43.     _Display
  44.     _Limit 100
  45. _Title "Spacebar finshes Paint4" ' Paint4 paints everything around a given point a color
  46. '                                  if the points around it are close to another given color
  47. '                                  How close is close? You get to say in an amount of RGB.
  48.     _PutImage , snap&, 0
  49.     While _MouseInput: Wend ' poll mouse to show me where I am at
  50.     mx = _MouseX: my = _MouseY
  51.     Circle (mx, my), 2, &HFFFFFFFF
  52.     Circle (mx, my), 3, &HFF000000
  53.         _PutImage , snap&, 0 'clear mouse
  54.         paint4 mx, my, _RGB32(0, 0, 0), _RGB32(245, 245, 245), 186
  55.         _Display
  56.         _PutImage , 0, snap& 'grab while mouse gone
  57.     End If
  58.     _Display
  59.     _Limit 100
  60. ' hopefully the above has been encoded properly into a Sub
  61. SaveCustomImage snap&, "Test Save Turkey Run"
  62. Print "Press any to test load image again... "
  63. 'And hopefully the LoadCustomImage& Function gets the data back from file
  64. Dim image2&: image2& = LoadCustomImage&("Test Save Turkey Run")
  65. _PutImage , image2&, 0 ' put back on screen
  66.  
  67.  
  68. 'this will create 2 files for Custom Image:
  69. '1) FileName$ + "CI_DIM" for image dimensions
  70. '2) FileName$ + "CI" for the Custom Image data
  71. Sub SaveCustomImage (imgHdl&, fileSaveBaseName$) ' for any image setup by _newimage
  72.     Dim As Long w, h: w = _Width(imgHdl&): h = _Height(imgHdl&)
  73.     Dim M As _MEM: M = _MemImage(imgHdl&) 'Dim a mem block.  Point it to your screen's image.
  74.     Dim screenGrab$: screenGrab$ = Space$(M.SIZE) 'Set a string that size.
  75.     _MemGet M, M.OFFSET, screenGrab$ 'Get the whole screen at once into that string.
  76.     screenGrab$ = _Deflate$(screenGrab$) ' << heh dummy put this after you get screen grab!
  77.     Open fileSaveBaseName$ + ".CI_DIM" For Output As #1
  78.     Print #1, w
  79.     Print #1, h
  80.     Close #1
  81.     Open fileSaveBaseName$ + ".CI" For Binary As #1
  82.     Put #1, , screenGrab$
  83.     Close
  84.  
  85. ' Function returns Image Handle& (like _LoadFile)
  86. Function LoadCustomImage& (fileLoadBaseName$) ' reverse the Save
  87.     Dim As Long w, h
  88.     Open fileLoadBaseName$ + ".CI_DIM" For Input As #1 ' get dimensions of custom image
  89.     Input #1, w
  90.     Input #1, h
  91.     Close #1
  92.     Dim imgHdl&: imgHdl& = _NewImage(w, h, 32) 'setup space and handle for it
  93.     Dim M As _MEM: M = _MemImage(imgHdl&) ' put data into handle space reserved
  94.     Dim screenGrab$: screenGrab$ = Space$(M.SIZE)
  95.     Open fileLoadBaseName$ + ".CI" For Binary As #1 ' get data
  96.     screenGrab$ = Space$(LOF(1))
  97.     Get #1, , screenGrab$
  98.     Close #1
  99.     screenGrab$ = _Inflate$(screenGrab$) ' fixed ?
  100.     _MemPut M, M.OFFSET, screenGrab$
  101.     LoadCustomImage& = imgHdl& ' finally assign the function
  102.  
  103. ' test Paint4 here
  104. ' this function needs:  Function IsNear& (colr As _Unsigned Long, nearColr As _Unsigned Long)
  105. ' this function needs:  Sub cAnalysis (c As _Unsigned Long, outRed, outGrn, outBlu, outAlp)
  106. ' this function needs:  Function min (n1, n2)
  107. ' this function needs:  Function max (n1, n2)
  108. Sub paint4 (x0, y0, PaintColor As _Unsigned Long, NearColor As _Unsigned Long, nearness As Long) ' needs max, min functions
  109.     Dim W, H, parentF, tick, ystart, ystop, xstart, xstop, x, y
  110.     If IsNear&(Point(x0, y0), NearColor, nearness) Then
  111.         PSet (x0, y0), PaintColor
  112.         W = _Width - 1: H = _Height - 1
  113.         Dim temp(W, H)
  114.         temp(x0, y0) = 1: parentF = 1
  115.         While parentF = 1
  116.             parentF = 0: tick = tick + 1
  117.             ystart = max(y0 - tick, 0): ystop = min(y0 + tick, H)
  118.             y = ystart
  119.             While y <= ystop
  120.                 xstart = max(x0 - tick, 0): xstop = min(x0 + tick, W)
  121.                 x = xstart
  122.                 While x <= xstop
  123.                     If (IsNear&(Point(x, y), NearColor, nearness) = -1) And (temp(x, y) = 0) Then
  124.                         If temp(max(0, x - 1), y) Then
  125.                             temp(x, y) = 1: parentF = 1: PSet (x, y), PaintColor
  126.                         ElseIf temp(min(x + 1, W), y) Then
  127.                             temp(x, y) = 1: parentF = 1: PSet (x, y), PaintColor
  128.                         ElseIf temp(x, max(y - 1, 0)) Then
  129.                             temp(x, y) = 1: parentF = 1: PSet (x, y), PaintColor
  130.                         ElseIf temp(x, min(y + 1, H)) Then
  131.                             temp(x, y) = 1: parentF = 1: PSet (x, y), PaintColor
  132.                         End If
  133.                     End If
  134.                     x = x + 1
  135.                 Wend
  136.                 y = y + 1
  137.             Wend
  138.         Wend
  139.     End If
  140.  
  141. Function min (n1, n2)
  142.     If n1 > n2 Then min = n2 Else min = n1
  143.  
  144. Function max (n1, n2)
  145.     If n1 < n2 Then max = n2 Else max = n1
  146.  
  147. Sub cAnalysis (c As _Unsigned Long, outRed As Long, outGrn As Long, outBlu As Long, outAlp As Long)
  148.     outRed = _Red32(c): outGrn = _Green32(c): outBlu = _Blue32(c): outAlp = _Alpha32(c)
  149.     'Print "cAnalysis says:"; outRed; outGrn; outBlu; outAlp
  150.  
  151. 'this function needs: cAnalysis (c As _Unsigned Long, outRed as long, outGrn as long, outBlu as long, outAlp as long)
  152. Function IsNear& (colr As _Unsigned Long, nearColr As _Unsigned Long, nearness As Long)
  153.     'try color +-5 on RGB as near
  154.     Dim As Long cRed, cGrn, cBlu, dummy, nRed, nGrn, nBlu
  155.     cAnalysis colr, cRed, cGrn, cBlu, dummy
  156.     'Print cRed, cGrn, cBlu
  157.     cAnalysis nearColr, nRed, nGrn, nBlu, dummy
  158.     'Print nRed, nGrn, nBlu
  159.     If Abs(cRed - nRed) <= nearness Then
  160.         If Abs(cGrn - nGrn) <= nearness Then
  161.             If Abs(cBlu - nBlu) <= nearness Then IsNear& = -1
  162.         End If
  163.     End If

For the Turkey Run image found in the above OP zip, I had to Black the writing at the bottom then click white points to Black out, there are a couple of inner light colored island that need clicking to paint Black too.

The point of all this is to have just one color to _ClearColor when load image into app.

My next Edit Image version will allow reframing the image so the Blackout of text show here wont be necessary.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« Reply #8 on: December 31, 2021, 11:29:37 pm »
Code: QB64: [Select]
  1. Sub paint4 (x0, y0, PaintColor As _Unsigned Long, NearColor As _Unsigned Long, nearness As Long)

Here is another image I managed to isolate with Edit Image 2 but took a little tweaking to get the NearColor, nearness numbers optimized. Flying in a blue sky I settled on:
Code: QB64: [Select]
  1. paint4 mx, my, _RGB32(0, 128, 0), _RGB32(175, 175, 200), 56

 
Test Wild Turkey.PNG

As shown in the Turkey Hunt Game with the green _ClearColor'd

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« Reply #9 on: January 01, 2022, 08:47:17 am »
Hi @bplus,

Only now have I looked into this thread. I use this solution to remove artifacts (but it's not as effective as your Super Paint 4), this is definitely a great topic and a useful thing to do. You will need SaveImage to try it out.

My procedure for using this utility: Scan an image. Then save it as a PNG. Then run it through this program (after reducing it to the required size). Left-click on the color you want to remove. What does not redraw it can be marked with the left mouse button. The output creates a GIF file that contains a yellow background. This is then removed in the program using _CLEARCOLOR
 &HFFFFFF00, handle &.

There's also room for improvement, such as running SUB SP as many times as you look for color (so when you clean an image from RGB32(255)  to RGB32(235) so 20 times and not just once, as it is now).

Code: QB64: [Select]
  1. '$include:'saveimage.bi'
  2. Input "Insert File Name:"; File$
  3. img = _LoadImage(File$, 32)
  4. Dim As _MEM m, n
  5. newimg = _NewImage(_Width(img), _Height(img), 32)
  6. Dim As _Unsigned _Byte R, G, B, A
  7. Dim As Long Counter
  8. m = _MemImage(img)
  9. n = _MemImage(newimg)
  10. Do Until Counter = m.SIZE - 4
  11.     _MemGet m, m.OFFSET + Counter, B
  12.     _MemGet m, m.OFFSET + Counter + 1, G
  13.     _MemGet m, m.OFFSET + Counter + 2, R
  14.     _MemGet m, m.OFFSET + Counter + 3, A
  15.  
  16.     D = 245
  17.     ND = 255
  18.     If R > D And G > D And B > D Then R = ND: G = ND: B = ND
  19.     _MemPut n, n.OFFSET + Counter, B
  20.     _MemPut n, n.OFFSET + Counter + 1, G
  21.     _MemPut n, n.OFFSET + Counter + 2, R
  22.     _MemPut n, n.OFFSET + Counter + 3, A
  23.     Counter = Counter + 4
  24.  
  25.  
  26. Screen newimg
  27.  
  28. Do Until k& = 27
  29.     k& = _KeyHit
  30.     GetMouse X, Y, LB, RB
  31.     If LB Then sp X, Y, &HFFFFFF00
  32.  
  33. nfile$ = "NEW " + Left$(File$, Len(File$) - 4) + ".gif"
  34. Result = SaveImage(nfile$, 0, 0, 0, _Width - 1, _Height - 1)
  35.  
  36. Sub sp (x, y, c~&)
  37.     W = _Width: H = _Height
  38.     Virtual = _NewImage(W, H, 32)
  39.  
  40.     Dim m As _MEM, n As _MEM, Bck As _Unsigned Long
  41.     m = _MemImage(_Source)
  42.     n = _MemImage(Virtual)
  43.  
  44.     'create mask (2 color image)
  45.     position& = (y * W + x) * 4
  46.     _MemGet m, m.OFFSET + position&, Bck
  47.     Clr2~& = _RGB32(_Red32(Bck) - 1, _Green32(Bck) - 1, _Blue32(Bck) - 1)
  48.     D& = 0
  49.     Do Until D& = n.SIZE
  50.         CLR~& = _MemGet(m, m.OFFSET + D&, _Unsigned Long)
  51.         If CLR~& = Bck~& Then _MemPut n, n.OFFSET + D&, CLR~& Else _MemPut n, n.OFFSET + D&, Clr2~&
  52.         D& = D& + 4
  53.     Loop
  54.  
  55.     d = _Dest
  56.     _Dest Virtual
  57.     Paint (x, y), c~&, Clr2~&
  58.     _Dest d
  59.     _ClearColor Clr2~&, Virtual
  60.     _PutImage , Virtual, d
  61.     _MemFree m
  62.     _MemFree n
  63.     _FreeImage Virtual
  64.  
  65. Sub ValC (variable, min, max)
  66.     If variable < min Then variable = min
  67.     If variable > max Then variable = max
  68.  
  69. Sub GetMouse (MX, MY, LB, RB)
  70.     MX = _MouseX
  71.     MY = _MouseY
  72.     LB = _MouseButton(1)
  73.     RB = _MouseButton(2)
  74. '$include:'saveimage.bm'
  75.  

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« Reply #10 on: January 01, 2022, 10:40:22 am »
Hi @Petr

Glad you see the value of what I am attempting. In your code, what does "sp" for sp sub stand for? Possibly Special Paint? I see allot of mem manipulations so will take me awhile to study. But if it is about removing colors or changing a color, I have that maybe using memory too from @Qwerkey, Pi in the Sky (still a great graphics demo IMHO) if only for changing a color in an image.

I do like this sub already!
Code: QB64: [Select]
  1. Sub ValC (variable, min, max)
  2.     If variable < min Then variable = min
  3.     If variable > max Then variable = max

I think we could change it into a function and be rid of my two Max, Min functions.

Coming up:
I am considering adding the color intended to be made transparent when loading a .CI (Custom Image file) ie
in .CI_DIM file (so handy to have image Width and Height for reading independent of .CI data) the simple File input listing will be:
 Width
 Height
 Color intended to be made transparent

I am hoping I can do this in the sub while loading the CI data and not have to tell the app using the loading sub to read the color to make _ClearColor for the Handle& returned from the loading sub, this may make loading a CI image a little more handy than _LoadImage.

So now that's 2 changes for Edit Image 3, cropping and handling _ClearColor Plus start a more formal editor with buttons and menus so there will be a screen work space for image and controls for manipulating...

Here we go:
Code: QB64: [Select]
  1. _Title "Between Function test" 'b+ 2022-01-01 (first function written this year!
  2. For i = 0 To 20
  3.     Print i; Between&(5, 15, i)
  4.  
  5. Function Between& (min, max, variable) ' since this is a function we dont have to worry about changing a variable value
  6.     If variable < min Then
  7.         Between& = min
  8.     ElseIf variable > max Then
  9.         Between& = max
  10.     Else
  11.         Between& = variable
  12.     End If
  13.  

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« Reply #11 on: January 01, 2022, 02:18:41 pm »
@bplus

To line 25 there is a solution for all pixels close to the value D to be overwritten to the value ND. Basically it's the same as this https://qb64forum.alephc.xyz/index.php?topic=4432.msg138555#msg138555

SP is an abbreviated name for the sub SuperPaint, its original purpose is to color the image no matter what colored borders delimit the colored area.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« Reply #12 on: January 01, 2022, 02:44:01 pm »
@bplus

To line 25 there is a solution for all pixels close to the value D to be overwritten to the value ND. Basically it's the same as this https://qb64forum.alephc.xyz/index.php?topic=4432.msg138555#msg138555

SP is an abbreviated name for the sub SuperPaint, its original purpose is to color the image no matter what colored borders delimit the colored area.

SP, I was close :)

The link is just color changing everything in an image (or rect area of it).

My solution paints until nothing paintable in an area around a point click, so say I am painting everything close to white eg in turkey run image but I don't want to paint white eye parts or white teeth part, Paint4 leaves them alone (unless I click those areas) because those areas are surrounded by dark colors, so Paint4 wont fill to those points. Maybe you got that already (but then why are you showing the link?), as I said I already have nice color changing code.

The Wild Turkey was painted green all around with one click once I got the numbers tweaked. Could still be shades of blue sky mixed in with those feathers.

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« Reply #13 on: January 02, 2022, 01:31:04 pm »
if it is about removing colors or changing a color, I have that maybe using memory too from @Qwerkey, Pi in the Sky (still a great graphics demo IMHO) if only for changing a color in an image.

@bplus You were always too kind about Pi-in-the-Sky.  It certainly had a certain degree of quirkiness, but all members have that individual creativity.  Thank you, again!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« Reply #14 on: January 09, 2022, 03:14:44 pm »
I tried to speed up the original BPlus program (mainly because it returns perfect results). Here is my edit. I pulled it out of the original 16.26 seconds to 8.78 seconds.

Interestingly, if you enter the color with the mouse in the left third of the image, it is even three seconds faster. But I don't see the reason.



So to put it bluntly ... I have a my new picture in my profile rightly ... I had a badly set start time measurement, so the acceleration is there, but only about 30 - 40 percent.

Code: QB64: [Select]
  1.  
  2. _Title "Edit image test 2" 'b+ 2021-12-29 sure would like to take an image and the subject wo background colors
  3. ' from  C:\Users\marka\Desktop\QB64 work\000 work QB64\000 Test\More Saving Images
  4. ' file "Fast Image Save and Load.bas" by SMcNeill 2021-12-07
  5.  
  6. ' posted 2021-12-30 with question about _inflate, _deflate
  7. ' here: https://qb64forum.alephc.xyz/index.php?topic=4541.msg139518#msg139518
  8. ' fixed with _deflate, _inflate thanks SMcNeil!
  9.  
  10. ' "Edit image test 2" 2021-12-31 still working on that Turkey image I have created Paint4
  11. ' that should paint everything a color if it is near another color, hopefully this will
  12. ' eliminate all the light pixels around the border of the turkey.
  13. ' The turkey run image needs the print at the bottom blacked out or the image reframed smaller
  14. ' all the near white around the turkey made black so I cam use one _clearColor (black here).
  15.  
  16.  
  17. ''Scn& = _NewImage(800, 600, 32)  'should not need these 2 lines if loadimage with 32
  18. ''Screen Scn&
  19. Dim image&: image& = _LoadImage("turkey run snap.png", 32) ' <<<<<<<<<<<<<<<<< Edit Image file name
  20. 'Print image& ' OK -12   guess I forgot to save file before trying so in QB64 folder instead of project folder
  21. 'Sleep
  22.  
  23. 'Petr's speed up attempt:
  24. '16.26 seconds original, now 8.78 seconds, on left side 4.87 seconds!
  25.  
  26. Dim Scn&: Scn& = _NewImage(_Width(image&), _Height(image&), 32)
  27. 'Dim Shared Temp(_Width(image&) - 1, _Height(image&) - 1)
  28. Dim Shared As _Unsigned _Byte NRed, NGreen, NBlue
  29. Type RGB
  30.     As _Unsigned _Byte R, G, B
  31. Dim Shared RGB(_Width(image&) * _Height(image&)) As RGB
  32.  
  33. Screen Scn&
  34. _Source image& ' for using Point from image
  35.  
  36. Dim mx, my, snap&
  37.  
  38. _Title "Escape finshes Blackout Then use Paint4"
  39. Cls ' must clear screen to see what was cleared from image if anything
  40. _PutImage , image&, 0 '
  41. snap& = _NewImage(_Width, _Height, 32)
  42. _PutImage , 0, snap&
  43.     _PutImage , snap&, 0
  44.     While _MouseInput: Wend ' poll mouse to show me where I am at
  45.     mx = _MouseX: my = _MouseY
  46.     Line (mx - 5, my - 5)-(mx + 5, my + 5), , B ' eraser block  black & white frame around eraser
  47.     Line (mx - 6, my - 6)-(mx + 6, my + 6), &HFF000000, B ' eraser block
  48.         _PutImage , snap&, 0 'clear mouse
  49.         Line (mx - 4, my - 4)-(mx + 4, my + 4), &HFF000000, BF
  50.         _Display
  51.         _PutImage , 0, snap& 'grab while mouse gone
  52.     End If
  53.     _Display
  54.     _Limit 100
  55. _Title "Spacebar finishes Paint4" ' Paint4 paints everything around a given point a color
  56. '                                  if the points around it are close to another given color
  57. '                                  How close is close? You get to say in an amount of RGB.
  58.     _PutImage , snap&, 0
  59.     While _MouseInput: Wend ' poll mouse to show me where I am at
  60.     mx = _MouseX: my = _MouseY
  61.     Circle (mx, my), 2, &HFFFFFFFF
  62.     Circle (mx, my), 3, &HFF000000
  63.      T = Timer  
  64.     _PutImage , snap&, 0 'clear mouse
  65.         paint4 mx, my, _RGB32(0, 0, 0), _RGB32(245, 245, 245), 186
  66.         _Display
  67.         _PutImage , 0, snap& 'grab while mouse gone
  68.         If oTimer = 0 Then oTimer = Timer
  69.     End If
  70.  
  71.     If oTimer Then Print oTimer - T
  72.     _Display
  73.     _Limit 100
  74. ' hopefully the above has been encoded properly into a Sub
  75. SaveCustomImage snap&, "Test Save Turkey Run"
  76. Print "Press any to test load image again... "
  77. 'And hopefully the LoadCustomImage& Function gets the data back from file
  78. Dim image2&: image2& = LoadCustomImage&("Test Save Turkey Run")
  79. _PutImage , image2&, 0 ' put back on screen
  80.  
  81.  
  82. 'this will create 2 files for Custom Image:
  83. '1) FileName$ + "CI_DIM" for image dimensions
  84. '2) FileName$ + "CI" for the Custom Image data
  85. Sub SaveCustomImage (imgHdl&, fileSaveBaseName$) ' for any image setup by _newimage
  86.     Dim As Long w, h: w = _Width(imgHdl&): h = _Height(imgHdl&)
  87.     Dim M As _MEM: M = _MemImage(imgHdl&) 'Dim a mem block.  Point it to your screen's image.
  88.     Dim screenGrab$: screenGrab$ = Space$(M.SIZE) 'Set a string that size.
  89.     _MemGet M, M.OFFSET, screenGrab$ 'Get the whole screen at once into that string.
  90.     screenGrab$ = _Deflate$(screenGrab$) ' << heh dummy put this after you get screen grab!
  91.     Open fileSaveBaseName$ + ".CI_DIM" For Output As #1
  92.     Print #1, w
  93.     Print #1, h
  94.     Close #1
  95.     Open fileSaveBaseName$ + ".CI" For Binary As #1
  96.     Put #1, , screenGrab$
  97.     Close
  98.  
  99. ' Function returns Image Handle& (like _LoadFile)
  100. Function LoadCustomImage& (fileLoadBaseName$) ' reverse the Save
  101.     Dim As Long w, h
  102.     Open fileLoadBaseName$ + ".CI_DIM" For Input As #1 ' get dimensions of custom image
  103.     Input #1, w
  104.     Input #1, h
  105.     Close #1
  106.     Dim imgHdl&: imgHdl& = _NewImage(w, h, 32) 'setup space and handle for it
  107.     Dim M As _MEM: M = _MemImage(imgHdl&) ' put data into handle space reserved
  108.     Dim screenGrab$: screenGrab$ = Space$(M.SIZE)
  109.     Open fileLoadBaseName$ + ".CI" For Binary As #1 ' get data
  110.     screenGrab$ = Space$(LOF(1))
  111.     Get #1, , screenGrab$
  112.     Close #1
  113.     screenGrab$ = _Inflate$(screenGrab$) ' fixed ?
  114.     _MemPut M, M.OFFSET, screenGrab$
  115.     LoadCustomImage& = imgHdl& ' finally assign the function
  116.  
  117. ' test Paint4 here
  118. ' this function needs:  Function IsNear2& (color offset, nearColr As _Unsigned Long, nearness)
  119. ' this function needs:  Function min (n1, n2)
  120. ' this function needs:  Function max (n1, n2)
  121. Sub paint4 (x0, y0, PaintColor As _Unsigned Long, NearColor As _Unsigned Long, nearness As _Unsigned _Byte) ' needs max, min functions
  122.     Dim oW, W, H, parentF, tick, ystart, ystop, xstart, xstop, x, y As _Unsigned Integer
  123.     Dim m As _MEM
  124.     m = _MemImage(_Dest)
  125.     oW = _Width
  126.     'new color global shared values
  127.     NRed = _Red32(NearColor)
  128.     NGreen = _Green32(NearColor)
  129.     NBlue = _Blue32(NearColor)
  130.     'save all points in image to global shared array in format .R, .G, .B
  131.     Do Until clrs& = m.SIZE
  132.         RGB(i).B = _MemGet(m, m.OFFSET + clrs&, _Unsigned _Byte)
  133.         RGB(i).G = _MemGet(m, m.OFFSET + clrs& + 1, _Unsigned _Byte)
  134.         RGB(i).R = _MemGet(m, m.OFFSET + clrs& + 2, _Unsigned _Byte)
  135.         '+3 = alpha
  136.         clrs& = clrs& + 4
  137.         i = i + 1
  138.     Loop
  139.  
  140.     If IsNear2((y0 * oW + x0), NearColor, nearness) Then
  141.         _MemPut m, m.OFFSET + (y0 * oW + x0) * 4, PaintColor ' PSet (x, y), PaintColor
  142.         W = _Width - 1: H = _Height - 1
  143.         Dim Temp(W, H)
  144.         Temp(x0, y0) = 1: parentF = 1
  145.         While parentF = 1
  146.             parentF = 0: tick = tick + 1
  147.             ystart = max(y0 - tick, 0): ystop = min(y0 + tick, H)
  148.             y = ystart
  149.             While y <= ystop
  150.                 xstart = max(x0 - tick, 0): xstop = min(x0 + tick, W)
  151.                 x = xstart
  152.                 While x <= xstop
  153.                     ' If (IsNear&(Point(x, y), NearColor, nearness) = -1) And (temp(x, y) = 0) Then
  154.                     If (IsNear2((y * oW + x), NearColor, nearness) = 1) And (Temp(x, y) = 0) Then
  155.                         If Temp(max(0, x - 1), y) Then
  156.                             Temp(x, y) = 1: parentF = 1: _MemPut m, m.OFFSET + (y * oW + x) * 4, PaintColor 'PSet (x, y), PaintColor
  157.                         ElseIf Temp(min(x + 1, W), y) Then
  158.                             Temp(x, y) = 1: parentF = 1: _MemPut m, m.OFFSET + (y * oW + x) * 4, PaintColor 'PSet (x, y), PaintColor
  159.                         ElseIf Temp(x, max(y - 1, 0)) Then
  160.                             Temp(x, y) = 1: parentF = 1: _MemPut m, m.OFFSET + (y * oW + x) * 4, PaintColor ' PSet (x, y), PaintColor
  161.                         ElseIf Temp(x, min(y + 1, H)) Then
  162.                             Temp(x, y) = 1: parentF = 1: _MemPut m, m.OFFSET + (y * oW + x) * 4, PaintColor 'PSet (x, y), PaintColor
  163.                         End If
  164.                     End If
  165.                     x = x + 1
  166.                 Wend
  167.                 y = y + 1
  168.             Wend
  169.         Wend
  170.     End If
  171.     _MemFree m
  172.  
  173. Function min~% (n1, n2)
  174.     If n1 > n2 Then min = n2 Else min = n1
  175.  
  176. Function max~% (n1, n2)
  177.     If n1 < n2 Then max = n2 Else max = n1
  178.  
  179. Function IsNear2~% (colr As _Unsigned Long, nearColr As _Unsigned Long, nearness As _Unsigned _Byte) 'cAnalysis is not need
  180.     If Abs(RGB(colr).R - NRed) <= nearness Then
  181.         If Abs(RGB(colr).G - NGreen) <= nearness Then
  182.             If Abs(RGB(colr).B - NBlue) <= nearness Then IsNear2~% = 1
  183.         End If
  184.     End If
  185.  
« Last Edit: January 09, 2022, 03:38:26 pm by Petr »