[ANN]: More about masks (+ sample stack)

Wilhelm Sanke, FB01 sanke at hrz.uni-kassel.de
Sat Nov 29 04:11:36 EST 2008


Accompanying is a sample stack with a side-by-side comparison of a number of
approaches and containing most of the discussions with examples:

<http://www.sanke.org/Software/MoreAboutMasks.zip>

To run the stack you need Rev 2.9 or higher.

As a starter for this overview about how to produce masked images in Revolution
here is a "two-liner": 

on mouseup
crop image "to-be-masked" to the rect of image "SelectionOval"
set the alphadata of image "to-be-masked" to the alphadata of image "SelectionOval"
end mouseup

This is the essential "core"-procedure to create masked images, one of several
options. Usually such a two-liner would be sandwiched between "lock screen" and
hide "SelectionOval", and additionally there would be procedures in separate
buttons that determine what to do with the newly masked image, copy it
elsewhere, save it as an external file, patch it onto another image etc.

Image "to-be-masked" can be of any format, JPEG, GIF, PNG, image "SelectionOval"
must be a PNG of course.
If a graphic is used as a selection tool to determine the area of the resulting
masked image by capturing the transparency of the graphic with a snapshot, it is
*not* necessary to group graphic "SelectionOval". The selection graphics and
images in my sample stack *are* all grouped, but only because they are combined
with a "handle"-graphic for resizing and reshaping, otherwise a grouping of the
selection tools as a prerequisite to capture transparency is not required.

And, contrary to what the Rev docs state for "import snapshot" ("The format of
the resulting image depends on the current setting of the paintCompression
property."), since Rev version 2.7 the resulting images are invariably PNGs,
irrespective of what the current general setting of the paintcompression is,
RLE, PNG, or JPEG. Although with pre-2.7 versions the snapshot images would not
be PNGs, their formats are also not directly determined by the current
paintcompression. Paintcompression, however, plays a role for the speed of
processing imagedata and alphadata, RLE is fastest here, PNG the slowest setting.-

Graphics do contain transparency in the area outside of the shape of the
graphic, but this transparency is not represented by mask- and alphadata
properties of the graphic. We have to make detours to get at these data or to
reconstruct them. I hope that with future versions of Revolution graphics will
additionally have alphadata and maskdata properties. If that would be the case,
we could mask images with two-liners like in the "starter" script above.

What follows here is mainly an overview of such detours, of different attempts
to build masks along with the discussion of details and possible problems -
derived partly from individual experience, but much of it is based on the
results of a number of offlist-contacts and discussions during the last weeks
between James Hurley, Bernd Niggemann, and myself about problems, solutions, and
workarounds concerning the creation and application of masks to images. I have
also considered the onlist exchange between Scott Rossi and myself - at the time
after I had announced my first sample stack "Three Masks". On Ken Ray's website
(<http://www.sonsothunder.com/devres/revolution/tips/imag009.htm>, we found the
trick to produce transparency with the help of the "bucket tool". Ken presents a
two-liner from Jeanne DeVoto, which I managed to integrate into one of the
script examples.


==================

We could distinguish between two major categories: "Creating masks 'on the fly'"
and " Using prefabricated masks".


1. Creating masks "on the fly" 

 a) ====== "within"-functions"======

Jim Hurley has experimented with the native Rev "within" function to produce
masks and encountered the "edge problem", flat edges appearing at the right and
bottom of the masked images. Variations of the original script did not help to
overcome this problem.
Curiously enough, when you reverse the direction of the "scan" in Jim's script,
you get the edges on the left and on top.

I found three workarounds for this problem (but not a real solution of the basic
problem), namely "super-imposing" the edged alphamasks: 

1. Double scan from right and left, and then superimposing the two resulting masks.
2. Flipping - by script - the left half of the alphadata onto the right half,
and the top half onto the bottom half.
3. Capitalizing on the feature that since 2.9 flipped images preserve their
alphamasks (and flip them also), I run a normal scan, after that flip the image
horizontally and vertically, get the resulting second mask (then return the
image to its previous state) and superimpose the two masks.

All three workarounds produce masked images without edges.- 

Eventually Jim - as an expert in matters of mathematics and geometry - has now
developed a "within ellpse"-function on the basis of the mathematical properties
of an ellipse, which due to the more complex nature of the script takes a bit
longer to implement, but produces perfectly rounded masked images.

Script examples for the solutions and workarounds of this section are contained
in the sample stack, as are all solutions discussed below in the other sections.


b) ====== Comparing imagedata values from snapshot ======

