mirror of
https://github.com/CesiumGS/obj2gltf.git
synced 2024-11-27 10:30:16 -05:00
f141c2d9c9
A few npm dependencies were major versions behind, so this updates `yargs`, `fs-extra`, and `jasmin-spec-reporter` to their latest versions. The major change here is `fs-extra`, which now has promise implementations of all functions by default, this means there's no reason to manually `Promisify` a function any more, the result is less code overall. There is one important edge case, `fs-extra` uses built-in native Node promises, which do not have a `finally` function. If you start a promise change with an `fs-extra` function, you need to wrap it in `Promise.resolve` in order to make use of finally at the end (assuming you are using finally at all, if not you don't need to worry about it. The upside is that your code will always error if you forget to do this.
108 lines
2.9 KiB
JavaScript
108 lines
2.9 KiB
JavaScript
'use strict';
|
|
var Cesium = require('cesium');
|
|
var fsExtra = require('fs-extra');
|
|
var path = require('path');
|
|
var PNG = require('pngjs').PNG;
|
|
var Promise = require('bluebird');
|
|
|
|
var defined = Cesium.defined;
|
|
var WebGLConstants = Cesium.WebGLConstants;
|
|
|
|
module.exports = loadImage;
|
|
|
|
/**
|
|
* Load an image file and get information about it.
|
|
*
|
|
* @param {String} imagePath Path to the image file.
|
|
* @param {Object} options An object with the following properties:
|
|
* @param {Boolean} options.checkTransparency Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel.
|
|
* @returns {Promise} A promise resolving to the image information, or undefined if the file doesn't exist.
|
|
*
|
|
* @private
|
|
*/
|
|
function loadImage(imagePath, options) {
|
|
return fsExtra.readFile(imagePath)
|
|
.then(function(data) {
|
|
var extension = path.extname(imagePath).toLowerCase();
|
|
|
|
var info = {
|
|
transparent : false,
|
|
format : getFormat(3),
|
|
source : data,
|
|
extension : extension
|
|
};
|
|
|
|
if (extension === '.png') {
|
|
return getPngInfo(data, info, options);
|
|
}
|
|
|
|
return info;
|
|
});
|
|
}
|
|
|
|
function getPngInfo(data, info, options) {
|
|
// Color type is encoded in the 25th bit of the png
|
|
var colorType = data[25];
|
|
var channels = getChannels(colorType);
|
|
info.format = getFormat(channels);
|
|
|
|
if (channels === 4) {
|
|
if (options.checkTransparency) {
|
|
return isTransparent(data)
|
|
.then(function(transparent) {
|
|
info.transparent = transparent;
|
|
return info;
|
|
});
|
|
}
|
|
}
|
|
return info;
|
|
}
|
|
|
|
function isTransparent(data) {
|
|
return new Promise(function(resolve, reject) {
|
|
new PNG().parse(data, function(error, data) {
|
|
if (defined(error)) {
|
|
reject(error);
|
|
return;
|
|
}
|
|
var pixels = data.data;
|
|
var pixelsLength = data.width * data.height;
|
|
for (var i = 0; i < pixelsLength; ++i) {
|
|
if (pixels[i * 4 + 3] < 255) {
|
|
resolve(true);
|
|
return;
|
|
}
|
|
}
|
|
resolve(false);
|
|
});
|
|
});
|
|
}
|
|
|
|
function getChannels(colorType) {
|
|
switch (colorType) {
|
|
case 0: // greyscale
|
|
return 1;
|
|
case 2: // RGB
|
|
return 3;
|
|
case 4: // greyscale + alpha
|
|
return 2;
|
|
case 6: // RGB + alpha
|
|
return 4;
|
|
default:
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
function getFormat(channels) {
|
|
switch (channels) {
|
|
case 1:
|
|
return WebGLConstants.ALPHA;
|
|
case 2:
|
|
return WebGLConstants.LUMINANCE_ALPHA;
|
|
case 3:
|
|
return WebGLConstants.RGB;
|
|
case 4:
|
|
return WebGLConstants.RGBA;
|
|
}
|
|
}
|