Paint Clone in Python

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] what is going on guys welcome back in today's video we're going to build a simple paint clone in python and this is what we're going to end up with i have already coded this so we can look at the final result this is going to be a very simple canvas here that we can draw on we can increase the brush size we can decrease the brush size there you go we can clear the screen we can choose different colors from the color picker here so we can choose green for example we can choose red we can choose blue and once we're done with the whole artwork here yes that's what i would call an artwork uh we can either press save or we can try to close and then we're going to get a dialogue let's do the close thing uh we can it asks us do you want to save your work i can press yes and then it's going to ask me for a file name let's go with 123.png and then it's going to close the application and as you see there you go we have a png file on our desktop we can also choose a jpeg file let me just rerun the script here and we can now draw something fancy here let's just increase the brush size a lot and go with red for example there you go and then we can just save this as 456.jpg and there you go as you can see a jpeg file and i can of course say cancel so it doesn't close the application if i say i don't want to save it it's just going to close the application so this is what we're going to build today and for this we're just going to need two modules one of them is going to be a core python module so we don't even need to install it and the other one is pillow so you need to install pillow and for that you open up your command line or your terminal whatever you're using and you type pip or pip3 depending on which one you're using and install pillow like that so we're going to use pillow only for the export part so if you just want to have the application the graphical user interface and everything without the ability to save the final image you don't need pillow pillow is what we're going to use for the export and tk inter is what we're going to use for the actual graphical user interface so what we're going to say is from tk inter import everything because we're going to use a bunch of different gui elements uh we're going to also say import or actually we're going to do that later on we're going to also use some dialogues but we're going to import them when we need them and we're going to import from pill image draw now we also need image from pill but the problem is and i'm not sure where it was exactly maybe it was with tk inter maybe it was with opencv uh but sometimes there are some conflicts with the image so you can also say from pill import uh let me just go to the right position here you can also say from pill import image and then image draw as well but the problem is that image can be ambiguous because different libraries use the same image class so sometimes when you then say image it doesn't know are you actually talking about there you go as you can see it's talking about tk inter and not about pill dot image so if you want to use image from pill what you want to do is you want to import pill and then you can use image by saying pill dot image so besides that what we're going to do is we're going to define some constants first so we want to say the width and the height of the canvas is going to be 500 and 500 then the center is going to be the width floor divided by two so we have a whole number an integer and we're also going to define the color white to be two five five two five five two five five just an rgb value here so for the actual graphical user interface we're going to do a class we're going to have a gui class because then we have all the objects um we have one centralized object where we can just access self dot and the individual elements so we don't need to care about which function we define first which uh attribute and which widget we define first so we're just going to do that in a gui class class paint gui and i think we need one oh what the hell happened there i'm going to need one extra line here and we're going to start with the init method it's just going to be a basic constructor and we're going to start with the root window so the root window is going to be tk with a capital t and of course we want to make that part of self so self dot root is going to be tk self dot root dot title is going to be neural nine paint clone call it whatever you want just not as cool for example and then what we're going to do is we're going to define some basic parameters for example the brush width is going to be by default not parameters by the way attribute sorry it's going to be 15 and the default color current color is going to be zero zero zero zero zero zero by the way i have a plug-in for highlighting the colors if you wanna have that plug-in as well you just go to pycharm settings um then to plug-ins and the plugin is called color highlighter so you can install it in pycharm if you are using pycharm if you are using vim or um vs code there are other plugins like that as well so just look them up um and then we're going to start with a canvas so the canvas is just going to be cnv canvas we are going to pass self dot root as the parent object here the width of the canvas is going to be width minus 10 and height is going to be height minus 10 for the borders there you go and the background of the canvas is going to be white as you can see again we have the the color preview then self.canvas is going to be packed so that we can add it to the gui and what we're going to do is we're going to bind the motion of the first mouse key so the left mouse key being pressed and moved we're going to bind that uh that motion to a function that is going to draw on the canvas so we're going to say self.canva i'm going to pass the string b1 dash motion like that and this is going to be bound to the function self dot paint and we don't have that function yet so we're going to define it self paint and we're going to just leave it empty for now we're going to add a pass here and this function is going to be triggered every time we press the left mouse button and we move our mouse inside of the canvas every time we do that we're going to call the paint function it's going to do what it's going to do all right so after that we're going to also define the image that we're drawing itself so self image is going to be pill dot image dot new rgb and uh then we're going to pass the width and height of the image and we're going to pass the color white as the background um then we're going to create a draw object so draw is going to be image draw on the image and we're going to use image draw to draw on the image and we're going to use the image cell for the export later on there you go so what's next let me just look at the code here uh next we're going to define a button frame because you saw that we have the the canvas and then we have the buttons below the canvas and those buttons are inside a button frame so we're going to say self.button frame is going to be a button or actually just a frame and this frame is going to be part of self.root and we're going to fill we're going to say self.buttonframe.pack and we're going to fill we're going to set fill equal to x so it stretches across the x-axis and inside of that button frame we're now going to add all the different buttons for increasing the brush size decreasing it for clearing for saving and so on so what we're going to do first is we're going to say self.buttonframe dot column configure and we're going to set zero weight equals one we're going to copy that we're going to have three rows or three columns actually come on there you go and now we're going to add the buttons to that frame so self dot let's start with a clear button is going to be a button it's going to be part of the button frame and the text is going to be clear and every button can have a command and this command is going to just be a function so we're going to say command equals self.clear but we don't have that clear function yet so we're going to just go down here and say clear and we're going to pass for now so let's first finish the gui and then we're going to talk about these functions then we're going to say self.clear button we're going to grid that so it's going to be a grid structure here and we're going to place that clear button at row one and add column one actually i think column needs to be written like that and we're going to make it sticky so that it stretches to west and east to left and right so we're going to say sticky equals um w plus e this is not a string those are constants from the tk inter module uh what do we have here is not callable why is that not oh we need to say image draw dot draw there you go so we can copy that here and we can create a bunch of more buttons we want to have a what's the next one when i have a save button save button i'm gonna change the text to save and the function obviously to save as well and down here want to change it to [Music] uh what's the next one when i have brush plus or let's call it b plus btn and b plus btn here as well there you go the function is going to be called brush plus and brush minus brush underscore plus uh so let's copy that change that to minus btn minus btn and we change that symbol to a minus and this here to a minus as well and of course all these functions need to be implemented so we're going to define them down here save we're gonna pass brush plus there you go brush minus and one button is still missing and this button is the color picker so self dot change or let's just call it color btn is going to be button actually let's just copy that color btn color btn text is going to be change color and the command is going to be change color there you go so now we only need to adjust these uh row and column parameters here we want to have uh the save button in column two wanna have the brushes here in zero and zero and we wanna have or actually wanna have them column zero no row row zero and row one in column zero and column zero and the color button is right in the middle or actually how do we wanna have it we wanna have uh the brushes we want to have change color and clear so we want to have clear in column one in row zero let's change that i want to have the save button in or actually want to have the color button in row one column one i want to have the save button in column two row one okay that's fine i think that should be fine so change color needs to be defined as well def change color self pass there you go so at the end of that of course we need to also um run the actual tk inter uh main loop so we need to say self.root but first of all we're going to set a settings set self.true.protocol we're going to say wm delete window and we're going to call the function on closing you can call this again whatever you want and we're going to define the function on closing this just triggers that whenever we press the x symbol in the top right we're going to call a function so that we can ask if the user wants to save the artwork or not so on closing self pass there you go and then self dot self.root.attributes we're going to say that we want this to open um on top so topmost is going to be true you don't need that setting if you think it's annoying i just like it for the videos and then self.root there you go so now i think even though the buttons don't have any functionality we should be able to at least see the graphical user interface let's try it paint gui and let's run this script there you go as you can see okay maybe we want to have this at row zero um doesn't work because if i now press on the canvas you can see we get some errors but you can see that the basic graphical user interface is here so just a save button we want to have it at row zero so now if i run this there you go okay so what we're going to do next is we're going to define the individual functions now the clear function is quite simple so we're going to define that first the clear function basically says okay self.canvas delete everything i'm going to delete everything from the canvas and we're going to set the or actually we don't need to do that because we don't change the background so deleting it is everything we need to do and then also of course don't forget that we have two things that we edit here we have the actual canvas that we see while we draw then we have the actual image whatever we do on a canvas we also do in the image so whatever we did on the canvas we also did on the image and we need to delete that as well so we need to say self dot draw dot rectangle this is uh i don't know if that's the best practice way to do it but what we're going to do is we're just going to draw a white um rectangle and fill it with white color to reset everything from 0 0 to a thousand a thousand which is definitely enough and then we're going to say fill equals white i don't say that that's the best practice way to do it but that's one way to do it so this is how we clear everything now let's talk about the paint function itself because that's where the action is happening the paint function uh is taking an event sorry as a parameter and the event is the motion of the mouse this event has coordinates where is the mouse what is it doing so what we want to do is want to say x1 and y1 equals event dot x minus one and event dot y minus one and x2 is going to be x2 and y2 is going to be plus 1. so this is basically so that we have a rectangle because we cannot just uh cannot just draw a rectangle at the same position so this is the x and y coordinates of the rectangle and now we're going to say self dot canvas dot rectangle so this is on the we're actually draw rectangle right sound.canvas draw rectangle uh or actually it's create rectangle sorry these functions definitions i always i always mix them up so create rectangle and what we provide is the coordinates so x1 y1 to x2 and y2 those are the corners uh we're going to outline with a certain color and the color that we're going to use for the rectangle for the outline of the rectangle is going to be the current color which is self dot current color and we're going to fill with a certain color which is guess what self dot current color and we're going to set the width to guess what self dot brush width so all the parameters that we have um what's the problem here okay the line is too long that doesn't really matter and then oh sorry i need to fix that alarm real quick all right so for that interruption i had an alarm going on from my phone um there you go so this is the rectangle from the canvas and now we need to do the same thing the exact same thing that we do on the canvas we want to do it on the image draw as well so we want to say self dot draw dot rectangle and here we pass again x1 x2 x1 x y1 x2 uh plus self dot brush width and y2 plus self dot brush width and this is how we do it here we pass a list of the coordinates and then of course also the parameters outline and so on so outline is going to be self dot current color and fill is going to be self dot current color as well and i'm not sure if we need to have a width here yes we need to have a width here as well so the width is going to be self dot brush width there you go so by executing these two lines of code we're actually drawing this is just getting from the event where is the mouse actually located because remember we bound the motion of button one being pressed uh so whenever we move that that triggers the event which is bound to the canvas which calls paint so we pass the event and the event knows okay where is the mouse at the moment and depending on that we're going to take the action of creating a rectangle there on the canvas and of course doing it also in the image that we don't see that is operating in the background all right so this is the basic paint function i think we should actually be able to see that there you go we can already draw and we should also be able to clear as you can see a big part of the paint application is already working so let's do a very basic thing now and implement the brush sizes here so the brush plus and the brush minus is actually quite simple we just need to say self dot brush width is going to be plus equals one and here we need to say if self dot brush width is larger than one then we're going to decrease it by one because we don't want to go to zero or negative numbers brush with minus equals one there you go now i think that's most of it did i forget anything oh yeah we need to have a color dialog and we need to also care about on closing but the the next thing we're going to do is we're going to do the safe the safe is going to export the image that is created in the background so again we're drawing on the canvas but we're also drawing on the image so that we can export it later on and we're going to now implement the save function and the save function is going to be using a file dialog so before we do that we need to import the file dialogs from tk inter and we're going to say actually let me just see what the module is called from tk inter we're going to import um the file dialog and we're also going to import now the message box and we're going to import the color chooser those are the three dialogues that we're going to need here um and for the saving we're going to say file name equals and we're going to say file dialog dot ask save as file name and here we can pass a bunch of options and the options are going to be the initial file so the initial file is going to be in my case untitled dot png then we're going to specify the default extension default extension come on it's going to be png as well and then we can also specify the file types that are available and here you can choose whatever you want so you can say file types equals you need to pass a list uh and inside of that list you have two tuples so you have this and this and here we have the uh the name so png for example and we have jpg and here we have the endings the extension so dot png and dot jpg now actually you can pass everything here that pillow supports so you can also try different uh formats but this is what we're going to do now png and jpg and that's actually it now as a result of that what this is going to do is it's going to open um it's going to open the file dialog then we're going to choose a path and as a return value we're going to get the path to that file so all we need to do now is if the file name is not empty if file name is not empty like that then we're going to say self dot image dot safe to that file name and i'm not sure why pycharm is so stupid with the indentation at the moment i think maybe i didn't close a bracket what's the problem here let's just see come on let's see what's the problem [Music] actually should be fine now right there you go okay so we're basically saying get the file name that you want choose the extension that you want and then once you're done if you chose anything because if we click on cancel it's gonna have an empty file name if the file name is not empty we're going to save the image otherwise we're just going to not save the image so let's see if that works i think this should already work if i now click on save tests.png let's see if this produces an image there you go we already have the image so our application is almost done we only need to care about the colors and about the closing dialog and the colors is actually not the color choosing is not too difficult we just need to call the um the respective dialogue so we need to say color chooser dot ask color and the title of this is going to be i don't know choose a color and this is going to give us two return values the first value is not important to us because it's going to be the rjb color value and the second one is going to be the hex value that we can work with so we're going to say underscore and then self dot current color and then we're going to set that to the result so if you want to see what this produces we can also print color dot ask or actually color chooser dot ask color and we will not provide a title so we can comment that out and i can show you what this actually does there you go let's pick this one here you can see that we get first of all the rgb values and then also the hex value and we want to have only the hex value so we just get that so that's basically it and for the closing part we also want to have a message box that asks do you really want to quit or do you want to save your work before you quit and if the answer is yes then we're going to save the work otherwise we're just going to do nothing so the answer is going to be messagebox dot ask yes no cancel so we have three options title is going to be quit and the message is do you want to save your work and the parent of that message box is going to be self.root and the answer can now be either true false or none so if the answer is not none so if the answers not cancel then we're going to say if the answer is true so if answer then we're just going to say self.save otherwise we're just going to say self. or where we're always going to say self.root.destroy and we're always going to say exit 0 but if we don't have answer equals true so if the answer is no we're just going to going to destroy immediately and if the answer is yes we're going to also save the work so i think that's actually it so we are done let's see if it works we can draw we can change the colors we can increase the brush size we cannot go into the negative so if i press this a bunch of times i should not be able to go below one there you go and i can also save this i can also cancel this and i can press on x i can say cancel and i can press on x say yes and it would save it as one two three and i can also use jpeg oh i use jpeg twice so maybe i should change that but there you go it's saved we just need to fix that mistake i provided jpeg twice where is it safe there you go it was png and dot png and then jpeg and dot jpeg i just messed up the over there so this is how you build a simple paint clone in python so that's it for today's video if you enjoyed i hope you learned something if so let me know by hitting the like button leaving a comment in the comment section down below and of course don't forget to subscribe to this channel and hit the notification bell to not miss a single future video for free other than that thank you much for watching see you next video and bye [Music] you
Info
Channel: NeuralNine
Views: 4,353
Rating: 4.9858656 out of 5
Keywords: paint clone, drawing, tkinter, python, paint, draw, python drawing, tkinter drawing, python paint, python paint clone, tutorial, python tkinter, gui
Id: x_t292uiH5Q
Channel Id: undefined
Length: 29min 16sec (1756 seconds)
Published: Sun Sep 19 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.