Coloring an Image

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Bantymom
Posts: 73
Joined: Fri Aug 27, 2010 4:32 am

Coloring an Image

Post by Bantymom » Thu Sep 23, 2010 8:56 am

As a reward to completing a level of the game, I want to allow the student to color in a picture. I figured out how to get the coloring part started. I made little colored rectangles below the image and gave them the following code:

Code: Select all

on mouseup
   get backgroundcolor of me
   set the brushColor to the backgroundcolor of me
   choose bucket tool
end mouseup
This works very nicely, and I was so very proud of myself for figuring out something on my own for a change (easy for you guys, new for me), but it works only once. I can't select another color!

Written in plain English, it was supposed to go something like this:
Get the color of the rectangle the student clicks on and use it to paint the parts of the image the student clicks on. When the student clicks on another rectangle, change to another color and paint the next parts of the image the student clicks on.

lol, so close! I can get into the coloring, but I can't reverse it and get out!

I had thought to have the bucket turn back into the cursor when the student left the field of the picture or hovered over one of the colored rectangles. When that didn't work, I tried to tell it to choose the cursor after the first mouse up on the image (it colors on the mouse down). This would mean that the student would have to continue to go back over and over even for the same color, but Plan A wasn't working.

Unfortunately, Plan B didn't work either because, as it says in the Users Guide, once I have the bucket tool going, the stack has turned off the browser tool and clicking won't send any more mouse messages or even key messages to the stack.

So, any ideas on how to allow the student to go back to select another color? What kind of purposeful action (I would prefer not to employ a timer as it might be frustrating for the student) could the student employ to go back to a cursor? I think choose browse tool should work if I can just find an event or action the stack will listen to while the paint tool is active. "If there is new paint on the image, choose browser tool?"

Or, is there a way to tell it to paint a section of the picture (the same way as the bucket tool does by changing the color of the clicked pixel and all of the connected pixels of the same color) by using the cursor instead of actually choosing the bucket tool?

