'This program took on a life of its own starting from a basic mouse
'drawing program to then saving it as its own type of data file to
'then BMP pictures and now JPG pictures.
'Then other things were added such as rays, orbits, paint fill ins,
'boxes, printer support, Windows color picker, and editing.
'This program was made using QB64 and will always be Freeware.
'Paint PIxels was made by Kenneth Green with some help from
'the QB64 website Wiki pages.
'I want to thank the people who made and take care of the QB64 website
'and computer language. I have wanted to make a program like this for
'a very long time.
'It took 1 week to make this program and finished on June 5, 2019.
'Feel free to use any of its code below for your own creations but
'please don't copy more than half of it and sell it. Thank you.
'Just remember, there are much better graphics programs out there
'that can do much more than this can, but to me this is my pride and joy.
'One big thing I like a lot about this program is that it uses the
'entire computer screen to draw with. Also remember, I am no professional,
'just a guy who has loved BASIC programming for over 30 years.
'
'Technical Notes:
'This program uses around 55 MB RAM and 1% of the CPU on my semi-new computer.
'Use at your own risk. I hold no responsibility for any problems whatsoever.
'Here is the code needed for the Color Picker. The Function code
'is also at the end of this program.
CONST CC_RGBINIT
= &H1&
' Sets the initial color (don't know how to set it) CONST CC_FULLOPEN
= &H2&
' Opens all dialog sections such as the custom color selector CONST CC_PREVENTFULLOPEN
= &H4&
' Prevents the user from opening the custom color selector CONST CC_SHOWHELP
= &H8&
' Shows the help button (USELESS!) '----------------------------------------------------------------------------------------
'TYPE COLORDIALOGTYPE
' lStructSize AS LONG ' Length of this TYPE structure
' hwndOwner AS LONG 'Dialog owner's handle
' hInstance AS LONG ' ?
' rgbResult AS LONG ' The RGB color the user selected
' lpCustColors AS _OFFSET ' Pointer to an array of 16 custom colors (will be changed by user)
' flags AS LONG ' Dialog flags
' lCustData AS LONG ' Custom data
' lpfnHook AS LONG ' Hook
' lpTemplateName AS _OFFSET ' Custom template
'END TYPE
start:
PRINT "This is a little program that you" PRINT "can draw using your mouse and" PRINT "save the picture and load it." PRINT "You also can make lines (Rays)," PRINT "circles (Orbits), and fill in the" PRINT "same color. You also can print to" PRINT "your USB printer as well as edit" PRINT "an old picture file." PRINT "It saves under .jpg files which can" PRINT "be used with most other programs." PRINT "Press the Space Bar to" PRINT "skip instructions." PRINT "Press Esc to end program." PRINT "Press any other key to continue." gggo:
PRINT "(S)ave (L)oad (H)ome" PRINT "(R)ay coordinates for line." PRINT "Press R once to start line" PRINT "and again to finish it." PRINT "(O)rbit coordinates for circles." PRINT "Press O once to start circle." PRINT "and again to finish it." PRINT "The size of the circle depends" PRINT "on the length difference" PRINT "between where you pressed O" PRINT "both times. The center of the circle" PRINT "will be the first place you pressed O." PRINT "(P)rints the picture on" PRINT "your printer. It will not work" PRINT "if you choose a black background" PRINT "because of heavy ink or toner use." PRINT "To go around that, choose a white" PRINT "background and on the color picker" PRINT "window, choose black and press F" PRINT "to fill entire window." PRINT "The paper printed outcome will NOT" PRINT "be proportionate to the screen." PRINT "Esc to end program." PRINT "Space Bar clears the screen." PRINT "Left Mouse Button draws." PRINT "Right Mouse Button erases." PRINT "There is no Undo feature on" PRINT "Press Esc to end program or" PRINT "any other key to continue." ggggo:
PRINT " Instructions Page 2" PRINT "(C)olor changes colors." PRINT "A window will popup to use" PRINT "your mouse to choose a color." PRINT "This will also happen when you" PRINT "first start your painting." PRINT "(F)ill fills in a color between" PRINT "the lines of the same color only." PRINT "Also close any gaps or it will" PRINT "fill the whole screen." PRINT "(B)oxes makes a box." PRINT "First press B once to start the" PRINT "box corner, then press B again" PRINT "to set the 2nd corner and size" PRINT "diagonally from the first one." PRINT "Paint slowly to leave out gaps." PRINT "When you press S to save," PRINT "the program will create a temp.jpg" PRINT "of the screen and when asking you" PRINT "for a file name, it will rename temp.jpg" PRINT "to your chosen name." PRINT "Press Esc to end program or" PRINT "any other key to start." gggggo:
start2:
begin = 1
PRINT "Or Esc to end program." start3:
LINE (0, 0)-(640, 480), _RGB(255, 255, 255), BF
more2:
begin = 1
'---------------------------------------------------
'Here is the main loop of the program when painting.
'---------------------------------------------------
LINE (mouseX
, mouseY
)-(mouseX
+ 1, mouseY
+ 1), clr~&
, BF
LINE (mouseX
, mouseY
)-(mouseX
+ 1, mouseY
+ 1), 0, BF
'Here is when someone whipes the screen blank with the space bar.
'Here is code needed to call up the Windows Color Picker.
'It also uses the code on top of this program and the Function at the end
'of this program.
chosencolor:
''Color Dialog flag constants (use + or OR to use more than 1 flag)
'ColorString = "FFFFFFFFFF" 'not sure how this works?
'DECLARE DYNAMIC LIBRARY "comdlg32"
' FUNCTION ChooseColorA& (DIALOGPARAMS AS COLORDIALOGTYPE) ' Yet the also famous color dialog box
'END DECLARE
'DECLARE LIBRARY
' $IF 32BIT THEN
' FUNCTION FindWindow& (BYVAL ClassName AS _OFFSET, WindowName$) ' To get hWnd handle
' $ELSE
' FUNCTION FindWindow&& (BYVAL ClassName AS _OFFSET, WindowName$) ' To get hWnd handle
' $END IF
'END DECLARE
'' SCREEN _NEWIMAGE(640, 480, 12) '32 or 16 or 256 color screen modes
'_TITLE "Paint Pixels" 'set Title of program
'hWnd& = FindWindow(0, "Paint Pixels" + CHR$(0)) 'get window handle using _TITLE string
'clr~& = ChooseColor&(_RGB32(0, 0, 0), ColorString$, Cancel, CC_FULLOPEN, hWnd&)
check$ = colorDialog$
IF check$
<> "" THEN clr~&
= VAL(check$
) ELSE clr~&
= &HFF0000FF '<<< I am blue if colorDialog does not work
'Here is the Ray Lines code.
ck = ck + 1
xxx = mouseX: yyy = mouseY
LINE (mouseX
, mouseY
)-(mouseX
+ 1, mouseY
+ 1), clr~&
, BF
ray:
LINE (mouseX
, mouseY
)-(xxx
, yyy
), clr~&
xxx = 0: yyy = 0
ck = 0
firstray:
'Here is the Orbit Circles code.
ck2 = ck2 + 1
xxx2 = mouseX: yyy2 = mouseY
orbit:
IF mouseX
< xxx2
THEN size
= xxx2
- mouseX
IF mouseX
> xxx2
THEN size
= mouseX
- xxx2
IF mouseY
< yyy2
THEN size2
= yyy2
- mouseY
IF mouseY
> yyy2
THEN size2
= mouseY
- yyy2
size3
= INT((size
+ size2
) / 2) CIRCLE (xxx2
, yyy2
), size3
, clr~&
xxx2 = 0: yyy2 = 0
size = 0: size2 = 0: size3 = 0
ck2 = 0
firstorbit:
'Here is the Fill-in code.
PAINT (mouseX
, mouseY
), clr~&
'Here is the Boxes code.
ck3 = ck3 + 1
xxx3 = mouseX: yyy3 = mouseY
box:
LINE (mouseX
, mouseY
)-(xxx3
+ 1, yyy3
+ 1), clr~&
, B
xxx3 = 0: yyy3 = 0
ck3 = 0
firstbox:
'Here is the Printing of the picture.
INPUT "Print on printer (Y/N)?", i$
'print screen page on printer j& = 0
'Saving
'This section first saves your picture as temp.jpg and then
'asks you a name for your picture and then renames temp.jpg to your name.
saving:
'Now we call up the SUB to save the image to JPG.
SaveImage 0, "temp.jpg"
PRINT "Your jpg file will be saved in the" PRINT "same directory as this program is." PRINT "It can be used with almost any" PRINT "other graphics program or website." PRINT "It is saved using:" PRINT "width: 640 height: 480 pixels." PRINT "Type a name to save your picture" PRINT "and press the Enter key. Do not" PRINT "add .jpg at the end, the program" PRINT "will do it automatically." PRINT "Also do not use the name temp" PRINT "because the program uses that name" PRINT "and it would be erased the next time" PRINT "you save a picture." PRINT "Quit and Enter key ends program." nm$ = nm$ + ".jpg"
'Checking to see if the file already exists on your computer.
PRINT "File Already Exists" PRINT "Saving will delete your old" PRINT "Would you like to still do it?" PRINT "(Y/N). Esc ends program." llloop:
saving2:
nm$ = ""
loading: 'This section loads your picture from your computer.
PRINT "Do not add .jpg at the end." PRINT "The jpg picture must be in the same" PRINT "directory as this program is." PRINT "You will not be able to edit your" PRINT "picture file with this program." PRINT "Type the name of your picture file" PRINT "here and press the Enter key." PRINT "Quit and Enter key ends program." nm$ = nm$ + ".jpg"
PRINT "File Does Not Exist." PRINT "Would you like to try again (Y/N)" PRINT "Esc ends program." llloop2:
l = 0
'j& = _COPYIMAGE(0)
s& = i&
i& = 0
''Here is the function for the Windows Color Picker,
'FUNCTION ChooseColor& (InitialColor&, CustomColors$, Cancel, Flags&, hWnd&)
' ' Parameters:
' ' InitialColor& - The initial color used, will take effect if CC_RGBINIT flag is specified
' ' CustomColors$ - A 64-byte string where the user's custom colors will be stored (4 bytes per color in RGB0 format).
' ' Cancel - Variable where the cancel flag will be stored.
' ' Flags& - Dialog flags
' ' hWnd& - Your program's window handle that should be aquired by the FindWindow function.
' DIM ColorCall AS COLORDIALOGTYPE
' ColorCall.rgbResult = _RGB32(_BLUE32(InitialColor&), _GREEN32(InitialColor&), _RED32(InitialColor&))
' ColorCall.lStructSize = LEN(ColorCall)
' ColorCall.hwndOwner = hWnd&
' ColorCall.flags = Flags&
' ColorCall.lpCustColors = _OFFSET(CustomColors$)
' ' Do dialog call
' Result = ChooseColorA(ColorCall)
' IF Result THEN
' rgbResult& = ColorCall.rgbResult
' ' Swap RED and BLUE color intensity values using _RGB
' ChooseColor& = _RGB(_BLUE32(rgbResult&), _GREEN32(rgbResult&), _RED32(rgbResult&))
' ELSE
' Cancel = -1
' END IF
'END FUNCTION
'Here is the SUB needed to save the image to JPG.
'It also can be used for BMP pictures on your own program.
IF bytesperpixel&
= 1 THEN bpp&
= 8 ELSE bpp&
= 24 b$
= "BM????QB64????" + MKL$(40) + MKL$(x&
) + MKL$(y&
) + MKI$(1) + MKI$(bpp&
) + MKL$(0) + "????" + STRING$(16, 0) 'partial BMP header info(???? to be filled later) FOR c&
= 0 TO 255 ' read BGR color settings from JPG image + 1 byte spacer(CHR$(0)) MID$(b$
, 11, 4) = MKL$(LEN(b$
)) ' image pixel data offset(BMP header) FOR py&
= y&
- 1 TO 0 STEP -1 ' read JPG image pixel color data r$ = ""
c&
= POINT(px&
, py&
) 'POINT 32 bit values are large LONG values d$ = d$ + r$ + padder$
MID$(b$
, 35, 4) = MKL$(LEN(d$
)) ' image size(BMP header) b$ = b$ + d$ ' total file data bytes to create file
MID$(b$
, 3, 4) = MKL$(LEN(b$
)) ' size of data file(BMP header)
'first screen dimensions items to restore at exit
'save old settings to restore at end ofsub
'screen snapshot
r = 128: g = 128: b = 128: a = 128
slider 16, 10, r, "Red"
slider 16, 60, g, "Green"
slider 16, 110, b, "Blue"
slider 16, 160, a, "Alpha"
_PRINTSTRING (150, 260), "Press enter or spacenbar, if you want to use the color: " + makeConst$
_PRINTSTRING (210, 280), "Press escape or q, to not use any color, returns 0." LINE (90, 300)-(710, 590), , B
f = 255 * (i - 100) / 600
'put things back
'clear key presses
'clear mouse clicks
SUB slider
(x
, y
, value
, label$
) CASE "Red": c~&
= &HFFFF0000 CASE "Green": c~&
= &HFF008800 CASE "Blue": c~&
= &HFF0000FF CASE "Alpha": c~&
= &H88FFFFFF LINE (x
, y
)-STEP(3 * value
, 40), c~&
, BF