Author Topic: Paint Image  (Read 12006 times)

0 Members and 1 Guest are viewing this topic.

This topic contains a post which is marked as Best Answer. Press here if you would like to see it.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Paint Image
« on: November 14, 2019, 12:20:38 am »
Turned out pretty easy!
Code: QB64: [Select]
  1. SUB paintImage (x, y, Border~&, destHandle&, imageHandle&)
  2.     _DEST destHandle&
  3.     PAINT (x, y), _RGB32(119, 24, 49), Border~&
  4.     FOR y = 0 TO _HEIGHT(destHandle&)
  5.         FOR x = 0 TO _WIDTH(destHandle&)
  6.             _SOURCE destHandle&
  7.             IF POINT(x, y) = _RGB32(119, 24, 49) THEN
  8.                 _SOURCE imageHandle&
  9.                 PSET (x, y), POINT(x MOD _WIDTH(imageHandle&), y MOD _HEIGHT(imageHandle&))
  10.             END IF
  11.         NEXT
  12.     NEXT
  13.  

Attached is demo code for these:
 
Paint Image test 2.PNG

 
Paint Image test 1.PNG

* Paint Image pkg.zip (Filesize: 70.55 KB, Downloads: 182)

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Paint Image
« Reply #1 on: November 14, 2019, 11:10:27 am »
Nice work, BPlus. Next method is with virtual screens and transparency + _PUTIMAGE.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Paint Image
« Reply #2 on: November 14, 2019, 11:43:04 am »
Nice work, BPlus. Next method is with virtual screens and transparency + _PUTIMAGE.

Thanks Petr, looks like you want to go beyond bricks ;)

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Paint Image
« Reply #3 on: November 14, 2019, 11:45:37 am »
I am pleased, that you know, where I use it :)

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Paint Image
« Reply #4 on: November 14, 2019, 11:46:39 am »
Incredible graphics, but I have no idea how you did that. LOL

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Paint Image
« Reply #5 on: November 14, 2019, 11:51:24 am »
I just tried it and got an Invalid Handle on Line 79. But you got some awesome code there. Reminds me of how I used POINT to make text larger. I wonder if it's because I put all the files in their own directory?
« Last Edit: November 14, 2019, 11:55:36 am by SierraKen »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Paint Image
« Reply #6 on: November 14, 2019, 11:59:15 am »
I just tried it and got an Invalid Handle on Line 79. But you got some awesome code there. Reminds me of how I used POINT to make text larger. I wonder if it's because I put all the files in their own directory?

Sounds like the image file didn't load which most likely cause is that under the Run menu of IDE > there is no bullet next to "Output EXE to Source Folder" so when you compiled the program the exe went to QB64 folder instead of the download folder with the image files.

And yes I did use that trick for blowing up text for the "B+" graphic part. ;) I have made a sub of that so I can print sized text anywhere, probably should have used it :D
« Last Edit: November 14, 2019, 12:02:21 pm by bplus »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Paint Image
« Reply #7 on: November 14, 2019, 12:00:50 pm »
Oh, deleted, my faul.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Paint Image
« Reply #8 on: November 14, 2019, 01:23:08 pm »
Yep bplus, that was the problem lol. Man that's amazing stuff, good job!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Paint Image
« Reply #9 on: November 14, 2019, 04:58:54 pm »
A few points here (as I happily steal and repurpose this code for my own demo)...

_RGB32(119, 24, 49) —>  Just make these _RGB commands (no 32), and you can use this in other screen modes (like SCREEN 12 or 256-color mode).  Only thing to watch for is if the fill color is used elsewhere in the program.  In 32-bit mode, that _RGB color isn’t very likely to be used previously (a simple generation of a random color, and a check to make certain it’s not in use could eliminate all “paint bleeds”), but as we reduce our color palette smaller, it’s more likely to fill wrong areas...

I haven’t looked at Petr’s fill routine yet, but it might work better in lower colors modes, without the worry of bad fills.  I’ll need to check it out later.  ;)

Point 2: Get _DEST and _SOURCE at the start of the sub, and then restore them at exit time, if you want the routine to be more portable.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Marked as best answer by bplus on November 14, 2019, 02:26:13 pm

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Paint Image
« Reply #10 on: November 14, 2019, 05:07:01 pm »
A few points here (as I happily steal and repurpose this code for my own demo)...

_RGB32(119, 24, 49) —>  Just make these _RGB commands (no 32), and you can use this in other screen modes (like SCREEN 12 or 256-color mode).  Only thing to watch for is if the fill color is used elsewhere in the program.  In 32-bit mode, that _RGB color isn’t very likely to be used previously (a simple generation of a random color, and a check to make certain it’s not in use could eliminate all “paint bleeds”), but as we reduce our color palette smaller, it’s more likely to fill wrong areas...

I haven’t looked at Petr’s fill routine yet, but it might work better in lower colors modes, without the worry of bad fills.  I’ll need to check it out later.  ;)

Point 2: Get _DEST and _SOURCE at the start of the sub, and then restore them at exit time, if you want the routine to be more portable.  ;)

