SetColorKey
SetColorKey
SetColorKey
SetColorKey
SetColorKey
SetColorKey SetColorKey SetColorKey SetColorKey SetColorKey SetColorKey SetColorKey SetColorKey
SetColorKey SetColorKey
SetColorKey
Go Back  Xtreme Visual Basic Talk > > > SetColorKey


Reply
 
Thread Tools Display Modes
  #1  
Old 08-03-2005, 12:51 PM
jenn5175 jenn5175 is offline
Regular
 
Join Date: Apr 2002
Posts: 99
Default SetColorKey


This is going to seem like a simple question, but it has frusterated me for 2 days now. I need to set transparancy and ran across the ImgAttr SetColorKey method. I have found the same example over and over of how to use it. But I cannot seem to find how to call it. What is "e" and how do I call this from another sub? I tried just dimming a PaintEventArgs but it complains about it being null, so I know I have to set it equal to SOMETHING before passing it through, but what? Help! I put the code below that I found. If you have any other example instead of how to invoke SetColorKey (full code - not leaving me hanging like this did) I would be so appreciative!

Code:
Public Sub SetColorKeyExample(e As PaintEventArgs) '<--- what is "e" here????
' Open an Image file, and draw it to the screen.
Dim myImage As Image = Image.FromFile("Circle.bmp")
e.Graphics.DrawImage(myImage, 20, 20)
' Create an ImageAttributes object and set the color key.
Dim lowerColor As Color = Color.FromArgb(245, 0, 0)
Dim upperColor As Color = Color.FromArgb(255, 0, 0)
Dim imageAttr As New ImageAttributes()
imageAttr.SetColorKey(lowerColor, upperColor, _
ColorAdjustType.Default)
' Draw the image with the color key set.
Dim rect As New Rectangle(150, 20, 100, 100)
e.Graphics.DrawImage(myImage, rect, 0, 0, 100, 100, _
GraphicsUnit.Pixel, imageAttr) ' Image
End Sub
-Thanks
Jenn
Reply With Quote
  #2  
Old 08-03-2005, 02:02 PM
Machaira's Avatar
MachairaSetColorKey Machaira is offline
Jedi Coder

* Expert *
 
Join Date: Aug 2002
Location: Abingdon, MD
Posts: 3,438
Default

What you have there is a procedure that overrides the Paint event for an object (usually a form or PictureBox). Start a new project and add the code in this procedure to the Paint event of the form in the new project.

This is a bad example though since it loads the bitmap every time it's called. You should change this to load the bitmap in the form's constructor and keep it as a member variable of the form.
Reply With Quote
  #3  
Old 08-03-2005, 02:18 PM
jenn5175 jenn5175 is offline
Regular
 
Join Date: Apr 2002
Posts: 99
Default

I need to be able to call it manually, not just once at form load. My application allows the user an admin screen. When the screen first loads nothing is set (no images, color ranges, etc). The admin then chooses 3 images (back, middle - which will be a frame from a digital camera, front). The admin chooses those 3 files from their harddrive and they are loaded into pictureboxes. They then choose which color/size of range in the middle photo (by clicking on a pixel in it) to make transparent and which color/size of range on the front photo (by clicking on a pixel in it) to make transparent. The result is a new image of all 3 smooshed together. The application is basically a greenscreen system. The back image, middle transparancy color/range, front image and front transparency color/range are then all stored and used in the real app - which takes snapshots of people at an event in front of a greenscreen and merges them into the preset scene onsite. Because it is a real digital photo you can see how important it is to have a color range be transparent rather than a color (shadows, lighting, etc).

I originally got the entire system working using GetPixel and SetPixel to just swap front "transparent" pixels to the middle pixels in their place and middle "transparent" pixels to the background pixels at their location. It worked great......until I loaded real images (800x600). Then it took about 5 minutes per transformation. So I started researching better ways to do this and came across SetColorKey. It looks like exactly what I need. But I am stuck as to how to call it.

Do you know any better approaches than using this? Is SetColorKey even going to do what I need to accomplish? Any advice would be greatly appreciated!

Thanks,
Jenn
Reply With Quote
  #4  
Old 08-04-2005, 08:35 AM
Machaira's Avatar
MachairaSetColorKey Machaira is offline
Jedi Coder

