setStretchAmount(v)}
toolTip="Values above 5 should be used with caution.
"
/>
```
### UIComboBox
Items array keeps the combo in sync via useEffect.
```tsx
setSelectedIndex(i)}
/>
```
### UIViewList
Lists open PixInsight views; mode prop filters what is shown.
```tsx
setTargetView(view)}
stretchFactor={1}
/>
```
### UIGroupBox
With optional title checkbox for enable/disable sections.
```tsx
setClosingEnabled(v)}
spacing={5}
margin={5}
>
setClosingSize(v)} />
```
### UIStretch
Acts as a flexible spacer inside a sizer.
```tsx
{/* pushes next item to the right */}
{}} />
```
### UIScrollBox
Ref gives direct access to the ScrollBox for scroll events.
```tsx
const scrollRef = useRef(null);
scrollRef.current?.viewport.update()}
onVerticalScrollPosUpdated={() => scrollRef.current?.viewport.update()}
/>
```
```
--------------------------------
### Build PixInScript Project
Source: https://github.com/beshanoe/pixinscript/blob/master/docs/GettingStarted.md
Build all packages within the PixInScript monorepo using the 'npm run build' command. Alternatively, use 'npm run dev' to start the development environment for all examples, which recompiles scripts on changes.
```bash
npm run build
```
```bash
npm run dev
```
--------------------------------
### render()
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Mounts a React component tree into a new PixInsight Dialog. It handles the creation of the dialog, context setup, reconciliation, and displays the modal window.
```APIDOC
## `render()` — Mount a React component tree into a PixInsight Dialog
`render` is the main entry point exported by `@pixinscript/react`. It instantiates a `Dialog`, wraps it with `DialogContext`, drives the custom reconciler to populate the dialog's sizer tree with the component tree, and then calls `dialog.execute()` to show the modal window. The `options.dialog` object accepts any `Dialog` property (e.g., `windowTitle`, `userResizable`, `scaledMinWidth`).
### Parameters
- **component**: `React.ReactNode` - The root React component to render.
- **options**: `object` - Configuration options for the dialog and rendering.
- **options.debug**: `boolean` - If true, logs reconciler operations.
- **options.dialog**: `object` - Properties for the PixInsight `Dialog`.
- **options.dialog.windowTitle**: `string` - The title of the dialog window.
- **options.dialog.minWidth**: `number` - The minimum width of the dialog.
- **options.dialog.maxHeight**: `number` - The maximum height of the dialog.
- **options.dialog.userResizable**: `boolean` - Whether the user can resize the dialog.
### Request Example
```tsx
import React from "react";
import { render } from "@pixinscript/react";
import { UILabel, UIVerticalSizer } from "@pixinscript/ui";
function MyDialogContent() {
return (
);
}
render(, {
dialog: {
windowTitle: "My Custom Dialog",
minWidth: 300,
},
});
```
```
--------------------------------
### Build Specific PixInScript Scripts
Source: https://github.com/beshanoe/pixinscript/blob/master/docs/GettingStarted.md
Build and start the development environment for a specific script, like 'hello-world', using the '--filter' flag with 'npm run dev'.
```bash
npm run dev -- --filter hello-world
```
--------------------------------
### Develop PixInsight Script with Watch Mode
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Starts Webpack in watch mode for incremental recompiles on file changes. No ZIP is produced in dev mode. Reload PixInsight after rebuilds to see changes.
```bash
# Watch mode for the hello-world example (from monorepo root)
npm run dev -- --filter hello-world
# Or inside the script directory directly
pixinscript dev
# Output on each rebuild:
# Starting watch mode
# asset script.js 543 KiB [emitted]
# webpack compiled successfully
```
--------------------------------
### Build PixInScript Project
Source: https://github.com/beshanoe/pixinscript/blob/master/README.md
Compile the PixInScript project. This command bundles the script and prepares it for PixInsight.
```sh
npm run build
```
--------------------------------
### Build PixInScript with ZIP (Default)
Source: https://github.com/beshanoe/pixinscript/blob/master/README.md
Compiles the script and creates a ZIP archive ready for PixInsight. This is the default behavior of the build command.
```sh
pixinscript build
```
--------------------------------
### PixInScript Configuration in package.json
Source: https://context7.com/beshanoe/pixinscript/llms.txt
The CLI reads configuration from the 'pixinscript' key in package.json. 'featureId' and 'featureInfo' are required and injected as header comments.
```json
// package.json
{
"name": "hello-world",
"version": "1.0.0",
"pixinscript": {
"script": {
"featureId": "com.example.scripts.HelloWorld",
"featureInfo": "A simple Hello World PixInScript example"
}
},
"scripts": {
"build": "pixinscript build",
"dev": "pixinscript dev"
},
"dependencies": {
"@pixinscript/core": "^0.2.1",
"@pixinscript/react": "^0.2.1",
"@pixinscript/ui": "^0.2.1"
}
}
```
--------------------------------
### Zip PixInsight Script Files
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Creates a ZIP archive from the dist/ folder without recompiling. Useful for packaging after code signing. Custom filenames and internal paths can be specified.
```bash
# Default: produces dist/script.zip with files at the archive root
pixinscript zip
# Custom filename and internal directory path inside the ZIP
pixinscript zip -f my-script-v1.0.zip -p "PixInsight/Scripts/MyScript/"
# Full signed-script workflow:
pixinscript build --no-zip # 1. compile
# (sign dist/script.js externally)
pixinscript zip -f signed.zip -p "scripts/" # 2. package
```
--------------------------------
### Workflow for Signed Scripts
Source: https://github.com/beshanoe/pixinscript/blob/master/README.md
Steps for building and packaging signed scripts. It involves building without a ZIP, signing the JavaScript file, and then creating the final ZIP archive.
```sh
pixinscript build --no-zip
```
```sh
pixinscript zip -f signed-script.zip -p "pixinsight/"
```
--------------------------------
### Build PixInsight Script
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Compiles TypeScript/TSX source into a PixInsight-compatible script.js bundle. Use --no-zip to skip archive creation, which is necessary for code signing.
```bash
# Standard build — outputs dist/script.js and dist/script.zip
pixinscript build
# Build without ZIP (e.g., prior to code signing)
pixinscript build --no-zip
# Expected output:
# Building script
# asset script.js 543 KiB [emitted] (name: main)
# webpack 5.x.x compiled successfully in 4321 ms
```
--------------------------------
### Manage Image Windows in PixInsight
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Open, create, manipulate, and save image windows using the ImageWindow API. Use temporary off-screen windows for processing.
```typescript
// Open an image file and access its main view
const windows = ImageWindow.open("/path/to/image.fits");
const win = windows[0];
const view = win.mainView;
console.log(`Opened: ${win.filePath} (${view.image.width}×${view.image.height})`);
// Create a temporary off-screen processing window
const src = ImageWindow.activeWindow.currentView.image;
const processingWin = new ImageWindow(
src.width,
src.height,
src.numberOfChannels,
src.bitsPerSample,
src.isReal,
src.isColor
);
processingWin.hide();
processingWin.mainView.beginProcess();
processingWin.mainView.image.assign(src);
processingWin.mainView.endProcess();
// ... apply transforms ...
applyPixelMath(processingWin.mainView, 5);
// Export a Bitmap for painting in a ScrollBox viewport
const bitmap: Bitmap = processingWin.mainView.image.render();
// Save the result and close the window
processingWin.saveAs("/path/to/output.fits");
processingWin.forceClose();
```
--------------------------------
### Create ZIP Archive
Source: https://github.com/beshanoe/pixinscript/blob/master/README.md
Creates a ZIP archive from the 'dist' folder. Options include specifying a custom filename and an internal path structure within the ZIP.
```sh
pixinscript zip
```
```sh
pixinscript zip -f custom-name.zip -p "scripts/"
```
--------------------------------
### Build PixInScript without ZIP
Source: https://github.com/beshanoe/pixinscript/blob/master/README.md
Compiles the script without creating a ZIP archive. This is useful for scripts that require code signing before packaging.
```sh
pixinscript build --no-zip
```
--------------------------------
### Render React Component into PixInsight Dialog
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Use `render` to mount a React component tree into a new PixInsight Dialog. Options can configure dialog properties like title and size.
```tsx
import React, { useState } from "react";
import { render, useDialog } from "@pixinscript/react";
import {
UIVerticalSizer,
UILabel,
UIPushButton,
UIHorizontalSizer,
} from "@pixinscript/ui";
function ScriptDialog() {
const dialog = useDialog();
const [count, setCount] = useState(0);
const [visible, setVisible] = useState(false);
return (
{visible && }
setVisible((v) => !v)}
/>
setCount((c) => c + 1)} />
setCount((c) => c - 1)} />
dialog.ok()} />
);
}
render(, {
debug: false, // set true to log reconciler operations
dialog: {
windowTitle: "Hello World Script",
minWidth: 400,
maxHeight: 300,
userResizable: false,
},
});
```
--------------------------------
### Utilize Polyfilled Browser APIs in PixInsight
Source: https://context7.com/beshanoe/pixinscript/llms.txt
The @pixinscript/core/polyfill enables standard browser APIs like setTimeout, setInterval, and console methods within PixInsight scripts. It must be the first Webpack entry point.
```javascript
// Polyfill is loaded automatically by the CLI via webpack.config.ts:
// entry: ["@pixinscript/core/polyfill", "src/index"]
// After loading, these APIs work as expected inside PixInsight scripts:
timeout(() => {
console.log("runs after 500 ms using PixInsight Timer");
}, 500);
const id = setInterval(() => {
console.log("repeating every 1 s");
}, 1000);
clearInterval(id);
// console methods map to PixInsight Console:
console.log("info message"); // → Console.writeln(...)
console.warn("warning"); // → Console.warning(...)
console.error("error"); // → Console.critical(...)
```
--------------------------------
### directRender()
Source: https://context7.com/beshanoe/pixinscript/llms.txt
A lower-level API to render a React component tree into an existing PixInsight `Control` or `Sizer`, useful for embedding React sub-trees.
```APIDOC
## `directRender()` — Render into an arbitrary Control or Sizer
`directRender` is a lower-level API that lets you mount a React tree into any existing PixInsight `Control` or `Sizer` rather than creating a new top-level `Dialog`. Useful when embedding a React-managed sub-tree inside a manually constructed dialog or inside a `UIScrollBox` viewport.
### Parameters
- **component**: `React.ReactNode` - The root React component to render.
- **container**: `Control | Sizer` - The PixInsight Control or Sizer to render into.
### Request Example
```tsx
import React from "react";
import { directRender } from "@pixinscript/react";
import { UILabel, UIVerticalSizer } from "@pixinscript/ui";
// Assume `existingFrame` is a PixInsight Frame control already added to a dialog
const existingFrame = new Frame();
directRender(
,
existingFrame // container must be a Control or Sizer
);
// The frame's sizer is now managed by the React reconciler; subsequent state changes will update controls automatically.
```
```
--------------------------------
### Configure PixinscriptWebpackPlugin in Webpack
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Use this Webpack configuration to integrate the PixinscriptWebpackPlugin. Ensure optimization.minimize is false for PixInsight readability. The plugin injects required feature headers.
```typescript
import { PixinscriptWebpackPlugin } from "@pixinscript/webpack-plugin";
import * as path from "path";
import webpack = require("webpack");
const config: webpack.Configuration = {
entry: ["@pixinscript/core/polyfill", "./src/index"],
mode: "production",
optimization: { minimize: false }, // PixInsight requires readable source
module: {
rules: [
{ test: /\.tsx?$/, use: "ts-loader", exclude: /node_modules/ },
{
test: /\.m?jsx?$/,
use: {
loader: "babel-loader",
options: {
presets: [
["@babel/preset-env", { targets: { ie: "8" }, useBuiltIns: "entry", corejs: "3" }],
"@babel/preset-react",
],
},
},
},
],
},
resolve: { extensions: [".tsx", ".ts", ".js", ".jsx"] },
output: { filename: "script.js", path: path.resolve(__dirname, "dist") },
plugins: [
new PixinscriptWebpackPlugin({
featureId: "com.example.MyScript",
featureInfo: "My custom PixInsight processing script",
}),
// Resulting script.js will begin with:
// #feature-id com.example.MyScript
// #feature-info My custom PixInsight processing script
// (bundled JS follows)
],
};
```
--------------------------------
### Render React Component into Existing PixInsight Control
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Use `directRender` to mount a React component tree into an existing PixInsight `Control` or `Sizer`. This is useful for embedding React sub-trees within manually constructed dialogs.
```tsx
import React from "react";
import { directRender } from "@pixinscript/react";
import { UILabel, UIVerticalSizer } from "@pixinscript/ui";
// Assume `existingFrame` is a PixInsight Frame control already added to a dialog
const existingFrame = new Frame();
directRender(
,
existingFrame // container must be a Control or Sizer
);
// The frame's sizer is now managed by the React reconciler;
// subsequent state changes will update controls automatically.
```
--------------------------------
### useDialog()
Source: https://context7.com/beshanoe/pixinscript/llms.txt
A React context hook that provides access to the `Dialog` instance created by `render()`, allowing interaction with dialog methods like `ok()`, `cancel()`, and `newInstance()` from any component.
```APIDOC
## `useDialog()` — Access the enclosing Dialog from any component
A React context hook exported by `@pixinscript/react` that returns the `Dialog` instance created by `render()`. Use it to call `dialog.ok()`, `dialog.cancel()`, `dialog.newInstance()`, or any other `Dialog` method from deep within the component tree without prop-drilling.
### Returns
- **dialog**: `Dialog` - The PixInsight `Dialog` instance.
### Usage Example
```tsx
import React from "react";
import { useDialog } from "@pixinscript/react";
import { UIHorizontalSizer, UIPushButton, UIToolButton } from "@pixinscript/ui";
function DialogFooter() {
const dialog = useDialog();
return (
{
Parameters.set("version", "1.0");
dialog.newInstance();
}}
/>
dialog.cancel()} />
dialog.ok()} />
);
}
```
```
--------------------------------
### React-wrapped PixInsight UI Controls
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Use these components to integrate PixInsight controls into React applications. They accept native PixInsight properties as props and forward layout props to the parent Sizer. Components use React.forwardRef to expose the underlying PixInsight control instance.
```tsx
import React, {
useRef
} from "react";
import {
UIVerticalSizer, UIHorizontalSizer,
UILabel, UIEdit, UICheckBox,
UIComboBox, UINumericControl,
UISpinBox, UISlider, UITextBox,
UIGroupBox, UIViewList, UIStretch,
UIPushButton, UIScrollBox, UIToolButton,
UITabBox, UITreeBox,
} from "@pixinscript/ui";
// UINumericControl — built-in label + slider + edit with setPrecision/setValue
setStretchAmount(v)}
toolTip="Values above 5 should be used with caution.
"
/>
// UIComboBox — items array keeps the combo in sync via useEffect
setSelectedIndex(i)}
/>
// UIViewList — lists open PixInsight views; mode prop filters what is shown
setTargetView(view)}
stretchFactor={1}
/>
// UIGroupBox with optional title checkbox for enable/disable sections
setClosingEnabled(v)}
spacing={5}
margin={5}
>
setClosingSize(v)} />
// UIStretch — acts as a flexible spacer inside a sizer
{/* pushes next item to the right */}
{}} />
// UIScrollBox — ref gives direct access to the ScrollBox for scroll events
const scrollRef = useRef(null);
scrollRef.current?.viewport.update()}
onVerticalScrollPosUpdated={() => scrollRef.current?.viewport.update()}
/>
```
--------------------------------
### Boost Color Saturation with Akima Spline
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Enhances color saturation using the ColorSaturation process class with an Akima-spline curve. The 'satAmount' parameter controls the overall saturation boost.
```typescript
// Boost color saturation with an Akima-spline curve
export function applyColorSaturation(view: View, satAmount: number) {
const P = new ColorSaturation();
P.HS = [
[0.0, satAmount * 0.4],
[0.5, satAmount * 0.7],
[1.0, satAmount * 0.4],
];
P.HSt = ColorSaturation.prototype.AkimaSubsplines;
P.hueShift = 0.0;
P.executeOn(view);
}
```
--------------------------------
### Apply Hyperbolic Stretch with PixelMath
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Applies a hyperbolic stretch to an image using the PixelMath process class. Adjust the 'amount' parameter to control the intensity of the stretch.
```typescript
import type { View } from "@pixinscript/core"; // type only — runtime is global
// Apply a hyperbolic stretch using PixelMath
export function applyPixelMath(view: View, amount: number) {
const P = new PixelMath();
P.expression = `((3^${amount})*$T)/((3^${amount} - 1)*$T + 1)`;
P.executeOn(view);
}
```
--------------------------------
### Save and Load Script Parameters
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Persist script parameters using the global Parameters object. Load parameters only if they exist to avoid errors.
```typescript
// Define all parameter defaults in one place
export const ScriptParameters = {
amount: 5,
satAmount: 1,
removeGreen: false,
save() {
Parameters.set("amount", ScriptParameters.amount);
Parameters.set("satAmount", ScriptParameters.satAmount);
Parameters.set("removeGreen", ScriptParameters.removeGreen);
},
load() {
if (Parameters.has("amount"))
ScriptParameters.amount = Parameters.getReal("amount");
if (Parameters.has("satAmount"))
ScriptParameters.satAmount = Parameters.getReal("satAmount");
if (Parameters.has("removeGreen"))
ScriptParameters.removeGreen = Parameters.getBoolean("removeGreen");
},
};
// In your script entry point:
function main() {
if (Parameters.isGlobalTarget) {
Console.criticalln("Script cannot run in global context.");
return;
}
if (Parameters.isViewTarget) {
ScriptParameters.load();
applyPixelMath(Parameters.targetView, ScriptParameters.amount);
return;
}
render(, { dialog: { windowTitle: "My Script" } });
}
main();
```
--------------------------------
### Clone PixInScript Repository
Source: https://github.com/beshanoe/pixinscript/blob/master/docs/GettingStarted.md
Clone the PixInScript monorepo to work directly within it. This is recommended for contributing to TypeScript definitions and the project.
```bash
git clone https://github.com/beshanoe/pixinscript.git
cd pixinscript
```
--------------------------------
### Access Dialog Instance with useDialog Hook
Source: https://context7.com/beshanoe/pixinscript/llms.txt
The `useDialog` hook provides access to the `Dialog` instance created by `render()`. Use it to call dialog methods like `ok()`, `cancel()`, or `newInstance()` from any component within the dialog's tree.
```tsx
import React from "react";
import { useDialog } from "@pixinscript/react";
import { UIHorizontalSizer, UIPushButton, UIToolButton } from "@pixinscript/ui";
function DialogFooter() {
const dialog = useDialog();
return (
{/* Save parameters as a draggable script instance */}
{
// persist any Parameters before creating the instance
Parameters.set("version", "1.0");
dialog.newInstance();
}}
/>
dialog.cancel()} />
dialog.ok()} />
);
}
```
--------------------------------
### Use PJSR Enum Constants from @pixinscript/core
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Import and use typed enum constants from @pixinscript/core for PJSR flags and modes to ensure type safety and improve IDE autocompletion, avoiding raw integer literals.
```typescript
import {
TextAlign_Left,
TextAlign_VertCenter,
TextAlign_Right,
StdCursor_OpenHand,
StdCursor_ClosedHand,
FrameStyle_Box,
ColorSpace,
ImageOp,
Interpolation,
SampleType,
MorphOp,
} from "@pixinscript/core";
// Use in UI component props
// Use with native PixInsight API calls
const img = new Image();
img.colorSpace = ColorSpace.RGB;
const cursor = new Cursor(StdCursor_OpenHand);
controlRef.current!.viewport.cursor = cursor;
// Morphological operator type — avoids magic numbers
img.morphologicalTransformation(MorphOp.Dilation, [structureMatrix]);
```
--------------------------------
### useCombinedRefs Utility
Source: https://context7.com/beshanoe/pixinscript/llms.txt
A utility function to merge multiple refs onto a single element, useful when a component needs to expose its ref while also maintaining an internal ref.
```APIDOC
## `useCombinedRefs()` — Merge multiple refs onto one element
A utility exported from `@pixinscript/ui` that merges a forwarded outer ref with an internal `useRef`. Necessary whenever a component both exposes a ref to its parent and needs its own internal ref to the same native control.
```tsx
import React, { useRef } from "react";
import { UIScrollBox, useCombinedRefs } from "@pixinscript/ui";
const ScrollControl = React.forwardRef
(({ minWidth }, outerRef) => {
const innerRef = React.useRef(null);
// Both innerRef.current and outerRef.current will point to the same ScrollBox
const ref = useCombinedRefs(outerRef, innerRef);
React.useEffect(() => {
if (!ref.current) return;
ref.current.autoScroll = true;
ref.current.viewport.onPaint = (x0, y0, x1, y1) => {
const g = new Graphics(ref.current!.viewport);
g.fillRect(x0, y0, x1, y1, new Brush(0xff000000));
g.end();
};
}, []);
return ;
}
);
```
```
--------------------------------
### Extract Structures with Multiscale Linear Transform
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Detects and extracts star structures from an image using the Starlet transform via the MultiscaleLinearTransform process. Specify the minimum and maximum layers for structure detection.
```typescript
// Multiscale star structure detection via Starlet transform
export function extractStructures(
image: Image,
minLayer: number,
maxLayer: number
): Image {
const copy = new Image();
copy.assign(image);
const layers = [];
for (let i = 1; i <= maxLayer + 1; i++) {
layers.push([i >= minLayer && i <= maxLayer, true, 0.0, false, 3.0, 1.0, 1]);
}
const P = new MultiscaleLinearTransform();
P.layers = layers;
P.transform = MultiscaleLinearTransform.prototype.StarletTransform;
P.executeOn(copy);
return copy;
}
```
--------------------------------
### Subtract Images Pixel-by-Pixel
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Performs pixel-wise subtraction between two images, clamping the result at 0. This operation is performed on a copy of the first image, leaving the original unmodified.
```typescript
// Subtract two images pixel-by-pixel (clamp at 0)
export function subtract(image: Image, second: Image): Image {
const result = new Image();
result.assign(image);
result.initPixelIterator();
second.initPixelIterator();
const v1 = new Vector(), v2 = new Vector();
do {
result.getPixelValue(v1);
second.getPixelValue(v2);
v2.isLessThan(v1) ? v1.sub(v2) : v1.mul(0);
result.setPixelValue(v1);
second.nextPixel();
} while (result.nextPixel());
return result;
}
```
--------------------------------
### Merge Refs with useCombinedRefs Hook
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Use `useCombinedRefs` to merge an outer forwarded ref with an internal `useRef`. This is essential when a component needs to expose a ref to its parent while also using its own internal ref for the same native control. Ensure the ref type matches the native control.
```tsx
import React from "react";
import { UIScrollBox, useCombinedRefs } from "@pixinscript/ui";
const ScrollControl = React.forwardRef
(({ minWidth }, outerRef) => {
const innerRef = React.useRef(null);
// Both innerRef.current and outerRef.current will point to the same ScrollBox
const ref = useCombinedRefs(outerRef, innerRef);
React.useEffect(() => {
if (!ref.current) return;
ref.current.autoScroll = true;
ref.current.viewport.onPaint = (x0, y0, x1, y1) => {
const g = new Graphics(ref.current!.viewport);
g.fillRect(x0, y0, x1, y1, new Brush(0xff000000));
g.end();
};
}, []);
return ;
});
```
--------------------------------
### Blend Images Through a Mask
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Blends two images (source and destination) using a mask. The operation is defined as out = src*(1-mask) + dst*mask. This function operates on pixel data directly.
```typescript
// Blend two images through a mask: out = src*(1-mask) + dst*mask
export function assignThroughMask(src: Image, dst: Image, mask: Image): Image {
mask.colorSpace = src.colorSpace;
const result = new Image();
result.assign(src);
result.initPixelIterator();
dst.initPixelIterator();
mask.initPixelIterator();
const v1 = new Vector(), v2 = new Vector(), vM = new Vector();
const old = new Vector(v1.length);
do {
result.getPixelValue(v1);
dst.getPixelValue(v2);
mask.getPixelValue(vM);
v2.mul(vM);
for (let i = 0; i < v1.length; i++) old.at(i, v1.at(i));
v1.mul(vM);
old.sub(v1);
old.add(v2);
result.setPixelValue(old);
dst.nextPixel();
mask.nextPixel();
} while (result.nextPixel());
return result;
}
```
--------------------------------
### Remove Green Cast with SCNR
Source: https://context7.com/beshanoe/pixinscript/llms.txt
Removes green color casts from an image using the Subtractive Chromatic Noise Reduction (SCNR) process. It preserves lightness by default and uses the average neutral protection method.
```typescript
// Remove green cast using Subtractive Chromatic Noise Reduction
export function applySCNR(view: View) {
const P = new SCNR();
P.amount = 1.0;
P.protectionMethod = SCNR.prototype.AverageNeutral;
P.colorToRemove = SCNR.prototype.Green;
P.preserveLightness = true;
P.executeOn(view);
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.