Author Topic: JS: Apply mask programatically  (Read 7801 times)

Offline David Serrano

  • PTeam Member
  • PixInsight Guru
  • ****
  • Posts: 503
JS: Apply mask programatically
« on: 2007 September 12 15:23:27 »
Hi,

I'd like to use an image as mask of another one, and manage it automatically, without user intervention, in an script. Did a search in the objects box but found little...

Maybe Image.assign()?

Or ImageWindow.mask? Does this have to be another ImageWindow? Why not just an Image?

Is it worthwhile to ask all these little thingies instead of letting you spend your time doing more productive work? This is just frustrating for everyone I think :^/.
--
 David Serrano

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
JS: Apply mask programatically
« Reply #1 on: 2007 September 12 16:10:42 »
David,

I am glad to answer these little but important things. As long as I can answer in a reasonable amount of time, I'll try to answer as quick and extensively as possible. Otherwise I'll delay a bit, but anyway please don't stop asking! ;^)

Masks are always image windows in PixInsight. This is because every masking relation acts exclusively from a mask window to a masked window. So you can't use any Image object as a mask for an existing ImageWindow. You have to create an ImageWindow object, put your image inside it, then activate that ImageWindow as a mask. Here's a little code snippet:

Code: [Select]
// Get access to the active image window (or you can find
// any window with ImageWindow.windowById()).
var window = ImageWindow.activeWindow;

// Always handle situations where there are no active image window.
if ( window.isNull )
   throw Error( "I want a window to play..." );

// Get access to the active image.
var image = window.mainView.image;

// Our mask image must have the same dimensions as the target image.
// However, it can be a grayscale image of any sample type.
var maskImage = new Image( image.width, image.height, 1,
                           ColorSpace_Gray, 16, SampleType_Integer );

// ... Do something with your mask image here ...

// Create a one-pixel grayscale image (1x1x1).
var maskWindow = new ImageWindow( 1, 1, 1, 16, false, false, "FooMask" );

// The main view of our mask window.
var maskView = maskWindow.mainView;

// Inform the core application that we are going to modify this view's
// image. UndoFlag_NoSwapFile avoids generation of a swap file. Since we
// are working with a new image, a swap file is not needed because we
// don't want to undo anything for this window at this point.
maskView.beginProcess( UndoFlag_NoSwapFile );

// Transfer the mask image.
// ### Important: Note that after this transfer, maskImage is no longer
//                a reference to a valid Image object.
maskView.image.transfer( maskImage );

// Inform the core application that we have finished processing the view.
maskView.endProcess();

// Show the mask window, or your users will hate you...
maskWindow.show();

// Now activate the mask for the active window.
window.mask = maskWindow;


Hope this clarifies.
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline David Serrano

  • PTeam Member
  • PixInsight Guru
  • ****
  • Posts: 503
JS: Apply mask programatically
« Reply #2 on: 2007 September 13 01:48:32 »
Quote from: "Juan Conejero"
I am glad to answer these little but important things. As long as I can answer in a reasonable amount of time, I'll try to answer as quick and extensively as possible. Otherwise I'll delay a bit, but anyway please don't stop asking! ;^)


Oye, esa narizota es mía :^P. Bueno, ayer perdí un poco los nervios y a pesar de haber contado hasta 10 antes de escribir y antes de enviar, como mandan los cánones, he tenido que decir algo. Si vieras el mensaje original... :roll:.

Quote from: "Juan Conejero"
You have to create an ImageWindow object, put your image inside it, then activate that ImageWindow as a mask.


Lo intenté ayer, pero me topé con problemas de "read-only image" al hacer el .transfer. Lo voy a intentar aislar hoy, no sea que se trate de un bug; el código era de lo más sencillo y aún así no funcionaba bien. Esta tarde pruebo mi código y este tuyo de ahora y a ver qué averiguo.

Gracias!
--
 David Serrano

Offline David Serrano

  • PTeam Member
  • PixInsight Guru
  • ****
  • Posts: 503
JS: Apply mask programatically
« Reply #3 on: 2007 September 13 07:34:56 »
Quote from: "David Serrano"
Lo intenté ayer, pero me topé con problemas de "read-only image" al hacer el .transfer.


Bien, ya lo tengo aislado. Me gustaría que hubiera alguna mención a esto en la documentación final, ya que el comportamiento no me parece obvio.

El problema de "read-only image" lo tuve porque en lugar de hacer esto:

Code: [Select]
var maskView = maskWindow.mainView;
maskView.beginProcess( UndoFlag_NoSwapFile );
maskView.image.transfer( maskImage );
maskView.endProcess();


Estaba eliminando la variable, y haciendo esto:

Code: [Select]
maskWindow.mainView.beginProcess( UndoFlag_NoSwapFile );
maskWindow.mainView.image.transfer( maskImage );
maskWindow.mainView.endProcess();


Al hacer el .transfer, da error. Pero antes de toparme con este problema, también intenté eliminar la variable window arriba de todo, y me encontré con otro error que ya no recuerdo. Dado que a mitad del proceso se crea una ImageWindow nueva, supongo que la ventana activa cambia, y por eso es bueno tenerla almacenada desde el principio en una variable (window en este caso). Y pienso que lo que ocurre aquí al quitar la variable maskView viene a ser algo similar. De alguna manera y por alguna razón, a la hora de hacer el .transfer, la variable maskView del primer ejemplo y el maskWindow.mainView del segundo ejemplo no son lo mismo.

Para la gente como yo a la que no guste crear variables que sólo se van a usar durante un par de líneas de código y nada más, puede ser útil usar "with":

Code: [Select]
with (maskWindow.mainView) {
    beginProcess( UndoFlag_NoSwapFile );
    image.transfer( luma );
    endProcess();
}


Código limpio, y sin variables chorras.

Esto es peligroso... en lugar de hacer Tab+Barra espaciadora para hacer un preview de este mensaje, la mano se me fue sola al F9 (Compile & run) y se me abrió el sidebar de mozilla ;).
--
 David Serrano