How to apply a transparency mask onto a picture

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
marielle
Livecode Opensource Backer
Livecode Opensource Backer

How to apply a transparency mask onto a picture

Post by marielle » Wed Nov 15, 2006 9:38 pm

Code: Select all

export paint to file "Picture" with mask "../circlemask"
My take on this is this means save my image, and have the transparent areas saved in a file circlemask which is given a PBM format.

I have an image and a polygon graphic behind. I use blending/ink to obtain as result that only only the parts of the image that overlap with the polygon graphic show up.

This works beautifully within my revolution interface. A have a nice effect, by which you have an image of any shape within your interface.

Now...how do I do to save this in a PNG file, where the parts that appear as transparent in my interface also appear as transparent in the PNG file (so far, with what I have tried, got the masked part black).

I guess I need to use alphaMask.

Can I directly transform a polygon graphic into an alphaMask.

I guess the answer is no.

I would bet that I have to take a snapshot of it to create an image that contains the data for the alphaMask. What is it that this image would look like? How to apply the Mask on the color picture?

Anybody with a recipe to do that?
Last edited by marielle on Sat Nov 18, 2006 8:57 pm, edited 1 time in total.

marielle
Livecode Opensource Backer
Livecode Opensource Backer

How to apply a transparency mask onto a picture

Post by marielle » Sat Nov 18, 2006 8:47 pm

Provided there is an image "a1" , an image "a2", an image "t1", all of the same size (width x height), here is the way to apply a mask onto a picture.

A1 contains the mask. Any part of the image that is plain black (R=0, G=0, B=0) will be transformed into a transparent area into the target image T1 (which contains a copy of the imagedata of A2).

Code: Select all

on mouseUp
  put the imagedata of image "a1" into tMaskData
  put the imagedata of image "a2" into tImageData
  put mask_apply(tMaskData, tImageData) into tData
  set the alphadata of image "t1" to tData
  set the imagedata of image "t1" to tImageData
end mouseUp

function mask_apply pMaskData, pImageData
  put the length of pMaskData into maskLength
  if maskLength <> the length of pImageData then
    answer "Mask and Image are of different sizes ", maskLength, the length of pImageData
    exit mask_apply
  end if
  ---
  put 0 into tPos
  put empty into tAlpha
  ---
  repeat for (maskLength/4) times
    put charToNum(char tPos + 2 of pMaskData) into tR1
    put charToNum(char tPos + 3 of pMaskData) into tG1
    put charToNum(char tPos + 4 of pMaskData) into tB1
    if max(tR1,tG1,tB1) = 0 then put 1 into tA1 else put 255 into tA1
    put binaryEncode("C",tA1) after tAlpha
    add 4 to tPos
  end repeat
  ---
  return tAlpha
end mask_apply
The code is based on a stack "TestComposite/Composite Example" written by Chipp Walters.

DarScott
Posts: 227
Joined: Fri Jul 28, 2006 12:23 am
Contact:

Post by DarScott » Sun Nov 19, 2006 1:30 am

Yikes! Sorry, Marielle. I had thought I responded with an image level solution. I guess I must have hit preview and then closed the window or got a phone call or something.

marielle
Livecode Opensource Backer
Livecode Opensource Backer

Re: How to apply a transparency mask onto a picture

Post by marielle » Sun Nov 19, 2006 10:50 am

Humm, the logic of the program is not good enough. Why do I send pImageData as parameter mask_apply function if it is not being manipulated there?

Then the name of that function mask_apply is really not a good description of what it does. What the function does, really is upon receiving the imagedata of an image, convert any black area into an alpha transparency value. Ok, let's call it imagedata.convertBlack2Alpha

Hey, what is recommended elsewhere is a verb-object pair (convertBlack2Alpha). Where does that imagedata.convertBlack2Alpha type of naming convention come from?

I personally find it easier to understand what the function is about this way (especially when trying to use it 3 months after having written it). The truth is that the verb-object naming construct is recommended for use in object oriented languages, where the function is enclosed within a object class. I add imagedata in a way that somehow parallels this. In a sense, I consider black2alpha to be a method of the class of objects of type imagedata.

Okay, okay... but then why use "." when "_" could do? There is no object notation in xtalk. However the "." is allowed within function names. I use an object.xxx notation for all functions that are enclosed in class-like libraries. More about that later. That's just for me a way to rapidly identify functions that are ideal candidates to be moved into a common library.

(TBD stands for "To Be Done". Easy to use for a search)

Code: Select all

on mouseUp
  --
  --| 1. extracting the alpha values from an image mask
  put the imagedata of image "a1" into tMaskData
  put imagedata.convertBlack2Alpha(tMaskData) into tAlphaData
  --
  --| 2. extracting the imagedata of an image.
  put the imagedata of image "a2" into tImageData
  --
  --| 3. checking that mask and imagedata have the same size
  -- TBD. It would be cleaner to use tAlphaData instead of tMaskData
  --       (tAlphaData is of a length 1/4 of the imagedata)
  if the length of tMaskData <> the length of tImageData then
    answer "Mask and Image are of different sizes ", the length of tImageData, the length of tImageData
    exit mouseup
  end if
  --
  --| 4. Using alpha and image data to define a target image
  set the alphadata of image "t1" to tAlphaData
  set the imagedata of image "t1" to tImageData
end mouseUp



/* ____________________________________________________________
|
|  imagedata.convertBlack2Alpha
|
|   @Description:   Given some imagedata, convert any black pixel 
|           into a transparent one and returns the corresponding 
|           alphadata
|   @tested:          18 Nov 2006, 10pm -- working
*/
function imagedata.convertBlack2Alpha pMaskData
  /* TBD
   some validation is required. Should exit if pMaskData is 
   empty or not of the right type. 
   if datatype.validate("imagedata", pMaskData) is false then ...
  */
  ---
  put 0 into tPos
  put empty into tAlpha
  ---
  put the length of pMaskData into maskLength
  repeat for (maskLength/4) times
    put charToNum(char tPos + 2 of pMaskData) into tR1
    put charToNum(char tPos + 3 of pMaskData) into tG1
    put charToNum(char tPos + 4 of pMaskData) into tB1
    if max(tR1,tG1,tB1) = 0 then put 1 into tA1 else put 255 into tA1
    put binaryEncode("C",tA1) after tAlpha
    add 4 to tPos
  end repeat
  ---
  return tAlpha
end imagedata.convertBlack2Alpha
I didn't need it so I didn't implement it. But it wouldn't be that difficult to change this function to have the alpha value based on the % of opacity (% of blackness) of the points in the image.

Hint: The solution can be found in the stack testComposite.rev that can be found on Chipp's website.

PS. Thanks Darr for the intent ;)

Post Reply