* Expert *
 
Join Date: Aug 2002
Location: Abingdon, MD
Posts: 3,438
Default

It looks like this can be done. See the attachment for a starting point. There's a URL referenced in the code for get the color of a pixel that's clicked in the 2 PictureBoxes. There's a few bugs in it, but it might help.
Attached Files
File Type: zip WindowsApplication10.zip (19.5 KB, 8 views)
Reply With Quote
  #5  
Old 08-04-2005, 12:58 PM
jenn5175 jenn5175 is offline
Regular
 
Join Date: Apr 2002
Posts: 99
Default

Holy moly - this is AWESOME! Thank you so much! Defiantely gives me a push, I was at a brick wall and had no clue where to go next. Thank you so much for taking the time to do this. I really appreciate your help. Can't wait to tackle this again now.

Thanks,
Jenn
Reply With Quote
  #6  
Old 08-04-2005, 02:11 PM
Machaira's Avatar
MachairaSetColorKey Machaira is offline
Jedi Coder

* Expert *
 
Join Date: Aug 2002
Location: Abingdon, MD
Posts: 3,438
Default

Glad you think it's useful. Just post any problems or questions you have.
Reply With Quote
  #7  
Old 08-04-2005, 02:51 PM
jenn5175 jenn5175 is offline
Regular
 
Join Date: Apr 2002
Posts: 99
Default

Okay, here is something you may be able to help with. I have been trying to figure it out and you have already been more than enough help so no biggie if you don't know or don't have time.

The only way I have found to get a color range from a single color is basically grab the RGB values, place them into an algorithm to get HSV, add and subtract a certain amount to the H value to now have a high and low H, then go through another algorithm to turn those HSV values back into RGB, then use cLowColor = cLowColor.FromArgb(R_low, G_low, B_low) and cHighColor = cHighColor.FromArgb(R_high, G_high, B_high) to have two system.drawing.colors for the SetKeyColor function. I have tested this and I get two valid colors and they appear to stay consistant with the size of the range (configuable by the user) - so if I grab a lime green as the Chosen Key and put a range of "5" (H + (5/ 100) to H - (5/ 100)) I see a lighter lime and a darker lime. So I think my algorithms are working.

However, the SetColorKey does not like my colors - it keeps complaining of "Invalid Parameters". If I hardcode a known color into SetColorKey then it works, so it has to be the format of my generated colors. But label.backcolor recognizes my colors as legitimate colors and outputs what I expect to see, so why doesn't SetColorKey see mine as legitimate system.drawing.colors?

I am going to keep playing around with OLE, HTML, ARGB, etc but if you have any suggestions I would love to hear them.

Thanks,
Jenn

---Edit: I tried a few random RGB values and realized I think it has to be a known color to use SetColorKey (using cLowColor = System.Drawing.Color.FromArgb(255, 255, 255) worked fine but
cLowColor = System.Drawing.Color.FromArgb(213, 42, 8) did not).

New question - how am I supposed to get a range if I cannot use all RGB values?

Last edited by jenn5175; 08-04-2005 at 03:00 PM.
Reply With Quote
  #8  
Old 08-05-2005, 08:06 AM
Machaira's Avatar
MachairaSetColorKey Machaira is offline
Jedi Coder

* Expert *
 
Join Date: Aug 2002
Location: Abingdon, MD
Posts: 3,438
Default

Hmmm, that value works for me. See the attached. Can you post the relevant code?

Edit by wayneph: Removed binaries from zip file
Attached Files
File Type: zip WindowsApplication4.zip (17.0 KB, 5 views)

Last edited by wayneph; 08-08-2005 at 02:10 PM.
Reply With Quote
  #9  
Old 08-08-2005, 12:00 PM
jenn5175 jenn5175 is offline
Regular
 
Join Date: Apr 2002
Posts: 99
Default

Hmmm...your zip file does exactly what my code was doing for me - no matter which color I choose from the color dialog I get a "Invalid Parameter" error. I set all of the colors to white as a default thinking it was erroring because I chose the low but not yet hi (or vice versa), but that didn't seem to help.