First, I need to mention that "lock screen" prevents all kinds of "import
snapshot"-routines  when working on Windows. This is nowhere documented, at
least I could find nothing in the docs. "lock screen" would be handy to avoid
the flickering that happens when a snapshot is imported. On MacOS "lock screen"
does not prevent importing a snapshot and thus circumvents the flickering.

Bernd Niggemann offers an interesting alternative approach to determine the
pixels "within" the oval graphic by comparing the imagedata values inside and
outside of the graphic. He first hides the basic image (that is intended to be
masked) and imports a snapshot of the selection graphic on the background of the
card:

"import snapshot from rect (the rect of grc "oval") of this cd" (or "of window
tStackWindowID").

No transparency values are captured with this snapshot format. For creating a
mask he then assigns opaque values for the background colors of the graphic area
of the snapshot and transparent values for the backgroundcolor of the card. To
speed up the process of building the masks, he compares only the values of one
color channel, e.g. "green". This requires, of course, to make sure that the
values of the chosen color channel are indeed different. If, for instance, you
have got a red graphic on a white card background, then you cannot use the "red"
channel, because both the values for red and white would be "255".

The results of this approach are well rounded masked images without showing
"edge effects".

I have added an "export snapshot"-variant - exporting the snapshot to an
external file and the reimporting it immediately to avoid the flickering caused
by "import snapshot" on Windows (without "lock screen").

In another example in this section I have integrated the "bucket tool"-two-liner
for producing the transparency found by Jeanne DeVoto and listed by Ken Ray. As
Devin Asay found out, information about this solution is buried deeply in the
Rev "User Guide" - on page 380 of the PDF of Rev 3.0  - but is nowhere to be
found in the Dictionary

Finally I have added a script in which all three color channels are compared to
create the mask.

c) ====== Capturing the transparency of the selection graphic with a snapshot ======

Since engine version 2.7 it is possible to capture the transparency of a control
- maskdata and alphadata - along with an image of this control, provided the
snapshot is taken from the area of the control and the control in question
possesses mask- or alphadata like an image or a graphic. In the case of a
graphic, no real maskdata and alphadata as  directly accessible properties are
of course available, but they are then part of the image produced by the
snapshot of the graphic area. The "blendlevel" of an image or graphic -
connected to the "ink"-property - can *not* be captured with a snapshot.

The syntax is like this:

"snapshot of rect (trect: any rect-definition) of grc "X"" 
either with "import" or "export".

As the first example in this section I chose Scott Rossi's script (which had to
be slightly adapted to the settings of the sample stack) from his stack for Jim
Hurley

<http://www.tactilemedia.com/site_files/downloads/masked_abe.rev">.

Taking a snapshot from the area of the graphic, either by import or export,
produces an especially smooth border of the mask, provided the selection graphic
has its antialiased property set to true.

Scott's assumptions - expressed in the comments of his script - that the image
"to-be-masked" must be in PNG-format and the selection graphic (from which the
snapshot for the mask is being taken) must be grouped, could not be verified
here, at least not on Windows. See my introductory remarks in this context at
the beginning of this post.

I have added a variant for this section with "export snapshot" to avoid the
flickering, similar to the approach in the section featuring Bernd's solutions.

Concerning the role of paintcompression when taking a snapshot also see the
introductory remarks of this post.
To demonstrate the irrelevance of the paintcompression when taking a snapshot I
have added two scripts and buttons to this section of the sample stack where you
can choose the general paintcompression, one button to transfer the alphadata,
the other for the maskdata.

The only case where the current paintcompression matters here is that with
"JPEG" - i.e. for the general paintcompression, not for the format of the
involved images - you cannot transfer the "maskdata" from the snapshot image to
the basic image (the image "to-be-masked"), but you can do this for the "alphadata".