Thanks Steve, I was just going to post your improvement:
Code: QB64: [Select]
  1. SUB paintImage (x, y, Border~&, destHandle&, imageHandle&)
  2.     d = _DEST: s = _SOURCE
  3.     _DEST destHandle&
  4.     PAINT (x, y), _RGB(119, 24, 49), Border~&
  5.     FOR y = 0 TO _HEIGHT(destHandle&)
  6.         FOR x = 0 TO _WIDTH(destHandle&)
  7.             _SOURCE destHandle&
  8.             IF POINT(x, y) = _RGB(119, 24, 49) THEN
  9.                 _SOURCE imageHandle&
  10.                 PSET (x, y), POINT(x MOD _WIDTH(imageHandle&), y MOD _HEIGHT(imageHandle&))
  11.             END IF
  12.         NEXT
  13.     NEXT
  14.     _DEST d: _SOURCE s
  15.  
I caught the saving and restoring _SOURCE and _DEST but missed the _RGB switch, dropping 32.

Update: Just checked Steve's improvements with the demo test code and ran fine, so that makes this version the best so far.
« Last Edit: November 14, 2019, 07:25:42 pm by bplus »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Paint Image
« Reply #11 on: November 15, 2019, 09:39:52 am »
And from that, what you write, BPlus and Steve, it shows an option for MEM and a feature that quickly finds an unused combination of RGB colors to prevent malfunction :-)

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Paint Image
« Reply #12 on: November 15, 2019, 10:46:16 am »
Here's a version of your paint image routine which I think would probably be "image bleed" proof:

Code: QB64: [Select]
  1. SUB paintImage (x, y, Border~&, destHandle&, imageHandle&)
  2.     DIM d AS INTEGER, s AS INTEGER
  3.     DIM w AS INTEGER, h AS INTEGER
  4.     DIM im1 AS INTEGER, im2 AS INTEGER
  5.     d = _DEST: s = _SOURCE
  6.     w = _WIDTH(destHandle&): h = _HEIGHT(destHandle&)
  7.     c1 = _RGB(119, 24, 49): c2 = _RGB(124, 49, 119)
  8.     im1 = _COPYIMAGE(destHandle&): im2 = _COPYIMAGE(destHandle&)
  9.  
  10.     _DEST im1: PAINT (x, y), c1, Border~& 'paint one background one color
  11.     _DEST im2: PAINT (x, y), c2, Border~& 'paint a second background a different color
  12.     _DEST destHandle&
  13.     w = _WIDTH(imageHandle&): h = _HEIGHT(imageHandle&)
  14.     FOR y = 0 TO _HEIGHT(destHandle&)
  15.         FOR x = 0 TO _WIDTH(destHandle&)
  16.             _SOURCE im1: p1 = POINT(x, y) 'check for proper color on one background
  17.             _SOURCE im2: p2 = POINT(x, y) 'check for proper color on second background
  18.             IF p1 = c1 AND p2 = c2 THEN 'if both our backgrounds match the expected colors then
  19.                 _SOURCE imageHandle&
  20.                 PSET (x, y), POINT(x MOD w, y MOD h) 'paint the destination with our image
  21.             END IF
  22.         NEXT
  23.     NEXT
  24.     _DEST d: _SOURCE s
  25.     _FREEIMAGE im1 'free the two temp images
  26.     _FREEIMAGE im2 'free the two temp images

Instead of painting the background of our original destination _RGB(119, 24, 29), we instead make a copy of the background and paint that copy.  Then, for error checking, we take a second copy of the original background, and paint it a second color...

Only in areas where those two changes overlap, do we actually paint our image onto the original background.

The end result works so that if our whole screen was _RGB(119, 24, 29) to begin with, we'd still only paint in the desired area, and not paint our pattern across the whole screen.  It's going to be a lot slower than what you had originally (we're copying and freeing images, painting three times in total, and getting point values from multiple screens for comparisons), but it's going to be more reliable if we're working on screens with a reduced color palette (like the SCREEN 12 which I was using for paint fill elsewhere).

It's a tradeoff of speed for safety, and I wouldn't want to use this version as a fill routine inside a game loop (I imagine your FPS would drop considerably), but it'd work nice as a simple routine to plug in and use to fill an area once, so you can use it for something else in your code elsewhere.  ;)
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: Paint Image
« Reply #13 on: November 15, 2019, 11:28:08 am »
Hi Steve,

Frankly my dear, I don't give a damn about SCREEN 12 mode. ;-))

Why in the wide world would you willingly and wistfully waste wonderful color options in graphics 32 for 16 colors? 0 alpha!?!? And further, be restricted in screen size to one.

If an image happens to "bleed" in a point or two, that actually might create a really cool effect, but a the sub does need a proper warning not to use the one off color allot or change the PAINT color to different if need to use _RGB(119, 24, 49)

BTW I was disappointed to learn that POINT does not recognize &H color constants, I had to switch code to _RGB32 colors in my testing of the SUB. To me, that is a bigger problem with this sub for 32 bit graphics users.

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Paint Image
« Reply #14 on: November 15, 2019, 11:29:16 am »
Thank you Steve. I started writing a function that returns the number of the first unused color in the image (or -1 if there is no free color). This resulted in my question on flashing colors in text mode. If I have a function that returns a free color number, I will ensure correct operation for both the BPlus and my image fill methods, that also use PAINT; So both methods require using an free (in image unused) color.
« Last Edit: November 15, 2019, 11:32:19 am by Petr »