[ANN] More about masks (+ sample stack)

Wilhelm Sanke sanke at hrz.uni-kassel.de
Fri Nov 25 09:45:00 EST 2011


Accompanying is a sample stack with a side-by-side comparison of a 
number of approaches produce and use masks and containing most of the 
discussions below 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 using graphics as selection 
tools with two-liners like in the "starter" script above, too.

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 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
<http://www.sanke.org/MetaMedia>







More information about the use-livecode mailing list