There is a different image for each level, so I can't designate areas and have those areas have their colors set as a property (oh boy, I'm afraid that probably makes no sense at all to anyone but me) ??? And I'll be running the stack in StackRunner, so the tool bar won't be available to the student (and I don't want it available to them as a general matter of course).

Thank you very much for everyone's help.
2nd-grade Teacher, Poultry Fancier, Scottish Country Dancer
and Perpetual Beginner

Klaus
Posts: 14177
Joined: Sat Apr 08, 2006 8:41 am
Contact:

Re: Coloring an Image

Post by Klaus » Thu Sep 23, 2010 10:30 am

Hi Bantymom,

the trick (and ONLY way) is to use a PALETTE for switching tools! That's why Rev does it this way :-)
A palette is the only way, because a palette will always show/use the browse tool.


Best

Klaus

P.S.
get backgroundcolor of me
## This line os not necessary

set the brushColor to the backgroundcolor of me
## Brava! :-)

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4163
Joined: Sun Jan 07, 2007 9:12 pm

Re: Coloring an Image

Post by bn » Thu Sep 23, 2010 12:01 pm

Bantymom,

have a look at this little stack, maybe it gives you some ideas.

regards

Bernd
Attachments
bucketToolBantymom.rev.zip
(1.42 KiB) Downloaded 383 times

Bantymom
Posts: 73
Joined: Fri Aug 27, 2010 4:32 am

Re: Coloring an Image

Post by Bantymom » Fri Sep 24, 2010 7:39 am

Klaus wrote:Hi Bantymom,
the trick (and ONLY way) is to use a PALETTE for switching tools! That's why Rev does it this way :-)
A palette is the only way, because a palette will always show/use the browse tool.
I was afraid that it wasn't going to be possible at all, and when I read that, I thought you meant that I had to have all the tools showing. I could have lived without being able to do what I wanted, but I would have been disappointed. But the little stack Bernd wrote for me is EXACTLY what I wanted to do! I had tried the "mouseleave" part before, but I had done it not quite right. Of course, when I saw the way it was done, it made perfect sense, and so elegantly done as well.
Klaus wrote: get backgroundcolor of me
## This line os not necessary

set the brushColor to the backgroundcolor of me
## Brava! :-)
Yea! I love neatness. I'm not good at it, but I love it. I had originally had one more line in the code earlier before figuring out it wasn't necessary, but now, wow!, down to one line. Every small lesson like that is greatly appreciated. I will go through things now to see if there are other places I can do that.

Cheers and many thanks,
*offers chocolate chip cookies*
Bantymom
Last edited by Bantymom on Sat Sep 25, 2010 3:40 am, edited 1 time in total.
2nd-grade Teacher, Poultry Fancier, Scottish Country Dancer
and Perpetual Beginner

Klaus
Posts: 14177
Joined: Sat Apr 08, 2006 8:41 am
Contact:

Re: Coloring an Image

Post by Klaus » Fri Sep 24, 2010 6:03 pm

Hi Bantymon,

you're welcome!

The kudos for the tiny little stack goes to Bernd however.
But we germans are hard to differ for americans :lol:


Best

Klaus

Bantymom
Posts: 73
Joined: Fri Aug 27, 2010 4:32 am

Re: Coloring an Image

Post by Bantymom » Sat Sep 25, 2010 3:43 am

Edited! It wasn't the double Germans that confused me, it's just that I have to stop working on these things in the middle of the night when I miss things.

Bernd, based on the sweet stack you made for me, I made the one that I've attached. I understood everything in yours except for why you made a custom property called fillcolor for the image and set to yellow to begin with. I couldn't find it referenced in any of the other scripts, so I must have missed it somewhere. I did the same anyway and set it to white, but I wish I understood why.

I used two regular buttons to do what the radio button did so that when I make it for my kids I can put a graphic like a paintbrush or something under a transparent button (I haven't figured out how to add icons yet, but I will eventually) Edit: Got it!

Thanks again.

Bantymom

*gets extra cookies to share all around*
Attachments
bucketToolBantymom II.rev.zip
(10.08 KiB) Downloaded 297 times
2nd-grade Teacher, Poultry Fancier, Scottish Country Dancer
and Perpetual Beginner

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4163
Joined: Sun Jan 07, 2007 9:12 pm

Re: Coloring an Image

Post by bn » Sat Sep 25, 2010 5:49 pm

Hi Bantymom,

That stack of yours looks very nice.
I understood everything in yours except for why you made a custom property called fillcolor for the image and set to yellow to begin with
Well, now I am a little confused. I don't recall using fillcolor as a custom property. The only custom property I used is "cBucketMode" of image 1.
I used a custom property because it is persistent, i.e. it is saved with the stack and I use them instead of e.g. a global property. It is well worth to get acquainted with custom properties. Unlike their complicated name they are very easy to use. Any object in Rev can have a custom property and you create one by just setting it, as in

Code: Select all

set the cBucketMode of image 1 to false
now, in case there was no custom property cBucketMode there is one attached to the image 1. You can look at the custom property in the property inspector -> custom properties. Many here prepend their variable and custom property names with a letter, for custom properties a "c" some use "u", it is just a way to make reading code easier. A local variable is often prepended by a "t", a script local variable by an "s" and a global variable by a "g". But this is in no way necessary, you can name it whatever you want as long as it is not a reserved word. (Words Rev uses itself)
Since in your case image 1 is the object that reacts to a mouseEnter/mouseLeave depending on whether you want to use the bucket tool it is the logical place to put it. You can access the custom property from everwhere in the stack by just queriing

Code: Select all

put the cBucketMode of image 1 into myVariable
In Hypercard one would have set a global variable, but once you get the concept of custom properties it feels more focused in the logic of the stack to attach it there.

Thank you for the cookies, everybody liked them when I passed them around. Since this seems a good way to get cookies I will be glad to add to your project with a little help if I can...
regards
Bernd

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4163
Joined: Sun Jan 07, 2007 9:12 pm

Re: Coloring an Image

Post by bn » Sat Sep 25, 2010 10:24 pm

BantyMom,
I do everything for cookies :)

I added a visual feedback to the colors that are selected in your stack. Something along those lines might be helpful down the road.
It is a graphic that is behind all other graphics and a little larger. When in bucket mode and selecting a color that color is marked by that graphic.

regards
Bernd
Attachments
bucketToolBantymom II with hilite.rev.zip
(10.55 KiB) Downloaded 366 times

Bantymom
Posts: 73
Joined: Fri Aug 27, 2010 4:32 am

Re: Coloring an Image

Post by Bantymom » Sun Oct 10, 2010 4:21 am

Bernd,

Thank you for all your help with this! I have been working on getting it just right. I've put it into my stack (I added more colors, some graphics, and changed the gHilite graphic to a black ring with a white dropshadow so it would show up better against the chalkboard.) So you can see the result of your inspiration, I have attached it here.

Oh! And I also figured out how to attach the script to the back of the images as they are brought into play! Since every level has its own set of images for reward, I was really not looking forward to having to go in and paste it into the scrip for each of the images used for painting. But now as the image is pasted onto the card, the script is added at the same time.

Thank you again,
Bantymom
Last edited by Bantymom on Sun Oct 24, 2010 7:26 pm, edited 1 time in total.
2nd-grade Teacher, Poultry Fancier, Scottish Country Dancer
and Perpetual Beginner

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4163
Joined: Sun Jan 07, 2007 9:12 pm

Re: Coloring an Image

Post by bn » Sun Oct 10, 2010 11:23 pm

Bantymom,

that looks really terrific. I think you came a long way in a short time. Bravo. I would love to paint like that as a kid. Even though it is a bribe for doing some dull spelling stuff :)