Now I am thinking it is a library discrepency between us - because your code works on your machine but not on mine. I am using VS 2003/.NET Framework 1.1. I am loading a back picture, then loading a middle picture, then choosing "low color ..." for the middle picture, a color dialog pops up, I choose a color (any color) and click "ok", I get an "Invalid Parameters" error message at the SetColorKey line (looking at the variables, a color was successfully chosen).

Wierd! I am going to play some more. Let me know if there is maybe a new DLL I could download for the drawing library (maybe you are using VS2005 and they have a newer bug-free version?). If I skip the choosing color part and just set the defaults to known colors it seems to work fine.

Jenn
Reply With Quote
  #10  
Old 08-08-2005, 01:49 PM
Machaira's Avatar
MachairaSetColorKey Machaira is offline
Jedi Coder

* Expert *
 
Join Date: Aug 2002
Location: Abingdon, MD
Posts: 3,438
Default

I'm using VS2003 as well (on an XP Pro machine). What OS are you using?
Reply With Quote
  #11  
Old 08-08-2005, 02:22 PM
jenn5175 jenn5175 is offline
Regular
 
Join Date: Apr 2002
Posts: 99
Default

XP Pro.....

Was there anything in the order I was doing things that you found was different? Glancing through the code I didn't see anything that would matter if I chose certain pictures first or colors first or whatnot.

I am going to try it on a few more machines and see if I can get it working once - I think as soon as I find out that issue everything will fall into place because your sample code was so helpful. Thanks again!!!

Jenn
Reply With Quote
  #12  
Old 08-15-2005, 07:58 AM
jenn5175 jenn5175 is offline
Regular
 
Join Date: Apr 2002
Posts: 99
Default

Has anyone else tried this code? I have tried 3 machines now and always get "Invalid Paremeters" error when trying to choose a color (even a known color). Sometimes it happens the first time I choose a color, sometimes I can successfully choose one color (say, Lime green for 'low') but when I choose another color (say, Yellow for 'high') I get that same error. It does not seem predictable - about 80% of the time I get the error on the first color choosing and the rest it is on subsequence color choosings - even if I keep choosing the same colors in the same order. That error is the same one I get when I use my own code.

Any clues/ideas at all? I am using Microsoft Development Environment 2003 Version 7.1.3088/Microsoft .NET Framework 1.1 Version 1.1.4322

Help!
Jenn
Reply With Quote
  #13  
Old 08-15-2005, 10:54 AM
JNewt's Avatar
JNewt JNewt is offline
Centurion
 
Join Date: Apr 2003
Location: KY (Home), ID (College)
Posts: 138
Default

Runs fine on my machine.
VS 2003, .Net 1.1
Reply With Quote
  #14  
Old 08-15-2005, 11:17 AM
jo0lsSetColorKey jo0ls is offline
Senior Contributor

Forum Leader
* Expert *
 
Join Date: Feb 2005
Location: London
Posts: 1,050
Default

Googling suggests it is to do with color depths, fromrgb(r,g,b) will work for 24bpp. You'll have to detect the users desktop color depth and make the colors depending on what they are using. I think.
The code works for me, I'm trying to force the error somehow...

Last edited by jo0ls; 08-15-2005 at 11:29 AM.
Reply With Quote
  #15  
Old 08-15-2005, 12:40 PM
jenn5175 jenn5175 is offline
Regular
 
Join Date: Apr 2002
Posts: 99
Default

Quote:
Originally Posted by jo0ls
Googling suggests it is to do with color depths, fromrgb(r,g,b) will work for 24bpp. You'll have to detect the users desktop color depth and make the colors depending on what they are using. I think.
The code works for me, I'm trying to force the error somehow...
Thanks - gives me someplace else to look. I am at 32 bits for color quality (assuming that is the same as "color depth" in Control Panel -> Display?) and my only other option is 16 - there is no 24. Seems like if it works for 24 it should work even better for 32 unless I am misunderstanding. The good thing is this app will be on our configured machines so if it is simply a display setting we can control that. The bad news is I still haven't been able to get by without the error no matter which setting I change. If you are talking about something other than the Display setting for Color Depth, can you explain more?

Thanks!
Jenn
Reply With Quote
  #16  
Old 08-15-2005, 06:34 PM
jo0lsSetColorKey jo0ls is offline
Senior Contributor

