node-vibrant
Advanced tools
Comparing version 3.0.0-alpha.2 to 3.0.0
import Vibrant from './vibrant'; | ||
export = Vibrant; |
@@ -0,0 +0,0 @@ "use strict"; |
@@ -0,0 +0,0 @@ /// <reference types="bluebird" /> |
@@ -5,3 +5,3 @@ "use strict"; | ||
var vibrant_1 = require("./vibrant"); | ||
var Builder = (function () { | ||
var Builder = /** @class */ (function () { | ||
function Builder(src, opts) { | ||
@@ -8,0 +8,0 @@ if (opts === void 0) { opts = {}; } |
@@ -0,0 +0,0 @@ "use strict"; |
@@ -0,1 +1,2 @@ | ||
import { Filter } from './typing'; | ||
export interface Vec3 extends Array<number> { | ||
@@ -16,2 +17,3 @@ 0: number; | ||
export declare class Swatch { | ||
static applyFilter(colors: Swatch[], f: Filter): Swatch[]; | ||
private _hsl; | ||
@@ -22,2 +24,5 @@ private _rgb; | ||
private _hex; | ||
readonly r: number; | ||
readonly g: number; | ||
readonly b: number; | ||
getRgb(): Vec3; | ||
@@ -24,0 +29,0 @@ getHsl(): Vec3; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var util_1 = require("./util"); | ||
var Swatch = (function () { | ||
var filter = require("lodash/filter"); | ||
var Swatch = /** @class */ (function () { | ||
function Swatch(rgb, population) { | ||
@@ -9,2 +10,25 @@ this._rgb = rgb; | ||
} | ||
Swatch.applyFilter = function (colors, f) { | ||
return typeof f === 'function' | ||
? filter(colors, function (_a) { | ||
var r = _a.r, g = _a.g, b = _a.b; | ||
return f(r, g, b, 255); | ||
}) | ||
: colors; | ||
}; | ||
Object.defineProperty(Swatch.prototype, "r", { | ||
get: function () { return this._rgb[0]; }, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
Object.defineProperty(Swatch.prototype, "g", { | ||
get: function () { return this._rgb[1]; }, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
Object.defineProperty(Swatch.prototype, "b", { | ||
get: function () { return this._rgb[2]; }, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
Swatch.prototype.getRgb = function () { return this._rgb; }; | ||
@@ -11,0 +35,0 @@ Swatch.prototype.getHsl = function () { |
export default function defaultFilter(r: number, g: number, b: number, a: number): boolean; |
@@ -0,0 +0,0 @@ "use strict"; |
export { default as Default } from './default'; | ||
import { Filter } from '../typing'; | ||
export declare function combineFilters(filters: Filter[]): Filter; |
@@ -5,2 +5,17 @@ "use strict"; | ||
exports.Default = default_1.default; | ||
function combineFilters(filters) { | ||
// TODO: caching | ||
if (!Array.isArray(filters) || filters.length === 0) | ||
return null; | ||
return function (r, g, b, a) { | ||
if (a === 0) | ||
return false; | ||
for (var i = 0; i < filters.length; i++) { | ||
if (!filters[i](r, g, b, a)) | ||
return false; | ||
} | ||
return true; | ||
}; | ||
} | ||
exports.combineFilters = combineFilters; | ||
//# sourceMappingURL=index.js.map |
import { Generator } from '../typing'; | ||
declare const DefaultGenerator: Generator; | ||
export default DefaultGenerator; |
@@ -19,4 +19,4 @@ "use strict"; | ||
weightSaturation: 3, | ||
weightLuma: 6, | ||
weightPopulation: 1, | ||
weightLuma: 6.5, | ||
weightPopulation: 0.5, | ||
}; | ||
@@ -78,7 +78,19 @@ function _findMaxPopulation(swatches) { | ||
var palette = {}; | ||
// mVibrantSwatch = findColor(TARGET_NORMAL_LUMA, MIN_NORMAL_LUMA, MAX_NORMAL_LUMA, | ||
// TARGET_VIBRANT_SATURATION, MIN_VIBRANT_SATURATION, 1f); | ||
palette.Vibrant = _findColorVariation(palette, swatches, maxPopulation, opts.targetNormalLuma, opts.minNormalLuma, opts.maxNormalLuma, opts.targetVibrantSaturation, opts.minVibrantSaturation, 1, opts); | ||
// mLightVibrantSwatch = findColor(TARGET_LIGHT_LUMA, MIN_LIGHT_LUMA, 1f, | ||
// TARGET_VIBRANT_SATURATION, MIN_VIBRANT_SATURATION, 1f); | ||
palette.LightVibrant = _findColorVariation(palette, swatches, maxPopulation, opts.targetLightLuma, opts.minLightLuma, 1, opts.targetVibrantSaturation, opts.minVibrantSaturation, 1, opts); | ||
// mDarkVibrantSwatch = findColor(TARGET_DARK_LUMA, 0f, MAX_DARK_LUMA, | ||
// TARGET_VIBRANT_SATURATION, MIN_VIBRANT_SATURATION, 1f); | ||
palette.DarkVibrant = _findColorVariation(palette, swatches, maxPopulation, opts.targetDarkLuma, 0, opts.maxDarkLuma, opts.targetVibrantSaturation, opts.minVibrantSaturation, 1, opts); | ||
// mMutedSwatch = findColor(TARGET_NORMAL_LUMA, MIN_NORMAL_LUMA, MAX_NORMAL_LUMA, | ||
// TARGET_MUTED_SATURATION, 0f, MAX_MUTED_SATURATION); | ||
palette.Muted = _findColorVariation(palette, swatches, maxPopulation, opts.targetNormalLuma, opts.minNormalLuma, opts.maxNormalLuma, opts.targetMutesSaturation, 0, opts.maxMutesSaturation, opts); | ||
// mLightMutedColor = findColor(TARGET_LIGHT_LUMA, MIN_LIGHT_LUMA, 1f, | ||
// TARGET_MUTED_SATURATION, 0f, MAX_MUTED_SATURATION); | ||
palette.LightMuted = _findColorVariation(palette, swatches, maxPopulation, opts.targetLightLuma, opts.minLightLuma, 1, opts.targetMutesSaturation, 0, opts.maxMutesSaturation, opts); | ||
// mDarkMutedSwatch = findColor(TARGET_DARK_LUMA, 0f, MAX_DARK_LUMA, | ||
// TARGET_MUTED_SATURATION, 0f, MAX_MUTED_SATURATION); | ||
palette.DarkMuted = _findColorVariation(palette, swatches, maxPopulation, opts.targetDarkLuma, 0, opts.maxDarkLuma, opts.targetMutesSaturation, 0, opts.maxMutesSaturation, opts); | ||
@@ -85,0 +97,0 @@ return palette; |
export { default as Default } from './default'; |
@@ -0,0 +0,0 @@ "use strict"; |
/// <reference types="bluebird" /> | ||
import * as Bluebird from 'bluebird'; | ||
import { Image, Options, ImageData, ImageSource } from '../typing'; | ||
import { Filter, Image, Options, ImageData, ImageSource } from '../typing'; | ||
export declare abstract class ImageBase implements Image { | ||
@@ -15,2 +15,3 @@ abstract load(image: ImageSource): Bluebird<ImageBase>; | ||
scaleDown(opts: Options): void; | ||
applyFilter(filter: Filter): Bluebird<ImageData>; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var ImageBase = (function () { | ||
var Bluebird = require("bluebird"); | ||
var ImageBase = /** @class */ (function () { | ||
function ImageBase() { | ||
@@ -21,2 +22,21 @@ } | ||
}; | ||
ImageBase.prototype.applyFilter = function (filter) { | ||
var imageData = this.getImageData(); | ||
if (typeof filter === 'function') { | ||
var pixels = imageData.data; | ||
var n = pixels.length / 4; | ||
var offset = void 0, r = void 0, g = void 0, b = void 0, a = void 0; | ||
for (var i = 0; i < n; i++) { | ||
offset = i * 4; | ||
r = pixels[offset + 0]; | ||
g = pixels[offset + 1]; | ||
b = pixels[offset + 2]; | ||
a = pixels[offset + 3]; | ||
// Mark ignored color | ||
if (!filter(r, g, b, a)) | ||
pixels[offset + 3] = 0; | ||
} | ||
} | ||
return Bluebird.resolve(imageData); | ||
}; | ||
return ImageBase; | ||
@@ -23,0 +43,0 @@ }()); |
@@ -0,0 +0,0 @@ /// <reference types="bluebird" /> |
@@ -30,3 +30,3 @@ "use strict"; | ||
} | ||
var BroswerImage = (function (_super) { | ||
var BroswerImage = /** @class */ (function (_super) { | ||
__extends(BroswerImage, _super); | ||
@@ -41,3 +41,3 @@ function BroswerImage() { | ||
canvas.className = 'vibrant-canvas'; | ||
canvas.style.visibility = 'hidden'; | ||
canvas.style.display = 'none'; | ||
this._width = canvas.width = img.width; | ||
@@ -75,7 +75,10 @@ this._height = canvas.height = img.height; | ||
}; | ||
img.onload = onImageLoad; | ||
// Already loaded | ||
if (img.complete) | ||
if (img.complete) { | ||
// Already loaded | ||
onImageLoad(); | ||
img.onerror = function (e) { return reject(new Error("Fail to load image: " + src)); }; | ||
} | ||
else { | ||
img.onload = onImageLoad; | ||
img.onerror = function (e) { return reject(new Error("Fail to load image: " + src)); }; | ||
} | ||
}); | ||
@@ -82,0 +85,0 @@ }; |
@@ -0,0 +0,0 @@ /// <reference types="bluebird" /> |
@@ -22,3 +22,3 @@ "use strict"; | ||
}; | ||
var NodeImage = (function (_super) { | ||
var NodeImage = /** @class */ (function (_super) { | ||
__extends(NodeImage, _super); | ||
@@ -25,0 +25,0 @@ function NodeImage() { |
import Vibrant from './vibrant'; | ||
export = Vibrant; |
@@ -0,0 +0,0 @@ "use strict"; |
@@ -0,1 +1,3 @@ | ||
import { Quantizer } from '../typing'; | ||
export { default as MMCQ } from './mmcq'; | ||
export declare var WebWorker: Quantizer; |
@@ -5,2 +5,3 @@ "use strict"; | ||
exports.MMCQ = mmcq_1.default; | ||
exports.WebWorker = null; | ||
//# sourceMappingURL=index.js.map |
@@ -1,3 +0,4 @@ | ||
import { Quantizer } from '../typing'; | ||
declare const MMCQ: Quantizer; | ||
import { Pixels, ComputedOptions } from '../typing'; | ||
import { Swatch } from '../color'; | ||
declare const MMCQ: (pixels: Pixels, opts: ComputedOptions) => Swatch[]; | ||
export default MMCQ; |
@@ -6,20 +6,23 @@ "use strict"; | ||
var pqueue_1 = require("./pqueue"); | ||
var maxIterations = 1000; | ||
var fractByPopulations = 0.75; | ||
function _splitBoxes(pq, target) { | ||
var colorCount = 1; | ||
var iteration = 0; | ||
while (iteration < maxIterations) { | ||
iteration++; | ||
var lastSize = pq.size(); | ||
while (pq.size() < target) { | ||
var vbox = pq.pop(); | ||
if (!vbox.count()) | ||
continue; | ||
var _a = vbox.split(), vbox1 = _a[0], vbox2 = _a[1]; | ||
pq.push(vbox1); | ||
if (vbox2) { | ||
pq.push(vbox2); | ||
colorCount++; | ||
if (vbox && vbox.count() > 0) { | ||
var _a = vbox.split(), vbox1 = _a[0], vbox2 = _a[1]; | ||
pq.push(vbox1); | ||
if (vbox2 && vbox2.count() > 0) | ||
pq.push(vbox2); | ||
// No more new boxes, converged | ||
if (pq.size() === lastSize) { | ||
break; | ||
} | ||
else { | ||
lastSize = pq.size(); | ||
} | ||
} | ||
if (colorCount >= target || iteration > maxIterations) | ||
return; | ||
else { | ||
break; | ||
} | ||
} | ||
@@ -31,14 +34,3 @@ } | ||
} | ||
var shouldIgnore = null; | ||
if (Array.isArray(opts.filters) && opts.filters.length > 0) { | ||
shouldIgnore = function (r, g, b, a) { | ||
for (var _i = 0, _a = opts.filters; _i < _a.length; _i++) { | ||
var f = _a[_i]; | ||
if (!f(r, g, b, a)) | ||
return true; | ||
} | ||
return false; | ||
}; | ||
} | ||
var vbox = vbox_1.default.build(pixels, shouldIgnore); | ||
var vbox = vbox_1.default.build(pixels); | ||
var hist = vbox.hist; | ||
@@ -56,16 +48,15 @@ var colorCount = Object.keys(hist).length; | ||
// calculate the actual colors | ||
return generateSwatches(pq2); | ||
}; | ||
function generateSwatches(pq) { | ||
var swatches = []; | ||
// let vboxes = [] | ||
while (pq2.size()) { | ||
var v = pq2.pop(); | ||
while (pq.size()) { | ||
var v = pq.pop(); | ||
var color = v.avg(); | ||
var r = color[0], g = color[1], b = color[2]; | ||
if (shouldIgnore === null || !shouldIgnore(r, g, b, 255)) { | ||
// @vboxes.push v | ||
swatches.push(new color_1.Swatch(color, v.count())); | ||
} | ||
swatches.push(new color_1.Swatch(color, v.count())); | ||
} | ||
return swatches; | ||
}; | ||
} | ||
exports.default = MMCQ; | ||
//# sourceMappingURL=mmcq.js.map |
@@ -0,0 +0,0 @@ export interface PQueueComparator<T> { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var PQueue = (function () { | ||
var PQueue = /** @class */ (function () { | ||
function PQueue(comparator) { | ||
@@ -5,0 +5,0 @@ this._comparator = comparator; |
@@ -0,0 +0,0 @@ import { Vec3 } from '../color'; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var util_1 = require("../util"); | ||
var VBox = (function () { | ||
var VBox = /** @class */ (function () { | ||
function VBox(r1, r2, g1, g2, b1, b2, hist) { | ||
@@ -35,3 +35,4 @@ this._volume = -1; | ||
a = pixels[offset + 3]; | ||
if (typeof shouldIgnore === 'function' && shouldIgnore(r, g, b, a)) | ||
// Ignored pixels' alpha is marked as 0 in filtering stage | ||
if (a === 0) | ||
continue; | ||
@@ -38,0 +39,0 @@ r = r >> util_1.RSHIFT; |
@@ -5,9 +5,3 @@ "use strict"; | ||
var Vibrant = require("../index"); | ||
// if (typeof Window !== undefined && this instanceof Window) { | ||
// Vibrant = this.Vibrant | ||
// } else { | ||
// Vibrant = require('../index') | ||
// } | ||
// Vibrant = require('../') | ||
// expect = require('chai').expect | ||
var omit = require("lodash/omit"); | ||
describe('builder', function () { | ||
@@ -33,5 +27,6 @@ it('modifies Vibrant options', function () { | ||
}; | ||
chai_1.expect(v.opts).to.deep.equal(expected); | ||
chai_1.expect(v.opts.combinedFilter, 'should have combined filter').to.be.a('function'); | ||
chai_1.expect(omit(v.opts, 'combinedFilter')).to.deep.equal(expected); | ||
}); | ||
}); | ||
//# sourceMappingURL=builder.spec.js.map |
export declare const TEST_PORT = 3444; | ||
export declare const REFERENCE_PALETTE: any; | ||
export declare const REFERENCE_PALETTE_WITH_FILTER: any; | ||
export declare const TARGETS: string[]; | ||
@@ -4,0 +5,0 @@ export interface Sample { |
@@ -10,7 +10,4 @@ "use strict"; | ||
// Comfirmed visually and established as baseline for future versions | ||
exports.REFERENCE_PALETTE = { | ||
chrome: require('../../../data/chrome-exec-ref.json'), | ||
firefox: require('../../../data/firefox-exec-ref.json'), | ||
ie: require('../../../data/ie11-exec-ref.json') | ||
}; | ||
exports.REFERENCE_PALETTE = require('../../../data/browser-palette-ref.json'); | ||
exports.REFERENCE_PALETTE_WITH_FILTER = require('../../../data/browser-palette-with-filter-ref.json'); | ||
exports.TARGETS = Object.keys(exports.REFERENCE_PALETTE); | ||
@@ -17,0 +14,0 @@ exports.SAMPLES = _.range(1, 5).map(function (i) { return ({ |
/// <reference types="mocha" /> | ||
/// <reference types="bluebird" /> | ||
import { VibrantStatic } from '../../typing'; | ||
import Promise = require('bluebird'); | ||
import Builder from '../../builder'; | ||
import { Sample, SamplePathKey } from './data'; | ||
export declare const testVibrant: (Vibrant: VibrantStatic, sample: Sample, done: MochaDone, pathKey?: SamplePathKey) => void; | ||
export declare const testVibrantAsPromised: (Vibrant: VibrantStatic, sample: Sample, pathKey?: SamplePathKey) => Promise<void>; | ||
export declare const testVibrant: (Vibrant: VibrantStatic, sample: Sample, done: MochaDone, pathKey?: SamplePathKey, builderCallback?: (b: Builder) => Builder, references?: any) => void; | ||
export declare const testVibrantAsPromised: (Vibrant: VibrantStatic, sample: Sample, pathKey?: SamplePathKey, builderCallback?: (b: Builder) => Builder, references?: any) => void; |
@@ -16,3 +16,3 @@ "use strict"; | ||
}; | ||
var paletteCallback = function (sample, done) { | ||
var paletteCallback = function (references, sample, done) { | ||
return function (err, palette) { | ||
@@ -26,3 +26,3 @@ if (err != null) { | ||
var key = sample.i.toString(); | ||
var expected = data_1.REFERENCE_PALETTE[target][key][name]; | ||
var expected = references[target][key][name]; | ||
var result = { | ||
@@ -34,9 +34,10 @@ target: target, | ||
}; | ||
if (actual === null) { | ||
chai_1.expect(expected, name + " color from '" + target + "' was expected").to.be.null; | ||
} | ||
if (expected === null) { | ||
chai_1.expect(actual, name + " color form '" + target + "' was not expected").to.be.null; | ||
if (actual !== null) { | ||
console.warn("WARN: " + name + " color form '" + target + "' was not expected. Got " + actual.getHex()); | ||
} | ||
// expect(actual, `${name} color form '${target}' was not expected`).to.be.null | ||
} | ||
else { | ||
chai_1.expect(actual, name + " color from '" + target + "' was expected").not.to.be.null; | ||
var actualHex = actual.getHex(); | ||
@@ -72,16 +73,22 @@ var diff = util.hexDiff(actualHex, expected); | ||
}; | ||
exports.testVibrant = function (Vibrant, sample, done, pathKey) { | ||
exports.testVibrant = function (Vibrant, sample, done, pathKey, builderCallback, references) { | ||
if (pathKey === void 0) { pathKey = 'filePath'; } | ||
Vibrant.from(sample[pathKey]) | ||
.quality(1) | ||
.clearFilters() | ||
.getPalette(paletteCallback(sample, done)); | ||
if (builderCallback === void 0) { builderCallback = null; } | ||
if (references === void 0) { references = data_1.REFERENCE_PALETTE_WITH_FILTER; } | ||
var builder = Vibrant.from(sample[pathKey]) | ||
.quality(1); | ||
if (typeof builderCallback === 'function') | ||
builder = builderCallback(builder); | ||
builder.getPalette(paletteCallback(references, sample, done)); | ||
}; | ||
exports.testVibrantAsPromised = function (Vibrant, sample, pathKey) { | ||
exports.testVibrantAsPromised = function (Vibrant, sample, pathKey, builderCallback, references) { | ||
if (pathKey === void 0) { pathKey = 'filePath'; } | ||
var cb = paletteCallback(sample); | ||
return Vibrant.from(sample[pathKey]) | ||
.quality(1) | ||
.clearFilters() | ||
.getPalette() | ||
if (builderCallback === void 0) { builderCallback = null; } | ||
if (references === void 0) { references = data_1.REFERENCE_PALETTE_WITH_FILTER; } | ||
var cb = paletteCallback(references, sample); | ||
var builder = Vibrant.from(sample[pathKey]) | ||
.quality(1); | ||
if (typeof builderCallback === 'function') | ||
builder = builderCallback(builder); | ||
builder.getPalette() | ||
.then(function (palette) { return cb(null, palette); }) | ||
@@ -88,0 +95,0 @@ .catch(function (e) { return cb(e); }); |
/// <reference types="node" /> | ||
import http = require('http'); | ||
export declare const createSampleServer: () => http.Server; |
@@ -0,0 +0,0 @@ "use strict"; |
@@ -0,0 +0,0 @@ "use strict"; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var data_1 = require("./common/data"); | ||
var helper_1 = require("./common/helper"); | ||
var server_1 = require("./common/server"); | ||
var data_1 = require("./common/data"); | ||
var data_2 = require("./common/data"); | ||
var Vibrant = require("../"); | ||
describe('Palette Extraction', function () { | ||
describe('process samples', function () { | ||
return data_1.SAMPLES.forEach(function (sample) { | ||
return data_2.SAMPLES.forEach(function (sample) { | ||
it(sample.fileName + " (callback)", function (done) { return helper_1.testVibrant(Vibrant, sample, done); }); | ||
@@ -14,2 +15,9 @@ it(sample.fileName + " (Promise)", function () { return helper_1.testVibrantAsPromised(Vibrant, sample); }); | ||
}); | ||
describe('process samples (no filters)', function () { | ||
return data_2.SAMPLES.forEach(function (sample) { | ||
var builderCallback = function (builder) { return builder.clearFilters(); }; | ||
it(sample.fileName + " (callback)", function (done) { return helper_1.testVibrant(Vibrant, sample, done, 'filePath', builderCallback, data_1.REFERENCE_PALETTE); }); | ||
it(sample.fileName + " (Promise)", function () { return helper_1.testVibrantAsPromised(Vibrant, sample, 'filePath', builderCallback, data_1.REFERENCE_PALETTE); }); | ||
}); | ||
}); | ||
describe('process remote images (http)', function () { | ||
@@ -19,6 +27,6 @@ var server = null; | ||
server = server_1.createSampleServer(); | ||
return server.listen(data_1.TEST_PORT); | ||
return server.listen(data_2.TEST_PORT); | ||
}); | ||
after(function () { return server.close(); }); | ||
data_1.SAMPLES.forEach(function (sample) { | ||
data_2.SAMPLES.forEach(function (sample) { | ||
it(sample.url + " (callback)", function (done) { return helper_1.testVibrant(Vibrant, sample, done); }); | ||
@@ -25,0 +33,0 @@ it(sample.url + " (Promise)", function () { return helper_1.testVibrantAsPromised(Vibrant, sample); }); |
@@ -29,2 +29,3 @@ /// <reference types="node" /> | ||
getImageData(): ImageData; | ||
applyFilter(filter: Filter): Bluebird<ImageData>; | ||
remove(): void; | ||
@@ -41,3 +42,3 @@ scaleDown(opts: Options): void; | ||
export interface Quantizer { | ||
(pixels: Pixels, opts: Options): Resolvable<Array<Swatch>>; | ||
(pixels: Pixels, opts: ComputedOptions): Resolvable<Array<Swatch>>; | ||
} | ||
@@ -57,1 +58,4 @@ export interface Generator { | ||
} | ||
export interface ComputedOptions extends Options { | ||
combinedFilter: Filter; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
//# sourceMappingURL=typing.js.map |
@@ -0,0 +0,0 @@ /// <reference types="bluebird" /> |
@@ -0,0 +0,0 @@ "use strict"; |
/// <reference types="bluebird" /> | ||
import { ImageSource, Options, Callback } from './typing'; | ||
import { ImageSource, Options, ComputedOptions, Callback } from './typing'; | ||
import { Palette } from './color'; | ||
@@ -9,3 +9,3 @@ import Bluebird = require('bluebird'); | ||
import * as Generator from './generator'; | ||
import * as Filter from './filter'; | ||
import * as Filters from './filter'; | ||
declare class Vibrant { | ||
@@ -16,10 +16,10 @@ private _src; | ||
static Generator: typeof Generator; | ||
static Filter: typeof Filter; | ||
static Filter: typeof Filters; | ||
static Util: typeof Util; | ||
static DefaultOpts: Partial<Options>; | ||
static from(src: ImageSource): Builder; | ||
opts: Options; | ||
opts: ComputedOptions; | ||
private _palette; | ||
constructor(_src: ImageSource, opts?: Partial<Options>); | ||
private _process(image); | ||
private _process(image, opts); | ||
palette(): Palette; | ||
@@ -26,0 +26,0 @@ swatches(): Palette; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var color_1 = require("./color"); | ||
var Bluebird = require("bluebird"); | ||
@@ -9,7 +10,8 @@ var defaults = require("lodash/defaults"); | ||
var Generator = require("./generator"); | ||
var Filter = require("./filter"); | ||
var Vibrant = (function () { | ||
var Filters = require("./filter"); | ||
var Vibrant = /** @class */ (function () { | ||
function Vibrant(_src, opts) { | ||
this._src = _src; | ||
this.opts = defaults({}, opts, Vibrant.DefaultOpts); | ||
this.opts.combinedFilter = Filters.combineFilters(this.opts.filters); | ||
} | ||
@@ -19,12 +21,9 @@ Vibrant.from = function (src) { | ||
}; | ||
Vibrant.prototype._process = function (image) { | ||
var _this = this; | ||
var opts = this.opts; | ||
Vibrant.prototype._process = function (image, opts) { | ||
var quantizer = opts.quantizer, generator = opts.generator; | ||
image.scaleDown(opts); | ||
var imageData = image.getImageData(); | ||
return Bluebird.resolve(quantizer(imageData.data, opts)) | ||
.then(function (colors) { return Bluebird.resolve(generator(colors)); }) | ||
.tap(function (palette) { return _this._palette = palette; }) | ||
.finally(function () { return image.remove(); }); | ||
return image.applyFilter(opts.combinedFilter) | ||
.then(function (imageData) { return quantizer(imageData.data, opts); }) | ||
.then(function (colors) { return color_1.Swatch.applyFilter(colors, opts.combinedFilter); }) | ||
.then(function (colors) { return Bluebird.resolve(generator(colors)); }); | ||
}; | ||
@@ -41,21 +40,23 @@ Vibrant.prototype.palette = function () { | ||
return image.load(this._src) | ||
.then(function (image) { return _this._process(image); }) | ||
.then(function (image) { return _this._process(image, _this.opts); }) | ||
.tap(function (palette) { return _this._palette = palette; }) | ||
.finally(function () { return image.remove(); }) | ||
.asCallback(cb); | ||
}; | ||
Vibrant.Builder = builder_1.default; | ||
Vibrant.Quantizer = Quantizer; | ||
Vibrant.Generator = Generator; | ||
Vibrant.Filter = Filters; | ||
Vibrant.Util = Util; | ||
Vibrant.DefaultOpts = { | ||
colorCount: 64, | ||
quality: 5, | ||
generator: Generator.Default, | ||
ImageClass: null, | ||
quantizer: Quantizer.MMCQ, | ||
filters: [Filters.Default] | ||
}; | ||
return Vibrant; | ||
}()); | ||
Vibrant.Builder = builder_1.default; | ||
Vibrant.Quantizer = Quantizer; | ||
Vibrant.Generator = Generator; | ||
Vibrant.Filter = Filter; | ||
Vibrant.Util = Util; | ||
Vibrant.DefaultOpts = { | ||
colorCount: 64, | ||
quality: 5, | ||
generator: Generator.Default, | ||
ImageClass: null, | ||
quantizer: Quantizer.MMCQ, | ||
filters: [Filter.Default] | ||
}; | ||
exports.default = Vibrant; | ||
//# sourceMappingURL=vibrant.js.map |
{ | ||
"name": "node-vibrant", | ||
"version": "3.0.0-alpha.2", | ||
"version": "3.0.0", | ||
"description": "Extract prominent colors from an image. Supports both node and browser environment.", | ||
@@ -15,3 +15,3 @@ "main": "lib/index.js", | ||
"@types/lodash": "^4.14.53", | ||
"@types/node": "^7.0.5", | ||
"@types/node": "^8.0.53", | ||
"bluebird": "^3.4.7", | ||
@@ -23,8 +23,8 @@ "jimp": "^0.2.27", | ||
"devDependencies": { | ||
"@types/chai": "^3.4.35", | ||
"@types/finalhandler": "0.0.31", | ||
"@types/chai": "^4.0.5", | ||
"@types/finalhandler": "0.0.32", | ||
"@types/mocha": "^2.2.39", | ||
"@types/serve-static": "^1.7.31", | ||
"@types/table": "^4.0.1", | ||
"chai": "^3.5.0", | ||
"chai": "^4.1.2", | ||
"finalhandler": "^1.0.0", | ||
@@ -38,9 +38,10 @@ "karma": "^1.5.0", | ||
"karma-webpack": "^2.0.2", | ||
"mocha": "^3.2.0", | ||
"mocha": "^4.0.1", | ||
"rimraf": "^2.6.1", | ||
"serve-static": "^1.11.2", | ||
"table": "^4.0.1", | ||
"ts-loader": "^2.0.1", | ||
"typescript": "^2.2.1", | ||
"webpack": "^2.2.1" | ||
"ts-loader": "^3.1.1", | ||
"typescript": "^2.6.1", | ||
"webpack": "^3.8.1", | ||
"worker-loader": "^1.1.0" | ||
}, | ||
@@ -47,0 +48,0 @@ "scripts": { |
@@ -6,2 +6,15 @@ # node-vibrant | ||
## New WebWorker support in v3.0 | ||
Quantization is the most time-consuming stage in `node-vibrant`. In v3.0, the quantization can be run in the WebWorker to avoid freezing the UI thread. | ||
Here's how to use this feature: | ||
1. Use WebWorker build `dist/vibrant.worker.js` or `dist/vibrant.worker.min.js`. Or if you are re-bundling with webpack, use `lib/bundle.worker.js` as entry | ||
2. Use WebWorker quantizer: | ||
```ts | ||
let v = Vibrant.from(src) | ||
.useQuantizer(Vibrant.Quantizer.WebWorker) | ||
// Other configurations | ||
``` | ||
## Features | ||
@@ -143,2 +156,4 @@ - Identical API for both node.js and browser environment | ||
Returns `true` if the color is to be kept. | ||
```ts | ||
@@ -145,0 +160,0 @@ export interface Filter { |
@@ -0,0 +0,0 @@ import Vibrant = require('./browser') |
@@ -0,2 +1,4 @@ | ||
import { Filter } from './typing' | ||
import { rgbToHsl, rgbToHex } from './util' | ||
import filter = require('lodash/filter') | ||
@@ -21,2 +23,7 @@ export interface Vec3 extends Array<number> { | ||
export class Swatch { | ||
static applyFilter(colors: Swatch[], f: Filter): Swatch[] { | ||
return typeof f === 'function' | ||
? filter(colors, ({r, g, b}) => f(r, g, b, 255)) | ||
: colors | ||
} | ||
private _hsl: Vec3 | ||
@@ -27,2 +34,5 @@ private _rgb: Vec3 | ||
private _hex: string | ||
get r() { return this._rgb[0] } | ||
get g() { return this._rgb[1] } | ||
get b() { return this._rgb[2] } | ||
getRgb(): Vec3 { return this._rgb } | ||
@@ -29,0 +39,0 @@ getHsl(): Vec3 { |
@@ -1,1 +0,14 @@ | ||
export { default as Default } from './default' | ||
export { default as Default } from './default' | ||
import { Filter, ImageData, Options } from '../typing' | ||
export function combineFilters(filters: Filter[]): Filter { | ||
// TODO: caching | ||
if (!Array.isArray(filters) || filters.length === 0) return null | ||
return (r: number, g: number, b: number, a: number) => { | ||
if (a === 0) return false | ||
for (let i = 0; i < filters.length; i++) { | ||
if (!filters[i](r, g, b, a)) return false | ||
} | ||
return true | ||
} | ||
} |
@@ -36,4 +36,4 @@ import { Swatch, Palette } from '../color' | ||
weightSaturation: 3, | ||
weightLuma: 6, | ||
weightPopulation: 1, | ||
weightLuma: 6.5, | ||
weightPopulation: 0.5, | ||
} | ||
@@ -124,2 +124,4 @@ | ||
let palette: Palette = {} | ||
// mVibrantSwatch = findColor(TARGET_NORMAL_LUMA, MIN_NORMAL_LUMA, MAX_NORMAL_LUMA, | ||
// TARGET_VIBRANT_SATURATION, MIN_VIBRANT_SATURATION, 1f); | ||
palette.Vibrant = _findColorVariation(palette, swatches, maxPopulation, | ||
@@ -134,2 +136,4 @@ opts.targetNormalLuma, | ||
) | ||
// mLightVibrantSwatch = findColor(TARGET_LIGHT_LUMA, MIN_LIGHT_LUMA, 1f, | ||
// TARGET_VIBRANT_SATURATION, MIN_VIBRANT_SATURATION, 1f); | ||
palette.LightVibrant = _findColorVariation(palette, swatches, maxPopulation, | ||
@@ -144,2 +148,4 @@ opts.targetLightLuma, | ||
) | ||
// mDarkVibrantSwatch = findColor(TARGET_DARK_LUMA, 0f, MAX_DARK_LUMA, | ||
// TARGET_VIBRANT_SATURATION, MIN_VIBRANT_SATURATION, 1f); | ||
palette.DarkVibrant = _findColorVariation(palette, swatches, maxPopulation, | ||
@@ -154,2 +160,4 @@ opts.targetDarkLuma, | ||
) | ||
// mMutedSwatch = findColor(TARGET_NORMAL_LUMA, MIN_NORMAL_LUMA, MAX_NORMAL_LUMA, | ||
// TARGET_MUTED_SATURATION, 0f, MAX_MUTED_SATURATION); | ||
palette.Muted = _findColorVariation(palette, swatches, maxPopulation, | ||
@@ -164,2 +172,4 @@ opts.targetNormalLuma, | ||
) | ||
// mLightMutedColor = findColor(TARGET_LIGHT_LUMA, MIN_LIGHT_LUMA, 1f, | ||
// TARGET_MUTED_SATURATION, 0f, MAX_MUTED_SATURATION); | ||
palette.LightMuted = _findColorVariation(palette, swatches, maxPopulation, | ||
@@ -174,2 +184,4 @@ opts.targetLightLuma, | ||
) | ||
// mDarkMutedSwatch = findColor(TARGET_DARK_LUMA, 0f, MAX_DARK_LUMA, | ||
// TARGET_MUTED_SATURATION, 0f, MAX_MUTED_SATURATION); | ||
palette.DarkMuted = _findColorVariation(palette, swatches, maxPopulation, | ||
@@ -176,0 +188,0 @@ opts.targetDarkLuma, |
import * as Bluebird from 'bluebird' | ||
import { Image, Options, ImageData, ImageSource } from '../typing' | ||
import { Filter, Image, Options, ImageData, ImageSource } from '../typing' | ||
export abstract class ImageBase implements Image { | ||
abstract load (image: ImageSource ): Bluebird<ImageBase> | ||
abstract clear (): void | ||
abstract update (imageData: ImageData): void | ||
abstract getWidth (): number | ||
abstract getHeight (): number | ||
abstract resize (targetWidth: number, targetHeight: number, ratio: number): void | ||
abstract getPixelCount () : number | ||
abstract getImageData (): ImageData | ||
abstract remove (): void | ||
scaleDown (opts: Options): void { | ||
abstract load(image: ImageSource): Bluebird<ImageBase> | ||
abstract clear(): void | ||
abstract update(imageData: ImageData): void | ||
abstract getWidth(): number | ||
abstract getHeight(): number | ||
abstract resize(targetWidth: number, targetHeight: number, ratio: number): void | ||
abstract getPixelCount(): number | ||
abstract getImageData(): ImageData | ||
abstract remove(): void | ||
scaleDown(opts: Options): void { | ||
let width: number = this.getWidth() | ||
let height: number = this.getHeight() | ||
let ratio: number = 1 | ||
@@ -27,5 +27,27 @@ | ||
} | ||
if (ratio < 1) this.resize(width * ratio, height * ratio, ratio) | ||
} | ||
applyFilter(filter: Filter): Bluebird<ImageData> { | ||
let imageData = this.getImageData() | ||
if (typeof filter === 'function') { | ||
let pixels = imageData.data | ||
let n = pixels.length / 4 | ||
let offset, r, g, b, a | ||
for (let i = 0; i < n; i++) { | ||
offset = i * 4 | ||
r = pixels[offset + 0] | ||
g = pixels[offset + 1] | ||
b = pixels[offset + 2] | ||
a = pixels[offset + 3] | ||
// Mark ignored color | ||
if (!filter(r, g, b, a)) pixels[offset + 3] = 0 | ||
} | ||
} | ||
return Bluebird.resolve(imageData) | ||
} | ||
} |
@@ -35,3 +35,3 @@ import * as Bluebird from 'bluebird' | ||
canvas.className = 'vibrant-canvas' | ||
canvas.style.visibility = 'hidden' | ||
canvas.style.display = 'none' | ||
@@ -73,8 +73,9 @@ this._width = canvas.width = img.width | ||
img.onload = onImageLoad | ||
// Already loaded | ||
if (img.complete) onImageLoad() | ||
img.onerror = (e) => reject(new Error(`Fail to load image: ${src}`)) | ||
if (img.complete) { | ||
// Already loaded | ||
onImageLoad() | ||
} else { | ||
img.onload = onImageLoad | ||
img.onerror = (e) => reject(new Error(`Fail to load image: ${src}`)) | ||
} | ||
}) | ||
@@ -112,2 +113,2 @@ } | ||
} | ||
} | ||
} |
@@ -9,5 +9,5 @@ import * as Bluebird from 'bluebird' | ||
interface ProtocalHandler { | ||
get(url: string, cb: (res: any) => void): void | ||
get(url: string | any, cb?: (res: any) => void): any | ||
} | ||
} | ||
interface ProtocalHandlerMap { | ||
@@ -14,0 +14,0 @@ [protocolName: string]: ProtocalHandler |
@@ -1,1 +0,4 @@ | ||
export { default as MMCQ } from './mmcq' | ||
import { Quantizer } from '../typing' | ||
export { default as MMCQ } from './mmcq' | ||
export var WebWorker: Quantizer = null |
@@ -5,3 +5,3 @@ import { | ||
Pixels, | ||
Options | ||
ComputedOptions | ||
} from '../typing' | ||
@@ -12,26 +12,28 @@ import { Swatch } from '../color' | ||
const maxIterations = 1000 | ||
const fractByPopulations = 0.75 | ||
function _splitBoxes(pq: PQueue<VBox>, target: number): void { | ||
let colorCount = 1 | ||
let iteration = 0 | ||
while (iteration < maxIterations) { | ||
iteration++ | ||
let lastSize = pq.size() | ||
while (pq.size() < target) { | ||
let vbox = pq.pop() | ||
if (!vbox.count()) continue | ||
let [vbox1, vbox2] = vbox.split() | ||
if (vbox && vbox.count() > 0) { | ||
let [vbox1, vbox2] = vbox.split() | ||
pq.push(vbox1) | ||
if (vbox2) { | ||
pq.push(vbox1) | ||
if (vbox2 && vbox2.count() > 0) pq.push(vbox2) | ||
pq.push(vbox2) | ||
colorCount++ | ||
// No more new boxes, converged | ||
if (pq.size() === lastSize) { | ||
break | ||
} else { | ||
lastSize = pq.size() | ||
} | ||
} else { | ||
break | ||
} | ||
if (colorCount >= target || iteration > maxIterations) return | ||
} | ||
} | ||
const MMCQ: Quantizer = (pixels: Pixels, opts: Options): Array<Swatch> => { | ||
const MMCQ = (pixels: Pixels, opts: ComputedOptions): Array<Swatch> => { | ||
if (pixels.length === 0 || opts.colorCount < 2 || opts.colorCount > 256) { | ||
@@ -41,14 +43,3 @@ throw new Error('Wrong MMCQ parameters') | ||
let shouldIgnore: Filter = null | ||
if (Array.isArray(opts.filters) && opts.filters.length > 0) { | ||
shouldIgnore = (r, g, b, a) => { | ||
for (let f of opts.filters) { | ||
if (!f(r, g, b, a)) return true | ||
} | ||
return false | ||
} | ||
} | ||
let vbox = VBox.build(pixels, shouldIgnore) | ||
let vbox = VBox.build(pixels) | ||
let hist = vbox.hist | ||
@@ -71,14 +62,12 @@ let colorCount = Object.keys(hist).length | ||
// calculate the actual colors | ||
return generateSwatches(pq2) | ||
} | ||
function generateSwatches(pq: PQueue<VBox>) { | ||
let swatches: Swatch[] = [] | ||
// let vboxes = [] | ||
while (pq2.size()) { | ||
let v = pq2.pop() | ||
while (pq.size()) { | ||
let v = pq.pop() | ||
let color = v.avg() | ||
let [r, g, b] = color | ||
if (shouldIgnore === null || !shouldIgnore(r, g, b, 255)) { | ||
// @vboxes.push v | ||
swatches.push(new Swatch(color, v.count())) | ||
} | ||
swatches.push(new Swatch(color, v.count())) | ||
} | ||
@@ -85,0 +74,0 @@ return swatches |
@@ -43,3 +43,4 @@ import { Vec3 } from '../color' | ||
if (typeof shouldIgnore === 'function' && shouldIgnore(r, g, b, a)) continue | ||
// Ignored pixels' alpha is marked as 0 in filtering stage | ||
if (a === 0) continue | ||
@@ -46,0 +47,0 @@ r = r >> RSHIFT |
@@ -5,9 +5,3 @@ import { expect } from 'chai' | ||
// if (typeof Window !== undefined && this instanceof Window) { | ||
// Vibrant = this.Vibrant | ||
// } else { | ||
// Vibrant = require('../index') | ||
// } | ||
// Vibrant = require('../') | ||
// expect = require('chai').expect | ||
import omit = require('lodash/omit') | ||
@@ -35,6 +29,7 @@ describe('builder', () => { | ||
expect(v.opts.combinedFilter, 'should have combined filter').to.be.a('function') | ||
expect(v.opts).to.deep.equal(expected) | ||
expect(omit(v.opts, 'combinedFilter')).to.deep.equal(expected) | ||
}) | ||
}) |
@@ -10,7 +10,4 @@ import _ = require('lodash') | ||
// Comfirmed visually and established as baseline for future versions | ||
export const REFERENCE_PALETTE: any = { | ||
chrome: require('../../../data/chrome-exec-ref.json'), | ||
firefox: require('../../../data/firefox-exec-ref.json'), | ||
ie: require('../../../data/ie11-exec-ref.json') | ||
} | ||
export const REFERENCE_PALETTE: any = require('../../../data/browser-palette-ref.json') | ||
export const REFERENCE_PALETTE_WITH_FILTER: any = require('../../../data/browser-palette-with-filter-ref.json') | ||
@@ -17,0 +14,0 @@ export const TARGETS = Object.keys(REFERENCE_PALETTE) |
import { expect } from 'chai' | ||
import { VibrantStatic } from '../../typing' | ||
import Builder from '../../builder' | ||
import path = require('path') | ||
@@ -10,2 +11,3 @@ import Promise = require('bluebird') | ||
REFERENCE_PALETTE, | ||
REFERENCE_PALETTE_WITH_FILTER, | ||
TARGETS, | ||
@@ -35,3 +37,3 @@ TEST_PORT, | ||
const paletteCallback = (sample: Sample, done?: MochaDone) => | ||
const paletteCallback = (references: any, sample: Sample, done?: MochaDone) => | ||
(err: Error, palette?: Palette) => { | ||
@@ -44,3 +46,3 @@ if (err != null) { throw err } | ||
let key = sample.i.toString() | ||
let expected = REFERENCE_PALETTE[target][key][name] | ||
let expected = references[target][key][name] | ||
let result = { | ||
@@ -53,8 +55,9 @@ target, | ||
if (actual === null) { | ||
expect(expected, `${name} color from '${target}' was expected`).to.be.null | ||
} | ||
if (expected === null) { | ||
expect(actual, `${name} color form '${target}' was not expected`).to.be.null | ||
if (actual !== null) { | ||
console.warn(`WARN: ${name} color form '${target}' was not expected. Got ${actual.getHex()}`) | ||
} | ||
// expect(actual, `${name} color form '${target}' was not expected`).to.be.null | ||
} else { | ||
expect(actual, `${name} color from '${target}' was expected`).not.to.be.null | ||
let actualHex = actual.getHex() | ||
@@ -91,16 +94,20 @@ let diff = util.hexDiff(actualHex, expected) | ||
export const testVibrant = (Vibrant: VibrantStatic, sample: Sample, done: MochaDone, pathKey: SamplePathKey = 'filePath') => { | ||
Vibrant.from(sample[pathKey]) | ||
export const testVibrant = (Vibrant: VibrantStatic, sample: Sample, done: MochaDone, pathKey: SamplePathKey = 'filePath', builderCallback: (b: Builder) => Builder = null, references: any = REFERENCE_PALETTE_WITH_FILTER) => { | ||
let builder = Vibrant.from(sample[pathKey]) | ||
.quality(1) | ||
.clearFilters() | ||
.getPalette(paletteCallback(sample, done)) | ||
if (typeof builderCallback === 'function') builder = builderCallback(builder) | ||
builder.getPalette(paletteCallback(references, sample, done)) | ||
} | ||
export const testVibrantAsPromised = (Vibrant: VibrantStatic, sample: Sample, pathKey: SamplePathKey = 'filePath') => { | ||
let cb = paletteCallback(sample) | ||
return Vibrant.from(sample[pathKey]) | ||
export const testVibrantAsPromised = (Vibrant: VibrantStatic, sample: Sample, pathKey: SamplePathKey = 'filePath', builderCallback: (b: Builder) => Builder = null, references: any = REFERENCE_PALETTE_WITH_FILTER) => { | ||
let cb = paletteCallback(references, sample) | ||
let builder = Vibrant.from(sample[pathKey]) | ||
.quality(1) | ||
.clearFilters() | ||
.getPalette() | ||
if (typeof builderCallback === 'function') builder = builderCallback(builder) | ||
builder.getPalette() | ||
.then(palette => cb(null, palette)) | ||
@@ -107,0 +114,0 @@ .catch(e => cb(e)) |
import { | ||
REFERENCE_PALETTE, | ||
} from './common/data' | ||
import { | ||
testVibrant, | ||
@@ -17,2 +20,3 @@ testVibrantAsPromised, | ||
import Vibrant = require('../') | ||
import Builder from '../builder' | ||
@@ -27,2 +31,13 @@ describe('Palette Extraction', () => { | ||
describe('process samples (no filters)', () => | ||
SAMPLES.forEach((sample) => { | ||
const builderCallback = (builder: Builder) => builder.clearFilters() | ||
it(`${sample.fileName} (callback)`, done => testVibrant(Vibrant, sample, done, 'filePath', builderCallback, REFERENCE_PALETTE)) | ||
it(`${sample.fileName} (Promise)`, () => testVibrantAsPromised(Vibrant, sample, 'filePath', builderCallback, REFERENCE_PALETTE)) | ||
}) | ||
) | ||
describe('process remote images (http)', function () { | ||
@@ -29,0 +44,0 @@ let server: http.Server = null |
@@ -33,2 +33,3 @@ import * as Bluebird from 'bluebird' | ||
getImageData(): ImageData | ||
applyFilter(filter: Filter): Bluebird<ImageData> | ||
remove(): void | ||
@@ -49,3 +50,3 @@ scaleDown(opts: Options): void | ||
export interface Quantizer { | ||
(pixels: Pixels, opts: Options): Resolvable<Array<Swatch>> | ||
(pixels: Pixels, opts: ComputedOptions): Resolvable<Array<Swatch>> | ||
} | ||
@@ -66,2 +67,6 @@ | ||
generator?: Generator | ||
} | ||
export interface ComputedOptions extends Options { | ||
combinedFilter: Filter | ||
} |
@@ -5,6 +5,8 @@ import { | ||
Options, | ||
Callback | ||
ComputedOptions, | ||
Callback, | ||
Filter | ||
} from './typing' | ||
import { Palette } from './color' | ||
import { Palette, Swatch } from './color' | ||
@@ -20,10 +22,10 @@ import Bluebird = require('bluebird') | ||
import * as Generator from './generator' | ||
import * as Filter from './filter' | ||
import * as Filters from './filter' | ||
class Vibrant { | ||
static Builder = Builder | ||
static Builder = Builder | ||
static Quantizer = Quantizer | ||
static Generator = Generator | ||
static Filter = Filter | ||
static Filter = Filters | ||
static Util = Util | ||
@@ -37,3 +39,3 @@ | ||
quantizer: Quantizer.MMCQ, | ||
filters: [Filter.Default] | ||
filters: [Filters.Default] | ||
} | ||
@@ -45,9 +47,9 @@ | ||
opts: Options | ||
opts: ComputedOptions | ||
private _palette: Palette | ||
constructor(private _src: ImageSource, opts?: Partial<Options>) { | ||
this.opts = <Options>defaults({}, opts, Vibrant.DefaultOpts) | ||
this.opts = <ComputedOptions>defaults({}, opts, Vibrant.DefaultOpts) | ||
this.opts.combinedFilter = Filters.combineFilters(this.opts.filters) | ||
} | ||
private _process(image: Image): Bluebird<Palette> { | ||
let { opts } = this | ||
private _process(image: Image, opts: ComputedOptions): Bluebird<Palette> { | ||
let { quantizer, generator} = opts | ||
@@ -57,8 +59,6 @@ | ||
let imageData = image.getImageData() | ||
return Bluebird.resolve(quantizer(imageData.data, opts)) | ||
return image.applyFilter(opts.combinedFilter) | ||
.then((imageData) => quantizer(imageData.data, opts)) | ||
.then((colors) => Swatch.applyFilter(colors, opts.combinedFilter)) | ||
.then((colors) => Bluebird.resolve(generator(colors))) | ||
.tap((palette) => this._palette = palette) | ||
.finally(() => image.remove()) | ||
} | ||
@@ -76,3 +76,5 @@ | ||
return image.load(this._src) | ||
.then((image) => this._process(image)) | ||
.then((image) => this._process(image, this.opts)) | ||
.tap((palette) => this._palette = palette) | ||
.finally(() => image.remove()) | ||
.asCallback(cb) | ||
@@ -79,0 +81,0 @@ } |
@@ -5,6 +5,9 @@ var path = require('path') | ||
var entry = './src/bundle.ts' | ||
var entryWithWorker = './src/bundle.worker.ts' | ||
module.exports = { | ||
entry: { | ||
'vibrant': entry, | ||
'vibrant.min': entry | ||
'vibrant.min': entry, | ||
'vibrant.worker': entryWithWorker, | ||
'vibrant.worker.min': entryWithWorker | ||
}, | ||
@@ -21,3 +24,3 @@ devtool: "source-map", | ||
options: { | ||
configFileName: 'tsconfig.browser.json' | ||
configFile: 'tsconfig.browser.json' | ||
} | ||
@@ -24,0 +27,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
4684183
147
39714
1
319
22
+ Added@types/node@8.10.66(transitive)
- Removed@types/node@7.10.14(transitive)
Updated@types/node@^8.0.53