In the stack you posted there is a typo in the script of the of the image "linedrawing"
eon mouseEnter
which prevents the mouseEnter message.

glad you got it working, the kids are going to love it.

regards
Bernd

Bantymom
Posts: 73
Joined: Fri Aug 27, 2010 4:32 am

Re: Coloring an Image

Post by Bantymom » Mon Oct 11, 2010 5:46 am

Thanks for the catch! I've fixed it on the lineDrawing and in the Custom Property for that card where it's stored (to be pasted)

Thank you also for the kind words, though nearly everything on that card was yours. I mostly added the wrapping paper. But I do feel like I am learning more. I played with it until I understood what you had done, then tried a few different things, like setting a drop shadow for the selected oval instead of using the moving graphic, and learned why that wouldn't work as well. Each bit someone helps me with bets me into the dictionary and user's guide, and teaches me so much. I am very grateful for the time everyone takes to point me in the right direction.

I'll be putting up the latest version of the entire stack soon. It is close to finished for the one child it was written for, but not quite.

Cheers,
Bantymom
Attachments
Painting Card bn.zip
(224.37 KiB) Downloaded 321 times
Last edited by Bantymom on Sun Oct 24, 2010 7:26 pm, edited 1 time in total.
2nd-grade Teacher, Poultry Fancier, Scottish Country Dancer
and Perpetual Beginner

Bantymom
Posts: 73
Joined: Fri Aug 27, 2010 4:32 am

Re: Coloring an Image

Post by Bantymom » Sun Oct 24, 2010 7:20 pm

*a plate of brownies and chocolate-chip cookies has been laid out*

Bernd,

I hope you don't mind too much, but I've copied your post about my Undo and Reset problem to this, the original thread, because I know that this is where I will look for it when I want to refer to it again (and again and again...)

bn wrote:Bantymom,

I thought about your undo problem a bit. I did notice that when you hit the black dividing lines of the drawing with the bucket tool the color could "bleed" and fill a lot more area than intended.