Forum Leader
* Expert *
 
Join Date: Feb 2005
Location: London
Posts: 1,050
Default

try this:
It just redraws the image from file onto a 24bppRGB bitmap. I don't understand it myself - it would help if I got the error.

Code:
PictureBox2.BackColor = Color.FromArgb(231, 42, 8) 'draw the bitmap onto a new bitmap that is 24bppRGB Dim myImage As Bitmap = New Bitmap(Application.StartupPath & "\test.bmp") Dim bitmap24bpp As New Bitmap(myImage.Width, myImage.Height, Imaging.PixelFormat.Format24bppRgb) Dim g As Graphics = Graphics.FromImage(bitmap24bpp) g.DrawImage(myImage, 0, 0) Dim gr As Graphics = PictureBox1.CreateGraphics Dim lowerColor As Color = Color.FromArgb(213, 42, 8) Dim upperColor As Color = Color.FromArgb(213, 42, 8) Dim imageAttr As New System.Drawing.Imaging.ImageAttributes Dim rect As New Rectangle(150, 20, 100, 100) imageAttr.SetColorKey(lowerColor, upperColor, Imaging.ColorAdjustType.Default) gr.DrawImage(bitmap24bpp, rect, 0, 0, 100, 100, GraphicsUnit.Pixel, imageAttr)
Reply With Quote
  #17  
Old 08-16-2005, 02:44 PM
jenn5175 jenn5175 is offline
Regular
 
Join Date: Apr 2002
Posts: 99
Default

Hmm...didn't seem to make a difference (if I did it correctly). I think my issue is the range must follow rules and I am not following them - if I set both the high and low to the same color, it works fine.

I have attached my actual code rather than the example supplied. The project I am speaking about is form2.vb (should be set to run this one).

I included my images folder. I need to be able to use JPGs, but for now have made 2 BMPs to make it simpler (back1.bmp and middle2.bmp). If I run the progam as is, it works fine - load back1.bmp as back image, middle2.bmp as front image (or vice versa). Click on a color in middle2.bmp to set the transparent color then hit "Preview". If you load middle2.bmp as the back and back1.bmp as the front image, you can see the anti-aliasing on the blue or red (whichever you choose) and my entire goal of this project is to get those "stair" pixels to disappear so there is a nice smooth line.

However, it is only working for me because both the low and high values in setColorKey are equal right now.

To use it the way I need it, I have to change line 422 from
Code:
attr.SetColorKey(cChosenColor, cChosenColor, Imaging.ColorAdjustType.Default)

to 

attr.SetColorKey(cLowColor, cHighColor, Imaging.ColorAdjustType.Default)
Make that change, then run it again. This time, load up the images, click on the front image to set the color, then click "Get Range". You will see a high and low color now (should reflect the width you specified around the chosen color). These colors are generated by the sub getRange(). They are valid colors according to the label.backcolor (it obviously displays them) and if you break you can see the variables are system.drawing.colors with legit A, R, G, B values. But my program now breaks at line 422 saying "Invalid Parameter". It does not like me having a range - it wants the high and low to be the same. If I change the line to

