Hey,
I am working on building this chess program. I just started and I had a little problem. Well I have images of pieces that will be moved around the board. The problem is that pieces can be moved from a dark square to a light square or vice versa. So the background colour of the image cannot remain same.
The background colour is going to be white... So is there any way that the background colour of the image can be made transparent. Also is it possible that we can set the white colour to be transparent or the colour that most occures in the image (i.e. white) to be transparent.
Please help me out or else I will have to do twice the work by making pieces with two types of background colours and also have to check which square the piece is on.
Any help would be appreciated.
Khanjan
Last edited by khanjan_a2k; Aug 16th, 2006 at 06:22 PM.
Hey... If you found this post helpful please rate it.
edit your chess peice in Abode Photoshop. Click file and new then check the set transparent box. Then open your image and select the part of the image you want to retain using the magic wand tool. then click edit and copy. click on the 1st one you made(the one with a chessboard like background, gray and white checkered background) and click edit and paste. Then save it as gif. On vb, create an image box and put your gif image there.
the easiest way is to make pieces as transparent gifs and load them in image controls, but thats is not good solution (flickering may and probably will appear)
Well first of all... carlandrewg the problem is that I don't have Adobe Photoshop and I am not good at it. And is it possible that Painst Shop Photo Album 4 or Dell Pictur Studio will help??
And I do not undertsand your process quite clearly. I am sorry but could you explain clearly. In the meantime I will try to get some help from sprites
Khanjan
Hey... If you found this post helpful please rate it.
the easiest way is to make pieces as transparent gifs and load them in image controls, but thats is not good solution (flickering may and probably will appear)
krckoorascic I did try to look at the website that you gave me however it just gave me some knowledge on how to create sprints and masks but not how to use them in Visual Basic. However while reading it I came across the TransparentBit and BitBlt Api. I looked them up in the Api Guide.
The Transparent Bit Api may help me but the example they provided was with a Picture Box. I am using Images however I will try merging it onto a Image. Though, could you please confirm if it will work or not.
The BitBlt Api just made a circular form however since the example is big I will try to look at it.
Could someone explain what carlandrewg was trying to say because I quite did not understand him. Sorry!
Triggernum5 I will be looking at your example.
Thanx for your help guys
Khanjan
Hey... If you found this post helpful please rate it.
Its not an example, its a fullblown function you can just plug into your project after you declare a few api's etc.. Found it somewhere ages ago.. I don't know where I found it, and I'm not sure if there were ever any credientials attached to it, but the process is pretty much common knowledge today anyhow..
khanjan_a2k you cannot use gdi api functions on Image control cuz it doesn't have a hdc...
search for memDC on vbaccelerator, that will help you (just create a memory dc on which you'll do all the drawings and when all pieces are drown you just copy that memdc to you form or picturebox, depending where you want to render gfx)
Well is it possible to have the Picture box be transparent?
What I am doing is that there is a board full of shapes (i.e Squares) either dark gray or light gray.
Now the images of the pieces only has white and black colours or it so I dun need anything complicated for colours. I just want the white in black pieces and the black in white pieces to be transparent.
triggernum5 your function also talks about using Picture Boxes. Also, I don't know what hdc and DC is...
Khanjan
Hey... If you found this post helpful please rate it.
Apparently there is a bit of a memory leak with TransparentBlt() API.. The routine I posted gives the exact results cleanly.. You don't need the shapes to have an hdc since your form will have one.. Just tell pDrawTransparentBitmap where on the form containing your grid of shapes where you wish place the piece.
-The background color of the piece picture is the color the function expects.
-Load your piece pics into memory dc's or A memory dc using this class if you need it.. - http://www.vbaccelerator.com/home/Re...ection_cls.asp
-Use form.hdc as destination
-Memory dc as source
Bingo.. A picturebox however does have an hdc.. Thats good enough since you don't need any do memory intensive graphics work..
Couple of tips, Make the background color the same on both color sets.. Purple maybe.. Saves needing to modify your code to determine bg color.
Make a single invisible picturebox to hold all your pieces that are stored in a single picture file then calculate where to copy from..
It would even be possible to ditch all your shapes, start with ONLY a picture of a chess board with pieces (loaded from disk), and cut/paste the pieces and blank squares of proper color using pDrawTransparentBitmap
I'm really sorry but I am not familiar with any of the things u said to me. If possible could u just do what u said to one piece and I will understand it and apply to the whole thing. Pleaseee
Khanjan
Hey... If you found this post helpful please rate it.
A few things that will really simplify your program and cut down on controls..
Use a single image as a background for anything that will not move.. Your board is designed most excellently, you could just take a screen snapshot of that and put it in a picturebox the size of your form.. This will prevent other objects from interfering with the picture placement that you are new at anyways.. The example I coded demonstrates this
I have incorporated the cAlphadibSection class..
This class example refers to 3 images for one piece:
m_cImage = Your chess piece pic
m_cMask = Transparency Mask (Alpha Channel)
m_cAlphaImage = AlphaBlendedwithDest image
This allows you to use your white set as masks, and allows you to take transparency to a WHOLE new level with shadows etc..
Black Points in Mask are 100% transparent
White Points are 100% opaque
Anything in between is partially transparent if you include greys in the mask
Yes, it is possible to transfer only a single color.. Slightly modifying that pDrawTransparentBitmap sub will accomplish that.. RasterOp sequences can do basically anything if you understand boolean logic/arithmetic.. Thats a moot point now though, I'm just mentioning it so you know its an option in the future
Thank you for the example triggernum5 but unfortunately I am at work (library) right now and the office computers do not have Visual Basic. However, I would just like to respond to your suggestion about just taking an image of the board.
The reason I do not want to take an image of the chess board is because I want the user to be able to see the possible moves when the user moves his/her mouse over a piece. I would do this by just outlining the possible squares.
However, on the other hand I can also leave the square as the are and also have an image. But all I can do is that make the squares look like the outlines and not have the grey in them. I can just turn the visible property to false. And when I need the possible squares to be visiable = True.
Which one do you think will work better for me.
I will look at the example you made for me once I reach home.
Khanjan
Hey... If you found this post helpful please rate it.
Its still very easily doable to write a sub that draws on the pic temporarily, using vb directly, or API to outline potential moves.. Or, if you wanted you could do both, simply keep the squares invisible unless you want to outline, I honestly don't know how much memory is consumed by keeping an array of redundant shapes.. Maybe I'll learn here..
And if you haven't noticed by now, I like working directly with images.. I'd just make a pic/mask of an outlined square (with transparent or better yet, semitransparent bodyfill in its mask since some destinations will be occupied obviously).. Then you can alphapaint that onto as many squares as you need..
The only reason not to work with images directly would be if you needed scalability on an image that didn't rescale well, but your board/set could all be scaled nicely without degradation if you ever implement that..
BTW, if you haven't looked at the project I'm pretty sure you will pick up on how to use the cAlphaDibSection class easily, and that will explain all this crap I'm talking about
PS, scraping the big picturebox idea, and just putting the bg image on the form itself works too.. Slightly different properties in each, so you may find you have a prference
Yes you are right, I will need to take a look at the project you have given me. Unfortunately, I will not be able to look at it until the next few hours. Possibly 5-6 hours. Anyways, I will look at it and reply for any further questions.
I appreciate your help.
Khanjan
Hey... If you found this post helpful please rate it.
In the sample program you gave me, you attached two extra files:
cDibSectionmod.cls
modChroma.bas
Since I am trying to undertsand what you are doing, line by line, it would be better if you just briefly told me what these files are for since these files are not being used by the project example you gave me. If they are just attached by an accident, it would save me time. Thanx
Khanjan
Hey... If you found this post helpful please rate it.
Well I was using the example you gave me. However, when I change the co-ordinates of the edited Image to (280, 560) which is where the King is supposed to be, I can't see it. This is because my board comes in the middle. Any solution to this?
Khanjan
Hey... If you found this post helpful please rate it.
An easier alternative (although obviously a waste of resources) is to have each image with two background colours (one for each square colour)...however, it would be a simple matter to make the images transparent using paint shop pro, photoshop or pretty much any image program these days. I did a quick search of google and found http://graphicssoft.about.com/cs/ima...eephotoedw.htm which gives you a list of 8 programs that are free...I would guess GIMP would be able to handle your requirements :-)
I love helping noobs with their VB problems (probably because, as an amateur programmer, I am only slightly better at VB than them :-)) but if you SERIOUSLY want to get help for free from a community such as VBForums, you have to first have a grounding (basic knowledge) in VB6, otherwise you're way too much work to help...You've got to give a little if you want to get help from us, in other words!
And we DON'T do your homework. If your tutor doesn't teach you enough to help you make the project without his or her help, FIND A BETTER TUTOR or try reading books on programming! We are happy to help with minor things regarding the project, but you have to understand the rest of it if you want our help to be useful.
Thanx a lot Smux for your research. However I cannot use the easier alternative since I would be moving the pieces around. Anyways, I did some research on the pDrawTransparentBitmap method triggernum5 was talking about. I found an example that I used to create an example of my own. But I still do not know how I am going to be able to use it in my program. I have attached the example program I create and I also attached a credential since there wasn't one.
Smux now that I can download the program I hope it will be much easier.
Khanjan
Hey... If you found this post helpful please rate it.
I would say setting transparency with one of those programs will be the easiest option. If you can't figure out how to do it, I might be able to set transparency for you...put the images into a RAR/ZIP and send in a private message (through www.yousendit.com if you have to) and I'll set transparency and return the images the same way :-)
I love helping noobs with their VB problems (probably because, as an amateur programmer, I am only slightly better at VB than them :-)) but if you SERIOUSLY want to get help for free from a community such as VBForums, you have to first have a grounding (basic knowledge) in VB6, otherwise you're way too much work to help...You've got to give a little if you want to get help from us, in other words!
And we DON'T do your homework. If your tutor doesn't teach you enough to help you make the project without his or her help, FIND A BETTER TUTOR or try reading books on programming! We are happy to help with minor things regarding the project, but you have to understand the rest of it if you want our help to be useful.
Its because the shapes are drawn over the form (where the piece is painted), which is the reason I suggested eliminating the shapes and row labels, and why I placed the piece where it was half covered in the example.. You can store an outlined square pic/mask in your set, and alphapaintpicture it wherever you need, as often as you need.. The listboxes you need for move lists, and the shapes bordering it affect nothing whether they are there, or just another part of your bg picture on the form itself.. But really if it was me I'd only have the list boxes and other functional controls (If you need to add them later) and everything else would be image oriented.. Basically like dragging/dropping an edit clip in MSPaint, except with more restrictions on where the piece can be placed, and if the location is valid, snap it to proper borders.. This way you will also be able to reuse the same code for more features like a captured pieces box because virtually every action will be simply dragging/dropping a pic..
Edit: Actually if you have shapes bordering your list then even though its not a valid place to drop, the image will hide behind it while dragging..
Last edited by triggernum5; Aug 18th, 2006 at 09:58 AM.
Why does the code suggested only work for small images? I have been trying to change the settings for an image that is 720x480, but the colors don't transfer like they should. Any ideas?
Code:
Public Sub pDrawTransparentBitmap(lHDCDest As Long, lBmSource As Long, _
lMaskColor As Long, Optional lDestStartX As Long, _
Optional lDestStartY As Long, Optional lDestWidth As Long, _
Optional lDestHeight As Long, Optional lSrcStartX As Long, _
Optional lSrcStartY As Long, Optional BkGrndHdc As Long)
' Draw a sprite onto a picture. The background of
' the sprite is made transparent so the pictures
' shows through.
Dim lColorRef As Long
Dim lBmAndBack As Long
Dim lBmAndObject As Long
Dim lBmAndMem As Long
Dim lBmSave As Long
Dim lBmBackOld As Long
Dim lBmObjectOld As Long
Dim lBmMemOld As Long
Dim lBmSaveOld As Long
Dim lHDCMem As Long
Dim lHDCBack As Long
Dim lHDCObject As Long
Dim lHDCTemp As Long
Dim lHDCSave As Long
Dim x As Long
Dim y As Long
Dim udtBitMap As BITMAP
Dim udtSize As POINTAPI
'
' Create a temporary Device Context compatible with
' the destination DC (picturebox's DC).
lHDCTemp = CreateCompatibleDC(lHDCDest)
' Select the sprite's bitmap into the temporary DC.
Call SelectObject(lHDCTemp, lBmSource)
' Store the sprite bitmap's characteristics in
' the udtBitMap.
Call GetObject(lBmSource, Len(udtBitMap), udtBitMap)
' Set the size of the temporary bitmap.
With udtSize
.x = udtBitMap.bmWidth
.y = udtBitMap.bmHeight
' Use the optionally passed in width and height values.
If lDestWidth <> 0 Then .x = lDestWidth
If lDestHeight <> 0 Then .y = lDestHeight
x = .x
y = .y
End With
' Create some DCs compatible with
' the picture to hold temporary data.
' This creates one pixel by one pixel
lHDCBack = CreateCompatibleDC(lHDCDest)
lHDCObject = CreateCompatibleDC(lHDCDest)
lHDCMem = CreateCompatibleDC(lHDCDest)
lHDCSave = CreateCompatibleDC(lHDCDest)
' Create a bitmap for each DC. DCs are required
' for a number of GDI functions.
' Monochrome bitmaps.
lBmAndBack = CreateBitmap(x, y, 1&, 1&, 0&)
lBmAndObject = CreateBitmap(x, y, 1&, 1&, 0&)
' Color Compatible bitmaps.
lBmAndMem = CreateCompatibleBitmap(lHDCDest, x, y)
lBmSave = CreateCompatibleBitmap(lHDCDest, x, y)
' Each DC must select a bitmap object to store pixel data.
' Monochrome
lBmBackOld = SelectObject(lHDCBack, lBmAndBack)
lBmObjectOld = SelectObject(lHDCObject, lBmAndObject)
' Color
lBmMemOld = SelectObject(lHDCMem, lBmAndMem)
lBmSaveOld = SelectObject(lHDCSave, lBmSave)
' Set the mapping mode of the temporary (sprite)
' DC to that of the picture's DC. The mapping mode
' defines the unit of measure used to transform
' page-space units into device-space units, and
' also defines the orientation of the device's
' x and y axes.
Call SetMapMode(lHDCTemp, GetMapMode(lHDCDest))
' Save the sprite bitmap that was passed in
' because it will be overwritten.
Call BitBlt(lHDCSave, 0&, 0&, x, y, lHDCSave, lSrcStartX, lSrcStartY, vbSrcCopy)
' Set the background color of the sprite's DC to
' the color in the sprite that should be transparent.
' Background color of the DC to MaskColor
lColorRef = SetBkColor(lHDCTemp, lMaskColor)
' Create a mask for the sprite by performing a BitBlt from
' the sprite's bitmap to a monochrome bitmap. The result is
' a matrix of 1's and 0's where 0 represents the foreground
' color and 1 represents the the background color.
Call BitBlt(lHDCObject, 0&, 0&, x, y, lHDCTemp, lSrcStartX, lSrcStartY, vbSrcCopy)
' Set the background color of the sprite's
' DC back to its original color.
Call SetBkColor(lHDCTemp, lColorRef)
' Create the inverse of the mask.
Call BitBlt(lHDCBack, 0&, 0&, x, y, lHDCObject, 0&, 0&, vbNotSrcCopy)
' Copy the background of the main DC to the destination.
If (BkGrndHdc = 0) Then
Call BitBlt(lHDCMem, 0&, 0&, x, y, lHDCDest, lDestStartX, lDestStartY, vbSrcCopy)
Else
Call BitBlt(lHDCMem, 0&, 0&, x, y, BkGrndHdc, lDestStartX, lDestStartY, vbSrcCopy)
End If
' Mask out the places where the bitmap will be placed by AND-ing
' the memory DC with the mask with the 0's where the foreground is.
Call BitBlt(lHDCMem, 0&, 0&, x, y, lHDCObject, 0&, 0&, vbSrcAnd)
' Mask out the transparent colored pixels on the bitmap. The
' background of the sprite is masked out so only the foreground remains.
' lHDCTemp is the colored sprite. This is AND-ed with the mask
' which has the 1's where the foreground is and 0's where the background is.
Call BitBlt(lHDCTemp, lSrcStartX, lSrcStartY, x, y, lHDCBack, 0&, 0&, vbSrcAnd)
' Combine the colored foreground of the sprite with the colored
' background image by OR-ing the bitmap in the prior step with
' that from two steps back.
Call BitBlt(lHDCMem, 0&, 0&, x, y, lHDCTemp, lSrcStartX, lSrcStartY, vbSrcPaint)
' By varying lDestStartX and lDestStartY we can
' place the sprite in a different location on the
' background image (but now the sprite backgroud will be off).
Call BitBlt(lHDCDest, lDestStartX, lDestStartY, x, y, lHDCMem, 0&, 0&, vbSrcCopy)
'Call BitBlt(lHDCDest, 0, 0, x, y, lHDCMem, 0&, 0&, vbSrcCopy)
' Place the original sprite bitmap back into the bitmap sent here.
Call BitBlt(lHDCTemp, lDestStartX, lDestStartY, x, y, lHDCSave, 0&, 0&, vbSrcCopy)
' Delete memory bitmaps.
DeleteObject SelectObject(lHDCBack, lBmBackOld)
DeleteObject SelectObject(lHDCObject, lBmObjectOld)
DeleteObject SelectObject(lHDCMem, lBmMemOld)
DeleteObject SelectObject(lHDCSave, lBmSaveOld)
' Delete memory DC's
DeleteDC lHDCMem
DeleteDC lHDCBack
DeleteDC lHDCObject
DeleteDC lHDCSave
DeleteDC lHDCTemp
End Sub
Set some breakpoints in the sub before/after each step, create a temporary PBox with autoredraw enabled and use the debug window to BitBlt() the contents of the hdc's to the picbox.. That will show you exactly when the unexpected results occur.. Works with a 1000:1000 pixel image for me..