### Bundle Application and Start Dockerized Nginx Source: https://github.com/infinitered/nsfwjs/blob/master/examples/manual_testing/README.md Run these commands to bundle the application and start a local Nginx server. This setup is used to avoid CORS issues during manual testing. ```sh yarn bundle ``` ```sh docker-compose up -d ``` ```sh http://localhost/data/index.html ``` -------------------------------- ### Build and Run Node.js NSFWJS Demo Source: https://github.com/infinitered/nsfwjs/blob/master/examples/node_demo/README.md Commands to build the project, install dependencies for the Node.js demo, and start the Express server. ```bash yarn build yarn --cwd examples/node_demo install yarn --cwd examples/node_demo start ``` -------------------------------- ### Install NSFWJS and TensorFlow.js Source: https://context7.com/infinitered/nsfwjs/llms.txt Install the necessary peer dependency and the NSFWJS library using yarn or npm. ```bash # Install peer dependency yarn add @tensorflow/tfjs # Install NSFWJS yarn add nsfwjs ``` ```bash # For Node.js (better performance) npm install nsfwjs @tensorflow/tfjs-node ``` -------------------------------- ### Install WebGPU Backend for TensorFlow.js Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Installs the WebGPU backend for TensorFlow.js, which often provides the fastest performance on supported browsers and hardware. ```bash yarn add @tensorflow/tfjs-backend-webgpu ``` -------------------------------- ### Install NSFWJS and TensorFlow.js Node Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Install the NSFWJS library and the TensorFlow.js Node.js backend using npm for server-side applications. ```bash $ npm install nsfwjs $ npm install @tensorflow/tfjs-node ``` -------------------------------- ### Install WASM Backend for TensorFlow.js Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Installs the WASM backend for TensorFlow.js. This is useful as a fallback when WebGL is unavailable or restricted. ```bash yarn add @tensorflow/tfjs-backend-wasm ``` -------------------------------- ### Load Default NSFWJS Model Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Loads the default NSFWJS model. This is the simplest way to get started. ```javascript const model = nsfwjs.load(); // Default: "MobileNetV2" ``` -------------------------------- ### Install NSFWJS and TensorFlow.js Peer Dependency Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Installs NSFWJS and its peer dependency, TensorFlow.js, using yarn. Add TensorFlow.js if your project doesn't already include it. ```bash # peer dependency $ yarn add @tensorflow/tfjs # install NSFWJS $ yarn add nsfwjs ``` -------------------------------- ### Send Image to NSFWJS API Source: https://github.com/infinitered/nsfwjs/blob/master/examples/node_demo/README.md Example using curl to send an image file via multipart/form-data to the Node.js NSFWJS server's /nsfw endpoint for classification. ```bash curl -X POST http://localhost:8080/nsfw \ -F "image=@/path/to/image.jpg" ``` -------------------------------- ### Core entrypoint with selective model bundling (`nsfwjs/core`) Source: https://context7.com/infinitered/nsfwjs/llms.txt The `nsfwjs/core` entrypoint omits all built-in model definitions by default, enabling tree-shaking. Pass only the models needed via `modelDefinitions`. ```APIDOC ## load — Core entrypoint with selective model bundling (`nsfwjs/core`) The `nsfwjs/core` entrypoint omits all built-in model definitions by default, enabling tree-shaking. Pass only the models needed via `modelDefinitions`. ### Usage ```js import { load } from "nsfwjs/core"; import { MobileNetV2Model } from "nsfwjs/models/mobilenet_v2"; import { MobileNetV2MidModel } from "nsfwjs/models/mobilenet_v2_mid"; import { InceptionV3Model } from "nsfwjs/models/inception_v3"; // Only MobileNetV2 is bundled into the app const model = await load("MobileNetV2", { modelDefinitions: [MobileNetV2Model], }); // Multiple models available to select from const multiModel = await load("MobileNetV2Mid", { modelDefinitions: [MobileNetV2Model, MobileNetV2MidModel], type: "graph", }); // Throws — named model not in registry try { await load("MobileNetV2", { modelDefinitions: [] }); // Error: provided models registry } catch (err) { console.error(err.message); } // Load from URL via core — no bundled models pulled into bundle const hostedModel = await load("https://cdn.example.com/models/mobilenet_v2/", { modelDefinitions: [], // empty ok when using URL }); ``` ``` -------------------------------- ### Load Model with Core Entrypoint (Selective Bundling) Source: https://context7.com/infinitered/nsfwjs/llms.txt Use the `nsfwjs/core` entrypoint to omit built-in models by default, enabling tree-shaking. Pass only the required models via `modelDefinitions`. Handles loading from URLs without bundling models. ```javascript import { load } from "nsfwjs/core"; import { MobileNetV2Model } from "nsfwjs/models/mobilenet_v2"; import { MobileNetV2MidModel } from "nsfwjs/models/mobilenet_v2_mid"; import { InceptionV3Model } from "nsfwjs/models/inception_v3"; // Only MobileNetV2 is bundled into the app const model = await load("MobileNetV2", { modelDefinitions: [MobileNetV2Model], }); // Multiple models available to select from const multiModel = await load("MobileNetV2Mid", { modelDefinitions: [MobileNetV2Model, MobileNetV2MidModel], type: "graph", }); // Throws — named model not in registry try { await load("MobileNetV2", { modelDefinitions: [] }); // Error: provided models registry } catch (err) { console.error(err.message); } // Load from URL via core — no bundled models pulled into bundle const hostedModel = await load("https://cdn.example.com/models/mobilenet_v2/", { modelDefinitions: [], // empty ok when using URL }); ``` -------------------------------- ### Load a model (default entrypoint) Source: https://context7.com/infinitered/nsfwjs/llms.txt Loads one of the three bundled models by name, or falls back to `MobileNetV2` when called with no arguments. All bundled model definitions are included automatically. ```APIDOC ## load — Load a model (default entrypoint) Loads one of the three bundled models by name, or falls back to `MobileNetV2` when called with no arguments. All bundled model definitions are included automatically. ### Usage ```js import * as nsfwjs from "nsfwjs"; // Default: MobileNetV2 (224×224 layers model) const model = await nsfwjs.load(); // Explicit named model — "MobileNetV2" | "MobileNetV2Mid" | "InceptionV3" const midModel = await nsfwjs.load("MobileNetV2Mid"); const inceptModel = await nsfwjs.load("InceptionV3"); // Load from a self-hosted URL (reduces bundle size — binary weights instead of base64) const hosted = await nsfwjs.load("https://yoursite.com/models/mobilenet_v2/"); // Load from IndexedDB cache (browser) const cached = await nsfwjs.load("indexeddb://myModel"); // Load MobileNetV2Mid from URL — graph model requires { type: 'graph' } const graphModel = await nsfwjs.load("/models/mobilenet_v2_mid/", { type: "graph" }); // InceptionV3 requires size: 299 const v3 = await nsfwjs.load("/models/inception_v3/", { size: 299 }); ``` ``` -------------------------------- ### Load a Model with NSFWJS (Default Entrypoint) Source: https://context7.com/infinitered/nsfwjs/llms.txt Load one of the three bundled models by name. Falls back to 'MobileNetV2' if no argument is provided. Supports loading from URLs, IndexedDB, or with specific configurations for graph models and image sizes. ```javascript import * as nsfwjs from "nsfwjs"; // Default: MobileNetV2 (224×224 layers model) const model = await nsfwjs.load(); // Explicit named model — "MobileNetV2" | "MobileNetV2Mid" | "InceptionV3" const midModel = await nsfwjs.load("MobileNetV2Mid"); const inceptModel = await nsfwjs.load("InceptionV3"); // Load from a self-hosted URL (reduces bundle size — binary weights instead of base64) const hosted = await nsfwjs.load("https://yoursite.com/models/mobilenet_v2/"); // Load from IndexedDB cache (browser) const cached = await nsfwjs.load("indexeddb://myModel"); // Load MobileNetV2Mid from URL — graph model requires { type: 'graph' } const graphModel = await nsfwjs.load("/models/mobilenet_v2_mid/", { type: "graph" }); // InceptionV3 requires size: 299 const v3 = await nsfwjs.load("/models/inception_v3/", { size: 299 }); ``` -------------------------------- ### TensorFlow.js Backend Selection for NSFWJS Source: https://context7.com/infinitered/nsfwjs/llms.txt Demonstrates how to configure TensorFlow.js backends before loading the NSFWJS model. It covers automatic best-backend selection, explicit WebGPU, and WASM fallback, along with enabling production mode. ```javascript import * as tf from "@tensorflow/tfjs"; import "@tensorflow/tfjs-backend-webgpu"; import "@tensorflow/tfjs-backend-wasm"; import { setWasmPaths } from "@tensorflow/tfjs-backend-wasm"; import * as nsfwjs from "nsfwjs"; // Automatic best-backend selection (recommended) await tf.ready(); const model = await nsfwjs.load(); // Explicit WebGPU (fastest on supported hardware) await tf.setBackend("webgpu"); await tf.ready(); // WASM fallback (for environments without WebGL) setWasmPaths("https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm/dist/"); await tf.setBackend("wasm"); await tf.ready(); // Production: enable prod mode before loading model tf.enableProdMode(); const prodModel = await nsfwjs.load("https://yoursite.com/models/mobilenet_v2/"); ``` -------------------------------- ### Load NSFWJS in Browser with Script Tags Source: https://context7.com/infinitered/nsfwjs/llms.txt Load NSFWJS in a browser without a bundler using pre-built script tags. Ensure TensorFlow.js is loaded first. ```html ``` -------------------------------- ### Load NSFWJS Model from Directory Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Loads a model from a specified directory path. Ensure the directory contains `model.json` and associated files. ```javascript const model = nsfwjs.load("/path/to/mobilenet_v2/"); ``` -------------------------------- ### Configure and Set WASM Backend for TensorFlow.js Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Configures the path to WASM binaries and sets the TensorFlow.js backend to 'wasm'. Useful for environments without standard bundlers. ```javascript import * as tf from "@tensorflow/tfjs"; import { setWasmPaths, } from "@tensorflow/tfjs-backend-wasm"; import "@tensorflow/tfjs-backend-wasm"; // If you aren't using a standard bundler, set the path to the .wasm binaries. setWasmPaths("https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm/dist/"); await tf.setBackend("wasm"); await tf.ready(); ``` -------------------------------- ### Selective Model Loading with NSFWJS Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Import specific models for tree-shaking and pass them to the load function. Loading with an empty model registry will cause an error. ```javascript import { load } from "nsfwjs/core"; import { MobileNetV2Model } from "nsfwjs/models/mobilenet_v2"; import { MobileNetV2MidModel } from "nsfwjs/models/mobilenet_v2_mid"; const model = await load("MobileNetV2", { modelDefinitions: [MobileNetV2Model, MobileNetV2MidModel], }); ``` ```javascript await load("MobileNetV2", { modelDefinitions: [] }); // throws ``` -------------------------------- ### Selective Model Bundles Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Demonstrates how to selectively import and load specific model bundles for tree-shaking purposes. ```APIDOC ## load with modelDefinitions ### Description Loads a specific model by providing model definitions, allowing for selective bundling and tree-shaking. ### Method `nsfwjs.load(modelName, { modelDefinitions: [...] })` ### Parameters - **modelName** (string) - The name of the model to load (e.g., "MobileNetV2"). - **modelDefinitions** (array) - An array of model definitions to include. If empty, named bundled model loads will fail. ### Request Example ```javascript import { load } from "nsfwjs/core"; import { MobileNetV2Model } from "nsfwjs/models/mobilenet_v2"; import { MobileNetV2MidModel } from "nsfwjs/models/mobilenet_v2_mid"; const model = await load("MobileNetV2", { modelDefinitions: [MobileNetV2Model, MobileNetV2MidModel], }); // Example of failure with empty modelDefinitions // await load("MobileNetV2", { modelDefinitions: [] }); // throws ``` ### Response - **model** (object) - The loaded NSFWJS model object. ``` -------------------------------- ### Automatic Backend Selection with TensorFlow.js Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Allows TensorFlow.js to automatically select the best available backend. Ensure necessary backends are imported and `tf.ready()` is called. ```javascript import * as tf from "@tensorflow/tfjs"; import "@tensorflow/tfjs-backend-webgpu"; import "@tensorflow/tfjs-backend-wasm"; import * as nsfwjs from "nsfwjs"; await tf.ready(); const model = await nsfwjs.load(); ``` -------------------------------- ### Pinned Backend Selection with TensorFlow.js Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Explicitly sets the TensorFlow.js backend to 'webgpu' for deterministic behavior. Ensure the backend is imported and `tf.ready()` is called. ```javascript import * as tf from "@tensorflow/tfjs"; import "@tensorflow/tfjs-backend-webgpu"; await tf.setBackend("webgpu"); await tf.ready(); ``` -------------------------------- ### model.classify (Node.js) Source: https://context7.com/infinitered/nsfwjs/llms.txt Demonstrates how to use the `model.classify` method in a Node.js environment using `@tensorflow/tfjs-node`. It shows how to read an image file, decode it into a tensor, perform classification, and manage tensor memory. ```APIDOC ## `model.classify` — Node.js usage Use `@tensorflow/tfjs-node` for server-side classification. Decode images into `tf.Tensor3D` with `tf.node.decodeImage`. ```js const tf = require("@tensorflow/tfjs-node"); const nsfw = require("nsfwjs"); const fs = require("fs"); async function classifyFile(filePath) { const model = await nsfw.load(); const imageBuffer = fs.readFileSync(filePath); // decodeImage returns Tensor3D for 3-channel images const image = tf.node.decodeImage(imageBuffer, 3); try { const predictions = await model.classify(image); console.log("Predictions:", predictions); // [ // { className: "Neutral", probability: 0.87 }, // ... // ] return predictions; } finally { image.dispose(); // Must dispose tensors manually model.dispose(); } } classifyFile("./photo.jpg"); ``` ``` -------------------------------- ### Load Model with Custom Size Option Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Loads a model and specifies its expected input size using the `size` option. This is useful for models with dimensions other than the default 224x224. ```javascript const model = nsfwjs.load("/path/to/inception_v3/", { size: 299 }); ``` -------------------------------- ### Include NSFWJS in Browser with Script Tags Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Include the necessary NSFWJS model files and the main bundle using script tags in your HTML. Ensure all files are hosted alongside your project. ```html ``` -------------------------------- ### Enable Production Mode for NSFWJS Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Enable production mode before loading the NSFWJS model for performance in production environments. Ensure TensorFlow.js is imported. ```javascript import * as tf from "@tensorflow/tfjs"; import * as nsfwjs from "nsfwjs"; tf.enableProdMode(); //... let model = await nsfwjs.load(`${urlToNSFWJSModel}`); ``` -------------------------------- ### Load NSFWJS Model from Custom URL (Core) Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Imports `load` from `nsfwjs/core` to load a model from a custom URL. This is recommended for smaller app bundles as it avoids including built-in model definitions. ```javascript import { load } from "nsfwjs/core"; const model = await load("/path/to/mobilenet_v2/model.json"); ``` -------------------------------- ### Classify Image with NSFWJS Source: https://github.com/infinitered/nsfwjs/blob/master/examples/minimal_demo/index.html Load the NSFWJS model and classify an image. Ensure the image is loaded before classification. Predictions are logged to the console. ```javascript // const nsfwjs = require('nsfwjs') const img = new Image(); img.crossOrigin = "anonymous"; // some image here img.src = "https://i.imgur.com/Kwxetau.jpg"; img.onload = function () { // Load the model. nsfwjs.load("MobileNetV2Mid").then((model) => { // Classify the image. model.classify(img).then((predictions) => { console.log("Predictions", predictions); }); }); }; ``` -------------------------------- ### Enable Type-Aware ESLint Rules Source: https://github.com/infinitered/nsfwjs/blob/master/examples/nsfw_demo/README.md Configure ESLint to use type-aware lint rules by extending recommendedTypeChecked, strictTypeChecked, or stylisticTypeChecked configurations. Ensure project configurations are correctly specified in parserOptions. ```javascript export default defineConfig([ globalIgnores(["dist"]), { files: ["**/*.{ts,tsx}"], extends: [ // Other configs... // Remove tseslint.configs.recommended and replace with this tseslint.configs.recommendedTypeChecked, // Alternatively, use this for stricter rules tseslint.configs.strictTypeChecked, // Optionally, add this for stylistic rules tseslint.configs.stylisticTypeChecked, // Other configs... ], languageOptions: { parserOptions: { project: ["./tsconfig.node.json", "./tsconfig.app.json"], tsconfigRootDir: import.meta.dirname, }, // other options... }, }, ]); ``` -------------------------------- ### Load Graph Model with Options Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Loads a graph-type model and specifies the model type in the options. Graph models require this explicit type declaration. ```javascript /* You may need to load this model with graph type */ const model = nsfwjs.load("/path/to/mobilenet_v2_mid/", { type: 'graph' }); ``` -------------------------------- ### Create NSFW Image Upload Endpoint with Express Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Set up an Express.js server to handle multipart/form-data image uploads and classify them using NSFWJS. The model is loaded once to optimize performance. ```javascript const express = require("express"); const multer = require("multer"); const jpeg = require("jpeg-js"); const tf = require("@tensorflow/tfjs-node"); const nsfw = require("nsfwjs"); const app = express(); const upload = multer(); let _model; const convert = async (img) => { // Decoded image in UInt8 Byte array const image = await jpeg.decode(img, { useTArray: true }); const numChannels = 3; const numPixels = image.width * image.height; const values = new Int32Array(numPixels * numChannels); for (let i = 0; i < numPixels; i++) for (let c = 0; c < numChannels; ++c) values[i * numChannels + c] = image.data[i * 4 + c]; return tf.tensor3d(values, [image.height, image.width, numChannels], "int32"); }; app.post("/nsfw", upload.single("image"), async (req, res) => { if (!req.file) res.status(400).send("Missing image multipart/form-data"); else { const image = await convert(req.file.buffer); const predictions = await _model.classify(image); image.dispose(); res.json(predictions); } }); const load_model = async () => { _model = await nsfw.load(); }; // Keep the model in memory, make sure it's loaded only once load_model().then(() => app.listen(8080)); // curl --request POST localhost:8080/nsfw --header 'Content-Type: multipart/form-data' --data-binary 'image=@/full/path/to/picture.jpg' ``` -------------------------------- ### Load Model Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Loads the NSFWJS model. You can optionally specify a model to host on your own or use a different model from the ones available. ```APIDOC ## load ### Description Loads the NSFWJS model. This function is asynchronous and returns a Promise that resolves with the loaded model. ### Method `nsfwjs.load()` ### Parameters None ### Request Example ```javascript import * as nsfwjs from "nsfwjs"; const model = await nsfwjs.load(); ``` ### Response - **model** (object) - The loaded NSFWJS model object, which has a `classify` method. ``` -------------------------------- ### Load and Classify Image with NSFWJS Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Basic usage of NSFWJS to load a model and classify an image. Ensure the image element exists in the DOM. ```javascript import * as nsfwjs from "nsfwjs"; const img = document.getElementById("img"); // If you want to host models on your own or use different model from the ones available, see the section "Host your own model". const model = await nsfwjs.load(); // Classify the image const predictions = await model.classify(img); console.log("Predictions: ", predictions); ``` -------------------------------- ### Load Model Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Loads the NSFWJS model. It can load default models, specific bundled models, or custom models from a provided URL or path. Options for model type and size can be specified. ```APIDOC ## `load` the model Before you can classify any image, you'll need to load the model. ```js const model = nsfwjs.load(); // Default: "MobileNetV2" ``` You can use the optional first parameter to specify which model you want to use from the three built-in bundled models. Defaults to: `"MobileNetV2"`. ```js const model = nsfwjs.load("MobileNetV2Mid"); // "MobileNetV2" | "MobileNetV2Mid" | "InceptionV3" ``` If you are hosting your own model via URL and want the smallest app bundle, import `load` from `nsfwjs/core` instead of `nsfwjs`. ```js import { load } from "nsfwjs/core"; const model = await load("/path/to/mobilenet_v2/model.json"); ``` ```js const model = nsfwjs.load("/path/to/mobilenet_v2/"); ``` If you're using a model that needs an image of dimension other than 224x224, you can pass the size in the options parameter. ```js /* You may need to load this model with graph type */ const model = nsfwjs.load("/path/to/mobilenet_v2_mid/", { type: 'graph' }); ``` ```js const model = nsfwjs.load("/path/to/inception_v3/", { size: 299 }); ``` ### Parameters Initial Load: 1. URL or path to folder containing `model.json`. 2. Optional object with size or type property that your model expects. Subsequent Load: 1. IndexedDB path. 2. Optional object with size or type property that your model expects. **Returns** - Ready to use NSFWJS model object ``` -------------------------------- ### Load Specific NSFWJS Model Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Loads a specific NSFWJS model by name. Use this to choose between 'MobileNetV2', 'MobileNetV2Mid', or 'InceptionV3'. ```javascript const model = nsfwjs.load("MobileNetV2Mid"); // "MobileNetV2" | "MobileNetV2Mid" | "InceptionV3" ``` -------------------------------- ### Classify Images with NSFWJS Source: https://github.com/infinitered/nsfwjs/blob/master/examples/manual_testing/data/index.html Loads the NSFWJS model and classifies all images on the page. Use this to test model accuracy on different image formats. ```javascript nsfwjs.load("MobileNetV2Mid").then(model => { const images = document.querySelectorAll('img') for (let i = 0; i < images.length; i++) { model.classify(images[i], 3) .then(predictions => showResults(images[i], predictions, true)) .catch(error => showError(images[i], error)) } }) ``` -------------------------------- ### Model Caching with IndexedDB in Browser Source: https://context7.com/infinitered/nsfwjs/llms.txt Saves a model to IndexedDB on first load to avoid re-downloading on subsequent page loads. Handles cache misses by loading from a hosted URL and persisting the model. ```javascript import * as nsfwjs from "nsfwjs"; const MODEL_KEY = "indexeddb://nsfwjs-mobilenet-v2"; async function getModel() { let model; try { // Attempt to load from IndexedDB cache model = await nsfwjs.load(MODEL_KEY); console.log("Loaded from IndexedDB cache"); } catch { // Cache miss — load from hosted URL and persist model = await nsfwjs.load("https://yoursite.com/models/mobilenet_v2/"); await model.model.save(MODEL_KEY); console.log("Model saved to IndexedDB"); } return model; } const model = await getModel(); const img = document.getElementById("photo"); const predictions = await model.classify(img); console.log(predictions); ``` -------------------------------- ### Web Worker with IndexedDB Caching for Production Source: https://context7.com/infinitered/nsfwjs/llms.txt Offloads model loading and inference to a Web Worker to keep the main thread responsive. It attempts to load from IndexedDB first and falls back to a bundled model if the cache is missed. ```typescript // nsfwjs.worker.ts import { load } from "nsfwjs/core"; import { MobileNetV2Model, MobileNetV2MidModel, InceptionV3Model } from "nsfwjs/models/mobilenet_v2"; import type { ModelName, NSFWJS, PredictionType } from "nsfwjs"; let model: NSFWJS | null = null; onmessage = async (event: MessageEvent<{ type: string; modelName?: ModelName; file?: File }>) => { const { type, modelName, file } = event.data; if (type === "load" && modelName) { try { // Try IndexedDB first, fall back to bundled model try { model = await load(`indexeddb://${modelName}`, {}); } catch { model = await load(modelName, { modelDefinitions: [MobileNetV2Model, MobileNetV2MidModel, InceptionV3Model], }); await model.model.save(`indexeddb://${modelName}`); } postMessage({ modelLoaded: true }); } catch (err) { postMessage({ error: err instanceof Error ? err.message : "Failed" }); } } if (type === "predict" && file && model) { const bitmap = await createImageBitmap(file); const canvas = new OffscreenCanvas(bitmap.width, bitmap.height); const ctx = canvas.getContext("2d")!; ctx.drawImage(bitmap, 0, 0); const imageData = ctx.getImageData(0, 0, bitmap.width, bitmap.height); const predictions: PredictionType[] = await model.classify(imageData); bitmap.close(); postMessage({ predictions }); } }; // main.ts — usage const worker = new Worker(new URL("./nsfwjs.worker.ts", import.meta.url), { type: "module" }); worker.postMessage({ type: "load", modelName: "MobileNetV2" }); worker.onmessage = (e) => { if (e.data.modelLoaded) { const fileInput = document.querySelector("#fileInput")!; worker.postMessage({ type: "predict", file: fileInput.files![0] }); } if (e.data.predictions) { console.log("Predictions:", e.data.predictions); } }; ``` -------------------------------- ### Classify Image in Node.js with NSFWJS Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Use NSFWJS in a Node.js application to classify an image fetched via HTTP. Ensure to manage tensor memory by disposing of images after use. ```javascript const axios = require("axios"); //you can use any http client const tf = require("@tensorflow/tfjs-node"); const nsfw = require("nsfwjs"); async function fn() { const pic = await axios.get(`link-to-picture`, { responseType: "arraybuffer", }); const model = await nsfw.load(); // To load a local model, nsfw.load('file://./path/to/model/') // Image must be in tf.tensor3d format // you can convert image to tf.tensor3d with tf.node.decodeImage(Uint8Array,channels) const image = await tf.node.decodeImage(pic.data, 3); const predictions = await model.classify(image); image.dispose(); // Tensor memory must be managed explicitly (it is not sufficient to let a tf.Tensor go out of scope for its memory to be released). console.log(predictions); } fn(); ``` -------------------------------- ### Add React-Specific ESLint Rules Source: https://github.com/infinitered/nsfwjs/blob/master/examples/nsfw_demo/README.md Integrate eslint-plugin-react-x and eslint-plugin-react-dom to enable lint rules specifically for React and React DOM development. This enhances code quality and adherence to React best practices. ```javascript // eslint.config.js import reactX from "eslint-plugin-react-x"; import reactDom from "eslint-plugin-react-dom"; export default defineConfig([ globalIgnores(["dist"]), { files: ["**/*.{ts,tsx}"], extends: [ // Other configs... // Enable lint rules for React reactX.configs["recommended-typescript"], // Enable lint rules for React DOM reactDom.configs.recommended, ], languageOptions: { parserOptions: { project: ["./tsconfig.node.json", "./tsconfig.app.json"], tsconfigRootDir: import.meta.dirname, }, // other options... }, }, ]); ``` -------------------------------- ### Classify Image in Node.js with tfjs-node Source: https://github.com/infinitered/nsfwjs/wiki/FAQ:-NSFW-JS Use this snippet to classify images in a Node.js environment with tfjs-node. Ensure the model is loaded from a local path and image preprocessing is handled correctly. ```javascript const tf =require('@tensorflow/tfjs-node') const load=require('./dist/index').load const fs = require('fs'); const jpeg = require('jpeg-js'); // Fix for JEST const globalAny = global globalAny.fetch = require('node-fetch') const timeoutMS = 10000 const NUMBER_OF_CHANNELS = 3 const readImage = (path) => { const buf = fs.readFileSync(path) const pixels = jpeg.decode(buf, true) return pixels } const imageByteArray = (image, numChannels) => { const pixels = image.data const numPixels = image.width * image.height; const values = new Int32Array(numPixels * numChannels); for (let i = 0; i < numPixels; i++) { for (let channel = 0; channel < numChannels; ++channel) { values[i * numChannels + channel] = pixels[i * 4 + channel]; } } return values } const imageToInput = (image, numChannels) => { const values = imageByteArray(image, numChannels) const outShape = [image.height, image.width, numChannels] ; const input = tf.tensor3d(values, outShape, 'int32'); return input } (async()=>{ const model = await load('file://./model/')//moved model at root of folder const logo = readImage(`./_art/nsfwjs_logo.jpg`) const input = imageToInput(logo, NUMBER_OF_CHANNELS) console.time('predict') const predictions = await model.classify(input) console.timeEnd('predict') console.log(predictions) })() ``` -------------------------------- ### Cache and Load Model from IndexedDB Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Saves a loaded model to IndexedDB for faster subsequent loads and then loads it from there. This is beneficial for browser-based applications. ```javascript const initialLoad = await nsfwjs.load( "/path/to/different/model/" /*, { ...options }*/ ); await initialLoad.model.save("indexeddb://exampleModel"); const model = await nsfwjs.load("indexeddb://exampleModel" /*, { ...options }*/); ``` -------------------------------- ### Express.js REST API for Image Classification Source: https://context7.com/infinitered/nsfwjs/llms.txt Builds a multipart/form-data endpoint using Express.js and Multer to classify uploaded images server-side. The model is loaded once at startup and kept in memory for efficiency. ```javascript const tf = require("@tensorflow/tfjs-node"); const express = require("express"); const multer = require("multer"); const nsfw = require("nsfwjs"); const app = express(); const upload = multer(); let model; app.post("/nsfw", upload.single("image"), async (req, res) => { if (!req.file) { return res.status(400).json({ error: "Missing image in multipart/form-data" }); } const image = tf.node.decodeImage(req.file.buffer, 3); try { const predictions = await model.classify(image); res.json(predictions); // [ // { className: "Neutral", probability: 0.91 }, // { className: "Drawing", probability: 0.05 }, // ... // ] } catch (err) { res.status(500).json({ error: err.message }); } finally { image.dispose(); } }); // Load model once at startup, keep in memory nsfw.load().then((m) => { model = m; app.listen(8080, () => console.log("Server running on :8080")); }); // Test with curl: // curl --request POST localhost:8080/nsfw \ // --header 'Content-Type: multipart/form-data' \ // --form 'image=@/path/to/image.jpg' ``` -------------------------------- ### model.classify Source: https://context7.com/infinitered/nsfwjs/llms.txt Classifies an image using a pre-loaded NSFWJS model. It accepts various image input types and returns an array of prediction objects, each containing a class name and its probability. You can also specify the number of top results to return. ```APIDOC ## `model.classify` — Classify an image Accepts a DOM image element, video element, canvas, `ImageData`, or a `tf.Tensor3D`. Returns an array of `{ className, probability }` objects sorted by probability descending. ```js import * as nsfwjs from "nsfwjs"; const model = await nsfwjs.load(); // Classify from an element — returns all 5 classes const img = document.getElementById("myImage"); // HTMLImageElement const predictions = await model.classify(img); console.log(predictions); // [ // { className: "Neutral", probability: 0.912 }, // { className: "Drawing", probability: 0.051 }, // { className: "Sexy", probability: 0.023 }, // { className: "Porn", probability: 0.009 }, // { className: "Hentai", probability: 0.005 }, // ] // Return only top 3 results const top3 = await model.classify(img, 3); // Classify from a video element (current frame) const video = document.getElementById("myVideo"); // HTMLVideoElement const videoPredictions = await model.classify(video); // Classify from a canvas element const canvas = document.getElementById("myCanvas"); // HTMLCanvasElement const canvasPredictions = await model.classify(canvas); // Classify from a tf.Tensor3D (manage tensor memory manually) import * as tf from "@tensorflow/tfjs"; const tensor = tf.zeros([224, 224, 3]) as tf.Tensor3D; try { const tensorPredictions = await model.classify(tensor); console.log(tensorPredictions); } finally { tensor.dispose(); } // Simple safe/unsafe check const isNSFW = predictions[0].className !== "Neutral" && predictions[0].className !== "Drawing" && predictions[0].probability > 0.7; ``` ``` -------------------------------- ### Release Model Resources Source: https://context7.com/infinitered/nsfwjs/llms.txt Dispose of the NSFWJS model to free up memory. This operation is idempotent and subsequent calls to classify or infer will throw an error. Recommended for one-shot classification. ```javascript import * as nsfwjs from "nsfwjs"; const model = await nsfwjs.load(); const img = document.getElementById("myImage"); const predictions = await model.classify(img); console.log(predictions); // Release all GPU/CPU memory used by the model model.dispose(); // Subsequent calls throw "This NSFWJS instance has been disposed." try { await model.classify(img); } catch (err) { console.error(err.message); // "This NSFWJS instance has been disposed." } // Pattern: one-shot classification async function classifyOnce(imgElement) { const m = await nsfwjs.load(); try { return await m.classify(imgElement); } finally { m.dispose(); } } ``` -------------------------------- ### Classify Image with Custom Prediction Count Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Classifies an image using the loaded model and returns a specified number of top predictions. By default, it returns all 5 predictions. ```javascript // Return top 3 guesses (instead of all 5) const predictions = await model.classify(img, 3); ``` -------------------------------- ### Display Classification Results Source: https://github.com/infinitered/nsfwjs/blob/master/examples/manual_testing/data/index.html Helper function to display classification results for a single media element. Appends the results as a paragraph below the image. ```javascript function showResults(mediaElement, predictions, isSingle = false) { if (isSingle) { const html = predictions.map(({className, probability}) => `${className}: ${Math.round(probability * 10000) / 10000} `).join('') const el = document.createElement('p') el.style.cssText = 'font-size:13px;' el.innerHTML = html mediaElement.parentElement.append(el) } else { for (let j = 0; j < predictions.length; j++) { const html = predictions[j].map(({className, probability}) => `${className}: ${Math.round(probability * 10000) / 10000} `).join('') const el = document.createElement('p') el.style.cssText = 'font-size:13px;' el.innerHTML = html mediaElement.parentElement.append(el) } } } ``` -------------------------------- ### Classify Image in Browser Source: https://context7.com/infinitered/nsfwjs/llms.txt Classify images from DOM elements or tensors in the browser. Supports specifying the number of top results to return. Ensure tensors are disposed after use. ```javascript import * as nsfwjs from "nsfwjs"; const model = await nsfwjs.load(); // Classify from an element — returns all 5 classes const img = document.getElementById("myImage"); // HTMLImageElement const predictions = await model.classify(img); console.log(predictions); // [ // { className: "Neutral", probability: 0.912 }, // { className: "Drawing", probability: 0.051 }, // { className: "Sexy", probability: 0.023 }, // { className: "Porn", probability: 0.009 }, // { className: "Hentai", probability: 0.005 }, // ] // Return only top 3 results const top3 = await model.classify(img, 3); // Classify from a video element (current frame) const video = document.getElementById("myVideo"); // HTMLVideoElement const videoPredictions = await model.classify(video); // Classify from a canvas element const canvas = document.getElementById("myCanvas"); // HTMLCanvasElement const canvasPredictions = await model.classify(canvas); // Classify from a tf.Tensor3D (manage tensor memory manually) import * as tf from "@tensorflow/tfjs"; const tensor = tf.zeros([224, 224, 3]) as tf.Tensor3D; try { const tensorPredictions = await model.classify(tensor); console.log(tensorPredictions); } finally { tensor.dispose(); } // Simple safe/unsafe check const isNSFW = predictions[0].className !== "Neutral" && predictions[0].className !== "Drawing" && predictions[0].probability > 0.7; ``` -------------------------------- ### Classify Image Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Classifies an image using the loaded NSFWJS model. Returns an array of predictions for different NSFW categories. ```APIDOC ## classify ### Description Classifies an image to determine the probability of it falling into different NSFW categories. ### Method `model.classify(image)` ### Parameters - **image** (HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageData | tf.Tensor) - The image to classify. ### Request Example ```javascript const img = document.getElementById("img"); const predictions = await model.classify(img); console.log("Predictions: ", predictions); ``` ### Response - **predictions** (array) - An array of objects, where each object represents a prediction for a NSFW category. Each prediction object typically includes: - **className** (string) - The name of the NSFW class (e.g., 'Drawing', 'Hentai', 'Neutral', 'Porn', 'Sexy'). - **probability** (number) - The probability of the image belonging to this class (0 to 1). ``` -------------------------------- ### Classify Image in Node.js Source: https://context7.com/infinitered/nsfwjs/llms.txt Perform image classification server-side using Node.js. Requires `@tensorflow/tfjs-node` and `fs` module. Ensure tensors are disposed manually. ```javascript const tf = require("@tensorflow/tfjs-node"); const nsfw = require("nsfwjs"); const fs = require("fs"); async function classifyFile(filePath) { const model = await nsfw.load(); const imageBuffer = fs.readFileSync(filePath); // decodeImage returns Tensor3D for 3-channel images const image = tf.node.decodeImage(imageBuffer, 3); try { const predictions = await model.classify(image); console.log("Predictions:", predictions); // [ // { className: "Neutral", probability: 0.87 }, // ... // ] return predictions; } finally { image.dispose(); // Must dispose tensors manually model.dispose(); } } classifyFile("./photo.jpg"); ``` -------------------------------- ### Classify Image Source: https://github.com/infinitered/nsfwjs/blob/master/README.md Classifies an image using the loaded NSFWJS model. It accepts various image inputs and returns an array of predictions with their confidence levels. ```APIDOC ## `classify` an image This function can take any browser-based image elements (``, `