Well I did a modification of your painting card stack you posted. It uses 2 custom properties of the image to store an initial image and an image of the last version before applying a color. So you can either undo the last painting action or reset the whole image. It turns out that Rev/Livecode sends a undoChanged message for paint action. I use this in the card script. The undoChanged message does not do anything by itself but you can use it to take action.
Two new buttons "reset" and "undo" on the card. And changed to the "paint" button. Have a look. Had to remove the teacher image to upload :(

regards
Bernd
Yep, that is what he does, he clicks on the outlines and "poof," the boundaries for the spaces no longer exist. Your solution to the problem is so much more elegant (and simple) than mine (you are going to laugh at how clumsy my way is):

Code: Select all

global PaintLevel
global gFix

on mouseUp
   lock screen
   delete image "LineDrawing"
   copy image "LineDrawing" of card PaintLevel
   paste
   set the width of image "LineDrawing" to 469
   set the height of image "LineDrawing" to 545
   set location of image "LineDrawing" to 542, 294
   set layer of image "LineDrawing" to 2
   set the script of image "LineDrawing" to the cPaintScript of card "Painting Card"
   set the dropShadow of image "LineDrawing" to true
   set the dropShadow["size"] of image "LineDrawing" to "60"
   set the dropShadow["spread"] of image "LineDrawing" to "60"
   set the dropShadow["angle"] of image "LineDrawing" to "45"
   set the dropShadow["distance"] of image "LineDrawing" to "5"
   
   set the cbucketMode of image "LineDrawing" to true
   set the brushColor to white
   set the loc of grc "gHilite" to the loc of grc "gWhite"
   show grc "gHilite"
   
   put gFix + 1 into gFix
   if gFix = 2 then
      hide group "Fix"
   end if
   unlock screen
Now, a lot of that was about to go away because I was going to use one of those Empty Image Control Place Holder things to eliminate all of the property setting steps, and a custom handler for the four lines that set up the Paint button again, but, WOW, what you wrote is so much more clean and to the point.

I did discover, when reading undoChanged, that the simple undo DOES work on paint commands, I had misread the information, and upon trying it again, command-Z did work, at least on my laptop here at home. It wasn't working on the computer at school, which seemed strange, until I remembered that I am running the stack with StackRunner! Ah ha! I suspect that it probably does something similar to turning on "Suspend Revolution UI" in the Development menu, which for me is a good thing where Tomas is concerned. Having a button for Tomas that will do that is perfect.

Anyway, I could, of course, just use it, as one would use any new technology, without understanding it, but I won't learn anything that way. I looked at all the new pieces (scripts and custom properties) and tried to search the old pieces to see if anything had been added to them. I found:
1) the new custom properties on the image and I saw what those looked like after painting on the image
2) the code on the paint button that sets up the two new custom properties to the starting imagedata
3) but I can't find where the "set cStartImage to ...." or "set cUndoImage to ...." happens that puts in the information that changes have happened to the painting. I expected something in the script for the LineDrawing like "when the paint tool clicks on me, put the image data of the me just before it clicked into the custom property cUndoImage." I can't find how or where that happens.
Attachments
Painting Card bn.zip
(224.37 KiB) Downloaded 325 times
2nd-grade Teacher, Poultry Fancier, Scottish Country Dancer
and Perpetual Beginner

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4163
Joined: Sun Jan 07, 2007 9:12 pm

Re: Coloring an Image

Post by bn » Sun Oct 24, 2010 8:10 pm

Bantymom,
I was afraid you would not find the post easily here, so I reluctantly posted it over in the other thread.
I can't find where the "set cStartImage to ...." or "set cUndoImage to ...." happens that puts in the information that changes have happened to the painting
set cStartImage to is set in the paint button. I figured one starts painting with the paint button so I added

Code: Select all

  -- new code
   -- lets get the state of image LineDrawing when starting to paint
   -- so we can go back to this state if we want
   set the cStartImage of image "LineDrawing" to the imageData of image "LineDrawing"
   set the cUndoImage of image "LineDrawing" to the imageData of image "LineDrawing" 
to the paint button. The initial filling of cUndoImage of image "linedrawing" is done here also.

When painting the undoChanged message is sent to the card. I added a handler to the card script:

Code: Select all

-- this is new
on undoChanged
   -- undoChanged is sent by the system if e.g. you do something with the paint tools
   if the mouseLoc is within the rect of image "LineDrawing" then
      set the cUndoImage of image "LineDrawing" to the imageData of image "LineDrawing"
   end if
end undoChanged
this updates the cUndoImage to the image before changes take effect. The perfect image for an undo.


Regarding your code: You could probably have coded:

Code: Select all

put image "LineDrawing" of card PaintLevel into image "lineDrawing" of card "Painting Card"
without all the rest of the code. Just swap images, the rest of the image _object_stays the same, no setting of shadow, location etc. (if the images are of the same size)

I see you want to pick up the custom properties for your images. The same applies here. I would make and image "LineDrawing" with all the attributes and just swap in the images. You would have to set/reinitialize the custom properties cUndoImage, cStartImage accordingly of course.