By the way, transferring the "maskdata" from the snapshot image to the
image-to-be-masked produces somewhat rougher, pixelated borders, transferring
the "alphadata" produces smooth borders, provided the "antialiased" of the
graphic from which the snapshot was taken was set to "true", as I have already
mentioned.

2. Using prefabricated masks

a) ====== Masks with Selection Graphics ======

For my own work, I have for quite a time preferred to work with "prefabricated"
masks, i.e. such masks that are not created simultaneously during the masking
procedure, but which have been created before in separate processes inside
Revolution or with external photo tools.

One advantage of such an approach is that you can more easily finetune the
character of the mask than with taking a snapshot from a graphic during the
masking process (the latter resulting in one single format: a mask with smooth
edges and otherwise full opaqueness, meaning without possible transitions of the
transparency towards the fringes of the mask etc.).

My favourite tool has been so far "RealDraw Pro" from
<http://www.mediachance.com>, a tool that unfortunately only runs on Windows.
Especially useful in "RealDraw Pro" is the "burst" transition. A "radial"
transition produces good results with varying transition areas only for oval
objects, with "burst" you can get 
fitting transitional transparency for any shape - semicircle, triangle, rhomb,
star, or any other kind of polygon.
I have also experimented with the new gradient tools of Rev 3.0. The process to
produce masks this way is somewhat complicated, but the resulting masks are fine.

The basic procedure to create masked images with ready-made masks is:

1. Select a portion of the image-to-be-masked with the selection graphic, in
which process the selection graphic can be moved, resized, and reshaped.
2. Adjust the rect of the (hidden) mask image to the rect of the selection graphic
3. Crop the image-to-be-masked to the rect
4. Transfer the alphamask of the mask image to the image-to-be-masked.

Much depends here on the quality of the mask. It should have been created with
its antialiased set to true, which is especially important when you want to
create masked images with sharp borders without transitional transparency. You
should set the resizequality of the mask to "best" -  to better adjust the mask
to the variable sizes of the chosen shape of the selection graphic. Bernd
Niggemann has recommended in this context to create a larger mask-image object
as the working template: Decreasing the size of the mask image during the
adaptation to the rect of the selection graphic affects the quality of the mask
less than the other way round.


In the corresponding section of the sample stack, you can try out masks with
varying degrees of transitional transparency and also of different non-oval shapes.

A final observation concerning the creation of masks inside Revolution and using
the "import snapshot" format:

If the resulting mask image is not first saved as an external file and then
imported again, meaning if it remains as freshly created inside a stack or was
just copied from another mask-producing stack, then this mask image will have a
different quality, which we might call a "pre-PNG".

Pre-PNGs behave somewhat differently than normal PNGs: You cannot transfer its
alphamask to the image-to-be-masked when the pre-PNG is hidden, at least not
several times with resizing. After you have resized a pre-PNG during the masking
process, you might find that it is suddenly "empty", but it can be restored when
you copy and paste it (it then appears in its original size and shape).
A workaround to overcome this problem is to store the mask in a custom property
of its own and then to "initialize" the mask each time before it is used in the
calling script:

"put the CPimg of img "transition" into img "transition""

But of course you can easily convert a pre-PNG to a full PNG by saving the image
as an external file.

b) ====== Mask Images as Selection Tool =======

At the end of this overview we return to the two-line "starter" script of the
beginning which requires an image as a selection tool instead of a graphic.

I have added one card to the sample stack where this option can be tried out.

One feature is especially helpful when using a resizable and reshapable
selection image: You can set the blendlevel of the image separately without
affecting its alphamask and thus create a selection image which lets you see the
image-to-be-masked underneath the selection area.

On this card you can choose between 10 shapes for the mask. There is only one
selection tool - consisting of a group with the mask image and a graphic
"handle" - into which these shapes are then inserted when you select one of the
shape buttons.

The produced masked images can then be saved as external files or transferred to
a "composition" card, on which you can arrange the collected masked images as a
new picture. The options on the composition card are stiil on a very preliminary
level, this serves only to indicate one of  further possibilities of using
masked images.

Best regards

Wilhelm Sanke
<www.sanke.org/MetaMedia>

--------------------------------------------------------
This mail sent through http://www.uni-kassel.de/www-mail




More information about the use-livecode mailing list