[Footnote: Bueno bueno, se va uno un fin de semana y vaya la que montáis; no se os puede dejar solos :lol:]
...the beginProcess/endProcess lines because I have little idea of what that methods do.
A JavaScript script is somewhat like an "unexpected guest" in PixInsight. This is because once you launch a script, its behavior is completely asynchronous with respect to the normal processing workflow in the PixInsight platform. In other words, PI has no way to predict what a script can do and when, two important things that are much more easily controlled with processing modules.
For this reason, I included a number of mechanisms in PixInsight's JavaScript runtime that force a script to behave synchronously when it wants to change an image. If your script needs to modify an image in an existing view, it must inform the core application first. This way, undo/redo buffers can be prepared as necessary, views can be locked to protect pixel data from other threads that can access them concurrently, expensive error recovery and marshaling mechanisms can be triggered, and so on: This is the beginProcess method of View:
void View.beginProcess( [undoFlags] )
If you don't call beginProcess(), your script has read-only access to the view. Note that read-only here refers to
any property of the view's image, not just to its pixel contents.
The optional undoFlags argument can be specified to control how the core application will prepare to undo things. If you disable generation of a swap file, e.g.:
fooBarView.beginProcess( UndoFlag_NoSwapFile );
your script is expected to
not modify pixel data in any way; if you do so, please have a good conversation with your users about your reasons.
Having explained beginProcess(), endProcess() is straightforward. Plainly put, if you don't call it anywhere after beginProcess(), PI will bite your ass. :lol:
This code creates a new ImageWindow and tries to copy the data from another image. As you can see, I've tried several ways Wink to no avail. I've also tried commenting out the beginProcess/endProcess lines because I have little idea of what that methods do. Didn't found a method called .copy, .duplicate or so.
Ok, let's start fixing a problem that you have already reported as a bug. Please copy the following into a new jsh file:
#ifndef __PJSR_ResizeMode_jsh
#define __PJSR_ResizeMode_jsh
/*
* Resizing modes for Image.resample()
*/
#define ResizeMode_RelativeDimensions 0 // Resize relative to current image dimensions
#define ResizeMode_AbsolutePixels 1 // Resize to absolute dimensions in pixels
#define ResizeMode_AbsoluteCentimeters 2 // Resize to absolute dimensions in centimeters
#define ResizeMode_AbsoluteInches 3 // Resize to absolute dimensions in inches
#define ResizeMode_ForceArea 4 // Force the total number of pixels and keep existing aspect ratio
#define ResizeMode_Default ResizeMode_RelativeDimensions
/*
* Absolute resizing modes for Image.resample()
*
* These modes are only applicable when the main resize mode is
* ResizeMode_AbsolutePixels, ResizeMode_AbsoluteCentimeters or
* ResizeMode_AbsoluteInches.
*/
#define AbsoluteResizeMode_ForceWidthAndHeight 0 // Force both dimensions
#define AbsoluteResizeMode_ForceWidth 1 // Force width, preserve aspect ratio
#define AbsoluteResizeMode_ForceHeight 2 // Force height, preserve aspect ratio
#define AbsoluteResizeMode_Default = AbsoluteResizeMode_ForceWidthAndHeight
#endif // __PJSR_ResizeMode_jsh
and save it as <pjsr/ResizeMode.jsh>. This file is missing in the current PJSR distribution, and the corresponding constants haven't been included in the object browser interface. This of course will be fixed in the next version.
Now here's the code that will do what you're trying to achieve:
#include <pjsr/Interpolation.jsh>
#include <pjsr/ResizeMode.jsh>
#include <pjsr/SampleType.jsh>
#include <pjsr/UndoFlag.jsh>
function test()
{
var w = ImageWindow.activeWindow;
if ( w.isNull )
throw Error( "No image window." );
var v = w.mainView;
var copy_img = new ImageWindow (
1, 1, 1, v.image.bitsPerSample,
v.image.sampleType == SampleType_Real,
false, "foobar23204" );
with ( copy_img.mainView )
{
beginProcess( UndoFlag_NoSwapFile );
image.assign( v.image );
image.resample( 640, 480, Interpolation_BicubicBSpline, ResizeMode_AbsolutePixels );
//image.resample( 640, 1, Interpolation_BicubicBSpline, ResizeMode_AbsolutePixels, AbsoluteResizeMode_ForceWidth );
endProcess();
}
copy_img.show();
copy_img.zoomToFit();
}
test();
The new image window (copy_img) doesn't need to be of the same dimensions and color space as the source image that you want to duplicate. Always create a 1x1x1 image window, then assign the source image to its main view into a beginProcess()...endProcess() sequence. A 1x1x1 image used in this way will reduce your script's memory requirements.
Note that you can resize an image mainly in two ways: relative to its current dimensions and absolute. Relative is the default mode.
When resizing relatively, the first two arguments of Image.resize() are (positive) real scaling ratios that will multiply current dimensions. When resizing in absolute mode, you can force width, height or both in several ways. I think that the ResizeMode.jsh explains this well.
A potential pitfall: be aware that something like:
foo.resize( 640, 480, Interpolation_Bicubic );
will likely be an error since you're asking PI to multiply current horizontal and vertical dimensions by 640 and 480, respectively. If you apply the above code to a moderately sized image, say 1024x1024, go imagine... some 3.7x10^12 bytes for a 32-bit RGB color image! I'm not sure of how memory management routines would handle such a request because it goes well beyond 32-bit numbers... so better don't write things like that.