Click to See Complete Forum and Search --> : Combining picture boxes... without brain surgery?
Ander123
Apr 8th, 2002, 06:21 AM
Help! In VB6, I have two picture boxes, pic1 and pic2. I'd like to copy pic1 to pic2, minus its white areas---so that pic1's non-white areas appear over pic2.
(pic2 doesn't even have to be an image, just a solid color.)
Someone suggested I look at the BitBlt info on MS's site, but it's way over my head. If that is the only way to do it, maybe someone could take pity on me and post a bit of sample code Thanks!
/\/\isanThr0p
Apr 9th, 2002, 03:27 PM
well what you need is masking. I haven't done that for a long time so I am not sure if it's the black or the white part does not show, so you might need to inverse it first (which is really easy though) but you will surely need a maskfile...
so I would propose you to go to www.ur.co.nz I had no clue about all of that and after reading this everything was clear... go for the bitblt tutorial...
Arbiter
Apr 9th, 2002, 03:34 PM
You might want to look up the user "Fox" on these pages. Find a post by him, and then look at the tutorial in his signature.
It's pretty easy to get to grips with and deals with things like what you're trying for....
Ander123
Apr 11th, 2002, 02:40 AM
Thanks, guys. I thought this would be pretty simple, but I've posted on several forums (even asked some of those online "experts"), and no one seems to know...
See, I'm writing a program to make chess diagrams for webpages. I want the user to be able to change the colors of the squares, without changing the chess pieces _on_ the squares. Maybe there's an easier way to do this...?
Anyway, I dropped Fox a note.
Cheers, Ander
/\/\isanThr0p
Apr 11th, 2002, 07:02 AM
well the problem is that there is no easier way of doing it... except for maybe saving each tile with each background... but that's not a good option anyways...
so what you would need to do is have two sets of pics.. one for the tiles and one for the masks... (while the mask files go for each color.. 16 white, 16 black, 16 masks...) the code you would need to do it than would be just two simple lines, you could even copy without understanding, even though they are really simple...
there is another way of doing it, but I guess noone told you about it, because it leaks memory as crazy and kills that system that way... it's transparent-blt....
Fox
Apr 11th, 2002, 07:36 PM
I solved his problem via mail..
/\/\isanThr0p
Apr 12th, 2002, 12:29 AM
can you give me a short explanation how?
Ander123
Apr 13th, 2002, 02:17 AM
Fox: I already said this in email, but---thanks very much! Your generosity is impressive.
/\/\isanThr0p: Fox wrote a complete example for me (with a very interesting 100-square chessboard, by the way---must be one of those chess variations. :?)
It does use BitBlt transparency; is that really such a problem? It seems to me that Fox knows his stuff...
I'd be glad to upload the example, if it's okay with Fox.
Cheers, Ander
Ander123
Apr 13th, 2002, 02:20 AM
Ah, I forgot: Fox mentioned in his email that it was okay to post the example---so here it is.
/\/\isanThr0p
Apr 13th, 2002, 03:32 AM
thanks
well BitBlt is really no problem at all just look at the MSDN...
/\/\isanThr0p
Apr 13th, 2002, 03:36 AM
well I took a look
it's exactly what I said earlier. you need two pictues, one as mask and one for the tile... than you blit it with two different OpCodes (operations, the first one is an 'or' and the second one is an 'and')
Fox did not use BitBlt though, he used the paint picture which is pretty much the same thing, but you don't need to declare it first. As far as I know it's also a lot slower which does not matter when you don't draw those things in a loop. (I am not sure about the speed difference, I think there used to be one, so I never used this paint function again...)
Ander123
Apr 13th, 2002, 03:45 AM
Man---"when it rains, it pours."
I just heard from a developer on another forum. He suggested using the ImageList's Overlay method. Here's an example.
Hey, it's better to know too much than not enough. :?)
Bazza81
Apr 13th, 2002, 04:49 AM
use the TransparentBlt API and do it the same as you would with BitBlt only you have to pass vbWhite as the transparent colour :)
/\/\isanThr0p
Apr 13th, 2002, 05:00 AM
did not fox already use the image list?
oh well...
NO DO NOT USE THE TRANSPARENT BLT API. IT'S CRAP!
it leaks memory as crazy and will cause you computer to crash after playing a while (especialy if you play as long as a 100*100 field would take :))
VBD
Apr 14th, 2002, 01:19 PM
picture2.autoredraw = true
picture2.scalewidth = picture1.scalewidth
picture2.scaleheight = picture1.scaleheight
For X% = 0 to Picture1.scalewidth
For y% =0 to picture1.scaleheight
if Picture1.Point (X%,Y%) <> Picture1.BackColor Then
Picture2.circle(X%,Y%),1,picture1.point(X%,Y%)
end if
next
next
The above code copies a picture from pic1 to pic2. Anything that is Pic1's backcolor it doesn't copy
Stevie Rotten
Apr 22nd, 2002, 05:07 AM
Originally posted by VBD
picture2.autoredraw = true
picture2.scalewidth = picture1.scalewidth
picture2.scaleheight = picture1.scaleheight
For X% = 0 to Picture1.scalewidth
For y% =0 to picture1.scaleheight
if Picture1.Point (X%,Y%) <> Picture1.BackColor Then
Picture2.circle(X%,Y%),1,picture1.point(X%,Y%)
end if
next
next
The above code copies a picture from pic1 to pic2. Anything that is Pic1's backcolor it doesn't copy
That CODE lags for me!
Stevie Rotten
Apr 22nd, 2002, 05:26 AM
Originally posted by VBD
picture2.autoredraw = true
picture2.scalewidth = picture1.scalewidth
picture2.scaleheight = picture1.scaleheight
For X% = 0 to Picture1.scalewidth
For y% =0 to picture1.scaleheight
if Picture1.Point (X%,Y%) <> Picture1.BackColor Then
Picture2.circle(X%,Y%),1,picture1.point(X%,Y%)
end if
next
next
The above code copies a picture from pic1 to pic2. Anything that is Pic1's backcolor it doesn't copy
That CODE lags for me!
Sastraxi
Apr 22nd, 2002, 07:35 AM
Yeah, that code will be slow as all hell. What you need is a mask. Copy your image, make everything that is non-white black, and save this as another image. You will then have your silhouette, or mask. Then, you can BitBlt the Mask with vbMergePaint, and then BitBlt the Sprite with vbSrcAnd.
If you want to know more, I have a small tutorial on this as well ;)
http://vbden.tripod.com/articles/invmask.htm
Stevie Rotten
Apr 22nd, 2002, 09:11 AM
ok, i've looked at fox's chessboard sample and i played around with it, and got it to work with my own images.
2 paintboxes
imageMAIN (playing area)
imageSPIRIT (spirit)
I use...
'draw mask
imageMAIN.PaintPicture imageSPIRIT.Image, 0, 0, 88, 87, 88, 0, 88, 87, vbSrcPaint
'draw image
imageMAIN.PaintPicture imageSPIRIT.Image, 0, 0, 88, 87, 0, 0, 88, 87, vbSrcAnd
It works fine, but now the problem is when the spirit is moved (redrawn) how can I clear the old one from the playing field. There is gonna be more than 1 spirit on the playing field.
See I run in to another thing because the spirit(s) will only be put on the playing field in specific locations (blocks). Say the map is made up of 13 blocks. 1 Block can only hold 1 spirit since these blocks will be cm^2.
Say spirit Joe is in block a3 and wishes to move to b5. How could i clear Joe from a3 and draw him in b5. Maybe what i have to do is just redraw the whole field per each team's turn. And I run into something else. If 2 SPIRITS on the same team, submit to move on the same block during the teams turn then I would either have to give the red team member more time to pick a new location, or move 1 of the spirits to a block that is nearest to the already filled block. I see myself probably having to make a function moving the user to the nearest block. oh well.
Another thing is text. Is there a way I could draw text on the playing field (picture box) over the SPIRIT?
Please if you can help me or give me any suggestions on which approach is the better or best, I would appreciate it VERY much!
Thanks!
Sastraxi
Apr 22nd, 2002, 11:10 AM
Okay, you need to do something called double buffering. It is when you copy all of your stuff to an invisible picturebox first. Then you SRCCOPY it all to the front picturebox (visible), and clear the invisible one. This way you see no flicker and no trails.
Sastraxi
Apr 22nd, 2002, 11:13 AM
Also, use the TextOut API to draw text on a given device context (hDC).TextOut Me.hDC, 0, 0, "Text", Len("Text")That syntax may be wrong; I'm at school and have no access to the API viewer.
Mad Compie
Apr 25th, 2002, 03:12 PM
Why not using the GetDIBits and SetDIBitsToDevice API? It really could save time during the For..Next iterations...
Ander123
Apr 25th, 2002, 03:45 PM
Wow, this got a good topic going.
Actually, my application didn't need animation speed; I'm creating pictures (chess pieces on board) only as quickly as the user can click. So the Image Control method has worked fine.
I'm intrigued about the TextOut method, though. I'd like to move some words smoothly across a black background without flicker. Would TextOut be the best way? Could you give a few sample code lines for us API dummies?
Fox
May 1st, 2002, 01:27 AM
There's always 2 ways to avoid trails:
1) Draw the whole stuff in each frame again (background and sprites). Use this method if you have to redraw the whole frame anyways, eg. if you have animated and/or scrolling tiles like in Jump 'n' Runs, RPGs, RTS or any 3D game.
2) Draw the background once. Then backup the square where you're going to draw a sprite and restore the picture in each frame (because of intersection problems). Note that you have to restore the picture parts in inversed order as you draw them. Use this method if you have a fixed, non-animated background and just small parts that are active, like a Tetris game or similar (just the blocks are moving) or for the world map of your game (fixed picture; animated waterfall or so on it).
vbforums.com
Copyright Internet.com Inc., All Rights Reserved.