You might want to clear the custom properties cUndoImage, cStartImage on opencard and /or on closecard (set the cUndoImage of image "LineDrawing" to empty). They are of no much use as far as I see and it reduces the size of the stack. Each of the images in the custom properties add about 1 MB at their current size.

I will not tell you that after I discovered the undoChange message I did a version of your stack that "recorded" every changed image into an array that I put into a custom property. Well it worked quite well and I thought Thomas would have loved to see an animation of his painting. I even had a slider that let you go through the images/changes one by one. BUT Rev 4.0 has issues with storing large arrays in custom properties to disk and it corrupted the stack. So I gave up. No use in fiddling aroung with limitations. But it was nice though.

regards
Bernd

Bantymom
Posts: 73
Joined: Fri Aug 27, 2010 4:32 am

Re: Coloring an Image

Post by Bantymom » Thu Nov 11, 2010 4:45 am

Bernd,
Please, never be reluctant to add new information for me or another reply to one of my old threads. Not only to they pop back up to the top, but I check them frequently to remind myself what was said. I will always see the post. :) Heavens, I look for them! The responsiveness of this group always brightens my day.

However, I can't believe how long it has taken for me to understand the pieces of the lovely script you put together for me! Well, not all of it, just one part, but boy, what a hard time I had wrapping my mind around that one part!

I did put in an empty Image-Control-Place-Holder thing on the paint card as well as on the game card quite some time ago, setting all the properties and such there. That was pretty easy and has been wonderful! I had so much fun slashing blocks of code from my scripts! But for some reason, your perfectly good explanation of what was happening in the script for undoing an "oops" (one step) just completely eluded me. I got everything except the part about how the undoChanged worked. I kept looking for where it happened, where the undoChanged command was being sent. "on undoChanged" I would read, but where is it?????!!! I must have read the entry in the dictionary a couple of dozen times before I finally got it. Duh. The system itself sends it. Just like you said. Perfectly plain. *bangs head on keyboard*

So, I've got it now, and I can to ahead and make the adjustments to my real stack. I have one more question, and again, it isn't intended to question what you wrote for me, but to help me understand what makes one way of doing things more efficient than another.

Your code for "starting over" goes like this:

Code: Select all

--Paint Button
on mouseUp
--...
   set the cStartImage of image "LineDrawing" to the imagedata of image "LineDrawing"
--...
end mouseUp

Code: Select all

--the reset button
on mouseUp
   if the cStartImage of image "LineDrawing" is not "" then
      set the imagedata of image "LineDrawing" to the cStartImage of image "LineDrawing"
   end if
end mouseUp
--copies it right from the card I'm on
--should really clear it from the custom properties once done
You then also suggested that in my version, I could have written:

Code: Select all

put image "LineDrawing" of card PaintLevel into image "lineDrawing" of card "Painting Card"
--already exists, but I do have to get it from a different card
--wouldn't have to clear it from the custom property
Since I am now using an image object (is that the correct term for it?), how does swapping in the image from the original on the PaintLevel card (and I think I can get away with just the one line of code as the rest is now obsolete) compare to replacing the imagedata with the imagedata stored in the custom property?

Thank you so very much for all your patience and help,
Bantymom
2nd-grade Teacher, Poultry Fancier, Scottish Country Dancer
and Perpetual Beginner

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4163
Joined: Sun Jan 07, 2007 9:12 pm

Re: Coloring an Image

Post by bn » Thu Nov 11, 2010 11:41 am

Hi Bantymom,
Since I am now using an image object (is that the correct term for it?), how does swapping in the image from the original on the PaintLevel card (and I think I can get away with just the one line of code as the rest is now obsolete) compare to replacing the imagedata with the imagedata stored in the custom property?
You can just as well use the image on the paintlevel card to restore a to an unmodified image on the painting card instead of pulling it off the custom property. You just have to keep track of which image is the currently displayed image. In the undo code I did not want to worry about which image is actually displayed so I just set the customproperty cstartImage when the start painting button is pressed. There is actually no difference otherwise that I can see. I just did this without bothering where the images come from, the undo routine would work anyways. It does add to the required memory a bit, but it is not that much.

Image object is what I would call it to make the distinction between a container for the image and the bits and bytes that make up the image. That is what Rev calls it also, I believe.

regards
Bernd

Post Reply