From: Bee on
Still working with sprites. Well ... trying.

I have an image (i call it a positive for lack of a better definition) that
I want to make into a sprite.
I then need to create the sprite mask (the mask).

The positive is picture and not necessiarly line art (that would be simpler).

I copy the positive to the mask for starters.
Using all bitmaps .BMP to preserve them.

So I need to have show through areas in the sprite.
Current thinking is that the positive needs to have pure black in the
transparency area.
So i hand draw the black.
Now the mask needs these same areas to be white so I replace all black with
white.

unfortunately, there are some black areas originally in the positive that I
do not want to be transparent.
i have no contol over the colors in the image except for hand drawing the
transparency areas.

(1) is there an easy way to fix this?
(2) am I limited to black and white for the positive and mask transparency
area?
I have tried to use other colors but it did not work.
e.g. for the positive i use red and for the mask i use the bitwise
complement color.
I guess I do not understand that the BitBlt is doing with the SRCAND and
SRCPAINT

I am thinking that i could preprocess the positive and change all black to
almost black (off by one bit). then the black (positive) to white (mask)
would only change the transparency area and the almost black would not be
detectable by eye.

Or it I could get colors oter that black and white to work, i could choose a
colr not in the positive. seems like too much work on this thought.

From: Larry Serflaten on

"Bee" <Bee(a)discussions.microsoft.com> wrote

> So I need to have show through areas in the sprite.
> Current thinking is that the positive needs to have pure black in the
> transparency area.
> So i hand draw the black.
> Now the mask needs these same areas to be white so I replace all black with
> white.


The mask needs to be white where you want transparency, and black where
you want the positive to show.

Where there is black in the positive image that you want to show, that
area has to be black in the mask. So you can not simply 'replace all
black with white', but must replace only the opaque areas with black.

To see an example, paste the following into a new form:

LFS


Private Sub Form_Load()
AutoRedraw = True
ScaleMode = vbPixels

' Positive
Line (0, 0)-(50, 50), 0, BF
DrawWidth = 7
Circle (25, 25), 18, vbRed
Line (15, 36)-Step(20, -20), vbRed
DrawWidth = 1

' Mask
Line (60, 0)-(110, 50), vbWhite, BF
DrawWidth = 11
Circle (85, 25), 18, vbBlack
Line (75, 36)-Step(20, -20), vbBlack
DrawWidth = 1

' Background image
Line (0, 100)-(110, 150), vbYellow, BF
PSet (5, 115), vbYellow
Font.Size = 16
Font.Bold = True
ForeColor = vbBlue
Print "EXAMPLE"
Picture = Image

' Sprite copy
PaintPicture Me.Picture, 30, 100, 50, 50, 60, 0, 50, 50, vbSrcAnd ' Mask
PaintPicture Me.Picture, 30, 100, 50, 50, 0, 0, 50, 50, vbSrcPaint ' Positive

End Sub





From: Bee on
Well, except when I google I see where it talks about using other colors.
So are they doing something different?
Terminology limited here so it is all still a little confusing.
I have my code set up to do black and white but was considering alternatives.
What I have works for the case where black and white are NOT in the original
sprite. Some images already have those as areas of non-transparency.


"Larry Serflaten" wrote:

>
> "Bee" <Bee(a)discussions.microsoft.com> wrote
>
> > So I need to have show through areas in the sprite.
> > Current thinking is that the positive needs to have pure black in the
> > transparency area.
> > So i hand draw the black.
> > Now the mask needs these same areas to be white so I replace all black with
> > white.
>
>
> The mask needs to be white where you want transparency, and black where
> you want the positive to show.
>
> Where there is black in the positive image that you want to show, that
> area has to be black in the mask. So you can not simply 'replace all
> black with white', but must replace only the opaque areas with black.
>
> To see an example, paste the following into a new form:
>
> LFS
>
>
> Private Sub Form_Load()
> AutoRedraw = True
> ScaleMode = vbPixels
>
> ' Positive
> Line (0, 0)-(50, 50), 0, BF
> DrawWidth = 7
> Circle (25, 25), 18, vbRed
> Line (15, 36)-Step(20, -20), vbRed
> DrawWidth = 1
>
> ' Mask
> Line (60, 0)-(110, 50), vbWhite, BF
> DrawWidth = 11
> Circle (85, 25), 18, vbBlack
> Line (75, 36)-Step(20, -20), vbBlack
> DrawWidth = 1
>
> ' Background image
> Line (0, 100)-(110, 150), vbYellow, BF
> PSet (5, 115), vbYellow
> Font.Size = 16
> Font.Bold = True
> ForeColor = vbBlue
> Print "EXAMPLE"
> Picture = Image
>
> ' Sprite copy
> PaintPicture Me.Picture, 30, 100, 50, 50, 60, 0, 50, 50, vbSrcAnd ' Mask
> PaintPicture Me.Picture, 30, 100, 50, 50, 0, 0, 50, 50, vbSrcPaint ' Positive
>
> End Sub
>
>
>
>
>
> .
>
From: Mike Williams on
"Bee" <Bee(a)discussions.microsoft.com> wrote in message
news:C3439316-471D-456C-A5A7-00FE744AB8F4(a)microsoft.com...
>> "Larry Serflaten" wrote:
>> The mask needs to be white where you want transparency,
>> and black where you want the positive to show.
>
> [Bee responded] Well, except when I google I see where it talks
> about using other colors. So are they doing something different?
> I have my code set up to do black and white but was considering
> alternatives. What I have works for the case where black and
> white are NOT in the original sprite. Some images already have
> those as areas of non-transparency.