Code:
attr.SetColorKey(cLowColor, cLowColor, Imaging.ColorAdjustType.Default)
then it seems to work fine (at least doesn't error out but nothing disappears) - so I know my generated colors are legal.

Can anyone replicate my error or does this code work for you as well? Has anyone heard of SetColorKey arguing when trying to use a range rather than only deleting 1 color? Maybe I misunderstood its use?

Thanks!
Jenn
Attached Files
File Type: zip chromakeyTest.zip (135.3 KB, 2 views)
Reply With Quote
  #18  
Old 08-16-2005, 03:06 PM
jenn5175 jenn5175 is offline
Regular
 
Join Date: Apr 2002
Posts: 99
Default

A HA! - finally found what I was looking for. But it totally negates my logic for finding a low to high color range. Now that you see my code, does anyone have logic for coming up with a color range (since I won't know ahead of time the range width and if it is red/blue/green/or a mix)? I have to go back to the drawing board.

For anyone else who is having this issue, this was taken from http://iceplug.vwebservices.com/cngdi2.htm

Quote:
.SetColorKey(CL, CH)
CL and CH are color structures. First of all, what is a ColorKey? A ColorKey is a pair of colors that determine the transparency in a picture or a drawing operation. This will allow a range of colors to become transparent. The range of colors is defined by the two colors that are passed into the method. For example, you can remove all of the pure greens in a picture (you know, Green Green Green Green Green Green Green Green, R & B are both 0.) by setting the color key to be CL = Color.FromArgb(0, 0, 0), and CH = Color.FromArgb(0, 255, 0).
The transparent areas show up to match the form's background color.
Notice that black is also removed. If you want to keep black, then you'd use Color.FromArgb(0, 1, 0).
System.Drawing.dll will throw a fit if your lowcolor in the color key is not absolutely lower than the highcolor, so CL = Color.FromArgb(0, 255, 0) and CH = Color.FromArgb(0, 0, 255), if you wanted to get rid of green through blue, will throw an error. Also, even something as slight as CL = Color.FromArgb(1, 0, 0) and CH = Color.FromArgb(0, 255, 0) will throw an error.
On the situation with CL = Color.FromArgb(0, 255, 0) and CH = Color.FromArgb(0, 0, 255): if you wanted to get rid of Greens/Blues, you'd do: CL = Color.FromArgb(0, 0, 0) and CH = Color.FromArgb(0, 255, 255).
This would mean that anything that contains a hint of red will be visible. CL = Color.FromArgb(64, 64, 64) and CH = Color.FromArgb(192, 192, 192) gets rid of all colors that have Red between 64 and 192, Green between 64 and 192, and Blue between 64 and 192... this would be all of the grays in the picture vanishing.
Reply With Quote
  #19  
Old 08-16-2005, 03:36 PM
Iceplug's Avatar
IceplugSetColorKey Iceplug is offline
MetaCenturion

Retired Moderator
* Guru *
 
Join Date: Aug 2001
Location: Iowa, USA
Posts: 16,583
Default

Oh if that's the problem with your two chosen colors, then you have to make two composite colors, one as the minimum and one as the max.

Code:
Dim MinColor As Color, MaxColor As Color 'Will hold the lowest and highest colors. If Color1.R < Color2.R Then 'If the first color has less red than the second color. MinColor.R = Color1.R 'Set this lowest red amount to the MinimumColor variable. MaxColor.R = Color2.R 'And the greatest to the MaxColor variable. Else 'This means that Color2.R is less than Color1.R (or equal) 'Therefore, we need to swap the assignments. MinColor.R = Color2.R 'Set this lowest red amount to the MinimumColor variable. MaxColor.R = Color1.R 'And the greatest to the MaxColor variable. End If
You will need to do the same for Green and Blue.
After you finish this, MinColor and MaxColor will be your ColorKey .
__________________

Iceplug, USN
Quadrill 1 Quadrill 2 (full) Quadrill 3 JumpCross .NET Website is ALIVE! - DL Platform Tour for VB.NET! Posting Guidelines Hint: Specify your location in your user cp profile if you want compassion!
Reply With Quote
  #20  
Old 08-17-2005, 10:42 AM
jenn5175 jenn5175 is offline
Regular
 
Join Date: Apr 2002
Posts: 99
Default

How funny that you are on these forums and I found your website purely by chance (and hours of searching for help)

This works great. However, do you have a better way of determining a range from one given color than what I am doing? I only know if I change hue the color appears to go in the direction I wanted. So I am changing the chosen color to HSV, adding and subtracting from H to get two new H's, then transferring the color back to RGB. Although it appears to do its job by looking at the min and max colors produced, it isn't deleting a lot of what I want from the picture. I can't get rid of the "steps" to get a smooth line no matter how large I make my range (and if I make it too large, it screws up all together - the range for grey becomes between maroon and maroon?!?!). I am guessing it is because I am not altering S and V.

Is there a simpler way to take Color X and find a range that is Y distance from it on either side? I feel like I am making this way more complex than it needs to be.

Thanks!
Jenn
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
SetColorKey
SetColorKey
SetColorKey SetColorKey
SetColorKey
SetColorKey
SetColorKey SetColorKey SetColorKey SetColorKey SetColorKey SetColorKey SetColorKey
SetColorKey
SetColorKey
 
SetColorKey
SetColorKey
 
-->