yahoo/pngjs-image

View on GitHub
lib/pixel.js

Summary

Maintainability
A
1 hr
Test Coverage
// Copyright 2014-2015 Yahoo! Inc.
// Copyrights licensed under the Mit License. See the accompanying LICENSE file for terms.

/**
 * Pixel manipulation functions
 *
 * @class PNGImage
 * @submodule Core
 * @type {object}
 */
module.exports = {

    /**
     * Gets the color of a pixel at a specific index
     *
     * @method getPixel
     * @param {int} idx Index of pixel
     * @return {int} Color
     */
    getAtIndex: function (idx) {
        return this.getColorAtIndex(idx) | (this.getAlpha(idx) << 24);
    },

    /**
     * Gets the color of a pixel at a specific coordinate
     *
     * @method getAt
     * @param {int} x X-coordinate of pixel
     * @param {int} y Y-coordinate of pixel
     * @return {int} Color
     */
    getAt: function (x, y) {
        var idx = this.getIndex(x, y);
        return this.getAtIndex(idx);
    },

    /**
     * Gets the color of a pixel at a specific coordinate
     * Alias for getAt
     *
     * @method getPixel
     * @param {int} x X-coordinate of pixel
     * @param {int} y Y-coordinate of pixel
     * @return {int} Color
     */
    getPixel: function (x, y) {
        return this.getAt(x, y);
    },


    /**
     * Sets the color of a pixel at a specific index
     *
     * @method setAtIndex
     * @param {int} idx Index of pixel
     * @param {object|int} color
     * @param {int} [color.red] Red value for pixel
     * @param {int} [color.green] Green value for pixel
     * @param {int} [color.blue] Blue value for pixel
     * @param {int} [color.alpha] Alpha value for pixel
     * @param {number} [color.opacity] Opacity of color
     */
    setAtIndex: function (idx, color) {
        if (typeof color === 'object') {
            if (color.red !== undefined) this.setRed(idx, color.red, color.opacity);
            if (color.green !== undefined) this.setGreen(idx, color.green, color.opacity);
            if (color.blue !== undefined) this.setBlue(idx, color.blue, color.opacity);
            if (color.alpha !== undefined) this.setAlpha(idx, color.alpha, color.opacity);
        } else {
            this.setRed(idx, color & 0xff);
            this.setGreen(idx, (color & 0xff00) >> 8);
            this.setBlue(idx, (color & 0xff0000) >> 16);
            this.setAlpha(idx, (color & 0xff000000) >> 24);
        }
    },

    /**
     * Sets the color of a pixel at a specific coordinate
     *
     * @method setAt
     * @param {int} x X-coordinate for pixel
     * @param {int} y Y-coordinate for pixel
     * @param {object} color
     * @param {int} [color.red] Red value for pixel
     * @param {int} [color.green] Green value for pixel
     * @param {int} [color.blue] Blue value for pixel
     * @param {int} [color.alpha] Alpha value for pixel
     * @param {number} [color.opacity] Opacity of color
     */
    setAt: function (x, y, color) {
        var idx = this.getIndex(x, y);
        this.setAtIndex(idx, color);
    },

    /**
     * Sets the color of a pixel at a specific coordinate
     * Alias for setAt
     *
     * @method setPixel
     * @param {int} x X-coordinate for pixel
     * @param {int} y Y-coordinate for pixel
     * @param {object} color
     * @param {int} [color.red] Red value for pixel
     * @param {int} [color.green] Green value for pixel
     * @param {int} [color.blue] Blue value for pixel
     * @param {int} [color.alpha] Alpha value for pixel
     * @param {number} [color.opacity] Opacity of color
     */
    setPixel: function (x, y, color) {
        this.setAt(x, y, color);
    },


    /**
     * Gets the color of a pixel at a specific index
     *
     * @method getColorAtIndex
     * @param {int} idx Index of pixel
     * @return {int} Color
     */
    getColorAtIndex: function (idx) {
        return this.getRed(idx) | (this.getGreen(idx) << 8) | (this.getBlue(idx) << 16);
    },

    /**
     * Gets the color of a pixel at a specific coordinate
     *
     * @method getColor
     * @param {int} x X-coordinate of pixel
     * @param {int} y Y-coordinate of pixel
     * @return {int} Color
     */
    getColor: function (x, y) {
        var idx = this.getIndex(x, y);
        return this.getColorAtIndex(idx);
    },


    /**
     * Calculates the final color value for opacity
     *
     * @method _calculateColorValue
     * @param {int} originalValue
     * @param {int} paintValue
     * @param {number} [opacity]
     * @return {int}
     * @private
     */
    _calculateColorValue: function (originalValue, paintValue, opacity) {

        var originalPart, paintPart;

        if (opacity === undefined) {
            return paintValue;
        } else {
            originalPart = originalValue * (1 - opacity);
            paintPart = (paintValue * opacity);

            return Math.floor(originalPart + paintPart);
        }
    },

    /**
     * Get the red value of a pixel
     *
     * @method getRed
     * @param {int} idx Index of pixel
     * @return {int}
     */
    getRed: function (idx) {
        return this._getValue(idx, 0);
    },

    /**
     * Set the red value of a pixel
     *
     * @method setRed
     * @param {int} idx Index of pixel
     * @param {int} value Value for pixel
     * @param {number} [opacity] Opacity of value set
     */
    setRed: function (idx, value, opacity) {
        this._setValue(idx, 0, value, opacity);
    },


    /**
     * Get the green value of a pixel
     *
     * @method getGreen
     * @param {int} idx Index of pixel
     * @return {int}
     */
    getGreen: function (idx) {
        return this._getValue(idx, 1);
    },

    /**
     * Set the green value of a pixel
     *
     * @method setGreen
     * @param {int} idx Index of pixel
     * @param {int} value Value for pixel
     * @param {number} [opacity] Opacity of value set
     */
    setGreen: function (idx, value, opacity) {
        this._setValue(idx, 1, value, opacity);
    },


    /**
     * Get the blue value of a pixel
     *
     * @method getBlue
     * @param {int} idx Index of pixel
     * @return {int}
     */
    getBlue: function (idx) {
        return this._getValue(idx, 2);
    },

    /**
     * Set the blue value of a pixel
     *
     * @method setBlue
     * @param {int} idx Index of pixel
     * @param {int} value Value for pixel
     * @param {number} [opacity] Opacity of value set
     */
    setBlue: function (idx, value, opacity) {
        this._setValue(idx, 2, value, opacity);
    },


    /**
     * Get the alpha value of a pixel
     *
     * @method getAlpha
     * @param {int} idx Index of pixel
     * @return {int}
     */
    getAlpha: function (idx) {
        return this._getValue(idx, 3);
    },

    /**
     * Set the alpha value of a pixel
     *
     * @method setAlpha
     * @param {int} idx Index of pixel
     * @param {int} value Value for pixel
     * @param {number} [opacity] Opacity of value set
     */
    setAlpha: function (idx, value, opacity) {
        this._setValue(idx, 3, value, opacity);
    },


    /**
     * Sets the value of a pixel
     *
     * @method _getValue
     * @param {int} offset Offset of a value
     * @param {int} colorOffset Offset of a color
     * @return {int}
     * @private
     */
    _getValue: function (offset, colorOffset) {
        var localOffset = offset << 2;
        return this._image.data[localOffset + colorOffset];
    },

    /**
     * Sets the value of a pixel
     *
     * @method _setValue
     * @param {int} offset Offset of a value
     * @param {int} colorOffset Offset of a color
     * @param {int} value Value for pixel
     * @param {number} [opacity] Opacity of value set
     * @private
     */
    _setValue: function (offset, colorOffset, value, opacity) {
        var previousValue = this._getValue(offset, colorOffset),
            localOffset = offset << 2;

        this._image.data[localOffset + colorOffset] = this._calculateColorValue(previousValue, value, opacity);
    }
};