What Larry was talking about is the colours of the prepared mask and the
prepared sprite image (the two things that you need to effectively combined
together into the destination in order to perform a transparent blit). There
are slightly different arrangements (white on black instead of black on
white etc) depending on the specific raster operations you use in the two
blits, but the "black on white" mask and the "colour on white" sprite image
is possibly the most commonly used arrangement, and if you prepare those two
things in such a manner then you can perform your transparent blit into the
destination by first blitting the prepared "black on white" mask into the
destination using vbMergePaint, which effectively "punches a white hole" the
shape of the black portion of the mask into the destination, followed by a
blit of the prepared "colour on white" sprite image using vbSrcAnd at
exactly the same place in the destination, which (because of the presence of
the "white hole we just punched") effectively draws only the coloured pixels
of the prepared "colour on white" sprite image into the destination whilst
not drawing the white pixel of the prepared "colour on white" sprite image
at all. So, Larry was telling you what you need to do with regards to
creating the required mask and image (a "black on white" mask and a "colour
on white" sprite image). Those are the two images you need, but both of them
need to be "made" using the data of your original picture or drawing. They
can either be made manually (as you currently appear to be doing) or they
can be made in code by your program. The rest of the story (exactly why the
two blits mentioned above do what I've told you they do, and the details of
how those two images can be made in and why sometimes one method is better
than the other) can be told in many different ways, depending mainly on
whether you simply want a routine which works and which you can use in your
own code or whether you would prefer to actually learn "why these things
work". Reading your original post I'm not quite sure which of those two
things you would prefer.

> Well, except when I google I see where it talks
> about using other colors. So are they doing
> something different [2]?

That depends on what you've been Googling. You'll find lots of routines that
draw images transparently, and in many cases they will be starting with an
original image (your original drawing or picture or whatever) and they will
be using one or more different methods to construct the "black on white
mask" and the "colour on white" sprite image that I mentioned in the above
paragraph. Such routines construct those two images from the original image
(your original drawing or whatever) and then they use them to actually
perform the transparent blit, usually in the way I have already described
above. The part of the routine that constructs the mask and the sprite image
in code from your original drawing or picture is usually written in such a
way that it will accept any colour you wish as the desired "transparent
colour" when they are constructing the mask and the sprite. For example, if
you have an original picture and you pass it to such a routine then you will
be able to specify any colour you wish as the desired "transparent" colour.
That's probably the sort of stuff you've been Googling. Passing your
original picture to such a function will draw the sprite transparently for
you, but (because it needs to create the mask and sprite images "on the fly"
as part of the job it is doing) it will not be as fast as if you had
prepared the "black on white" mask and "colour on white" sprite image in
advance yourself (either manually or in code) and then just used those two
images in two BitBlt functions as mentioned above each time you need to draw
the transparent image at any specified position. Anyway, the details of how
these routines actually work and how you can do them yourself would probably
best be left until you have answered the question I asked in the first
paragraph above, and I'm sure you will get lots of responses from lots of
people here.

By the way, whilst you are deciding what sort of responses you would like, I
might just mention one specific API function that is capable of doing the
entire job for you, so as far as you are concerned there is virtually no
work at all for you to do. The function does all the various things I have
been talking about "under the hood" and all you need to do is pass it your
original picture or drawing and tell it what colour you would like to use as
the transparent colour and it will then draw the sprite transparently for
you, effectively "all in one go" as far as the coder is concerned. It is the
TransparentBlt function in msimg32.dll. Normally I would not mention that at
all, and normally it is the very last thing I would consider using, partly
because it used to have a bad memory leak and partly because it used to be
very much slower than doing the same job using two Blits with ready prepared
mask and sprite images. However, things have changed a lot since Vista
arrived (for the worse!). The memory leak was fixed in Windows XP onwards (a
good thing) and Vista has totally crippled GDI32 (a bad thing!), so much so
that in Vista performing two blits on ready prepared mask and sprite images
(which used to be very much faster than using the TransparentBlt API) is now
actually about the same speed, or even a bit slower! Vista really does make
me angry! Anyway, if you decide that you would rather just have some working
code and that you do not actually want to learn how these things work (and
of course if you are only concerned with performing this job on Vista
machines) then you might like to have a look at the API TransparentBlt
function in msimg32.dll. It really is very easy to use, and you should find
lots of working examples on Google. Post again if you want to go that way
and if you would like example code.

Mike


From: Larry Serflaten on

"Bee" <Bee(a)discussions.microsoft.com> wrote
> Well, except when I google I see where it talks about using other colors.
> So are they doing something different?

See Mike's response for TransparentBlt which could be what you've seen

> Terminology limited here so it is all still a little confusing.
> I have my code set up to do black and white but was considering alternatives.
> What I have works for the case where black and white are NOT in the original
> sprite. Some images already have those as areas of non-transparency.

Your first post mentioned using SRCAND and SRCPAINT so that is the method
I posted. It works for any / all available colors in the 'positive' image. If you
noticed, the red symbol had a black outline. If you want to see it also using white,
make the change below to the earlier posted example:

> > ' Positive
> > Line (0, 0)-(50, 50), 0, BF
> > DrawWidth = 7
> > Circle (25, 25), 18, vbRed
> > Line (15, 36)-Step(20, -20), vbRed ' < < Change to vbWhite
> > DrawWidth = 1

You'd then have a red circle with a white diagonal line, all outlined with black.
As I said, any available color in the 'positive' will work, as long as that area is
black in the mask image.

If you want to understand how it works, it may help to think of the bit values
of the colors you are using. The mask is black (no bits on) on white (all bits on).
Whenever you AND the mask to whatever colors, the black area ANDed with any
color results in black, where the white area ANDed with any color results in the
original color.

After copying the mask to the destination you get a black image on the destination
matching the opaque area of the positive image. You can then OR the positive image
where anything ORed with black results in the original color. Comment out those
PaintPicture lines (one at a time), to see what they do....

HTH
LFS






 |  Next  |  Last
Pages: 1 2 3 4 5 6
Prev: Simple Obfuscation
Next: Flag test