npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

nsfwjs-node

v2.1.14

Published

Detect NSFW content client side

Downloads

15

Readme

Fork from https://github.com/infinitered/nsfwjs

All Contributors Travis CI

A simple JavaScript library to help you quickly identify unseemly images; all in the client's browser. NSFWJS isn't perfect, but it's pretty accurate (~90% from our test set of 15,000 test images)... and it's getting more accurate all the time.

Why would this be useful? Check out the announcement blog post.

The library categorizes image probabilities in the following 5 classes:

  • Drawing - safe for work drawings (including anime)
  • Hentai - hentai and pornographic drawings
  • Neutral - safe for work neutral images
  • Porn - pornographic images, sexual acts
  • Sexy - sexually explicit images, not pornography

The demo is a continuous deployment source - Give it a go: http://nsfwjs.com/

How to use the module

With async/await support:

import * as nsfwjs from 'nsfwjs-node'

// Load model from my S3.
// See the section hosting the model files on your site.
const model = await nsfwjs.load()

// Classify the image
const logo = nsfwjs.readImage(filename);
const img = nsfwjs.imageToInput(logo, nsfwjs.NUMBER_OF_CHANNELS);
const predictions = await model.classify(img)
console.log('Predictions: ', predictions)

Without async/await support:

import * as nsfwjs from 'nsfwjs-node'

const logo = nsfwjs.readImage(filename);
const img = nsfwjs.imageToInput(logo, nsfwjs.NUMBER_OF_CHANNELS);

// Load model from my S3.
// See the section hosting the model files on your site.
nsfwjs.load().then(function(model) {
  model.classify(img).then(function(predictions) {
    // Classify the image
    console.log('Predictions: ', predictions)
  })
})

API

load the model

Before you can classify any image, you'll need to load the model. You should use the optional first parameter and load the model from your website, as explained in the install directions.

const model = nsfwjs.load('/path/to/model/directory/')

If you're using a model that needs an image of dimension other than 224x224, you can pass the size in the options parameter.

const model = nsfwjs.load('/path/to/different/model/', {size: 299})

Parameters

  • optional URL to the model.json folder.
  • optional object with size property that your model expects.

Returns

  • Ready to use NSFWJS model object

classify an image

This function can take any browser-based image elements (<img>, <video>, <canvas>) and returns an array of most likely predictions and their confidence levels.

// Return top 3 guesses (instead of all 5)
const predictions = await model.classify(img, 3)

Parameters

  • Tensor, Image data, Image element, video element, or canvas element to check
  • Number of results to return (default all 5)

Returns

  • Array of objects that contain className and probability. Array size is determined by the second parameter in the classify function.

classifyGif

This function can take a browser-based image element (<img>) that is a GIF, and returns an array of prediction arrays. It breaks a GIF into its frames and runs classify on each with a given configuration. This can take a while, as GIFs are frequently hundreds of frames.

// Returns all predictions of each GIF frame
const framePredictions = await model.classifyGif(img)

If you're looking to update the user on status (e.g. progress bar) or change the number of top results per frame, then you can utilize the configuration parameter.

Example of passing a configuration:

// returns top 1 prediction of each GIF frame, and logs the status to console
const myConfig = {
  topk: 1,
  setGifControl: (gifControl) => console.log(gifControl),
  onFrame: ({ index, totalFrames, predictions }) =>
    console.log(index, totalFrames, predictions)
}
const framePredictions = await classifyGif(img, myConfig)

Parameters

  • Image element to check
  • Configuration object with the following possible key/values:
    • topk - Number of results to return per frame (default all 5)
    • setGifControl - Function callback receives SuperGif object as an argument, allows a user to save it for later use
    • onFrame - Function callback on each frame - Param is an object with the following key/values:
      • index - the current GIF frame that was classified (starting at 1)
      • totalFrames - the complete number of frames for this GIF (for progress calculations)
      • predictions - an array of length topk, returning top results from classify

Returns

  • Array of the same order as number of frames in GIF. Each index corresponding to that frame, an returns array of objects that contain className and probability; sorted by probability and limited by topk config parameter.

Install

NSFWJS is powered by TensorFlow.js as a peer dependency. If your project does not already have TFJS you'll need to add it.

# peer dependency
$ yarn add @tensorflow/tfjs
# install NSFWJS
$ yarn add nsfwjs

For script tags add . Then simply access the nsfwjs global variable. This requires that you've already imported TensorFlow.js as well.

Host your own model

The magic that powers NSFWJS is the NSFW detection model. By default, this node module is pulling from my S3, but I make no guarantees that I'll keep that download link available forever. It's best for the longevity of your project that you download and host your own version of the model files. You can then pass the relative URL to your hosted files in the load function. If you can come up with a way to bundle the model into the NPM package, I'd love to see a PR to this repo!

Run the Examples

Example 1:

The demo that powers https://nsfwjs.com/ is available in the nsfw_demo example folder.

To run the demo, run yarn prep which will copy the latest code into the demo. After that's done, you can cd into the demo folder and run with yarn start.

Example 2:

A browserified version using nothing but promises and script tags is available in the minimal_demo folder.

Please do not use the script tags hosted in this demo as a CDN. This can and should be hosted in your project along side the model files.

More!

An FAQ page is available.

More about NSFWJS and TensorFlow.js - https://youtu.be/uzQwmZwy3yw

The model was trained in Keras over several days and 60+ Gigs of data. Be sure to check out the model code which was trained on data provided by Alexander Kim's nsfw_data_scraper.

Open Source

NSFWJS, as open source, is free to use and always will be :heart:. It's MIT licensed, and we'll always do our best to help and quickly answer issues. If you'd like to get a hold of us, join our community slack.

Premium

Infinite Red offers premium training and support. Email us at [email protected] to get in touch.

Contributors

Thanks goes to these wonderful people (emoji key):

This project follows the all-contributors specification. Contributions of any kind welcome!