For those who might ever have a need to resize textures and / or convert texture data, here is one possible way of doing this.
Some might find handling of Uint16Array and Float32Array somewhat interesting.
This is not necessarily limited to THREE.DataTexture and the code can probably be simplified and improved. Try passing any texture.image
to the function to see what it does.
The whole code can be seen in my repository and can be tested with my IMG2MESH viewer / converter.
Don’t hesitate to try this and if you manage to improve it then post your code here.
async function resize_texture( image, res = 2048 ) {
let tex;
await new Promise( resolve => {
let canvas = document.createElement('canvas');
let scale = res / Math.max( image.width, image.height );
canvas.width = image.width * Math.min( 1, scale );
canvas.height = image.height * Math.min( 1, scale );
let ctx = canvas.getContext( '2d', { willReadFrequently: true } );
if ( image instanceof ImageData ) {
ctx.putImageData( image, 0, 0 );
} else if ( image.data && image.data.constructor === Float32Array ) {
let u8 = new Uint8Array( image.data.length );
for ( let i = 0; i < image.data.length; i ++ ) {
let tmp = Math.max( -1, Math.min( 1, image.data[ i ] ) );
tmp = tmp < 0 ? ( tmp * 0x8000 ) : ( tmp * 0x7FFF );
u8[ i ] = tmp / 128.0;
}
let imgData = new ImageData( new Uint8ClampedArray( u8.buffer ), image.width, image.height );
ctx.putImageData( imgData, 0, 0 );
} else if ( image.data && image.data.constructor === Uint16Array ) {
let u8 = new Uint8Array( image.data.length );
for ( let i = 0; i < image.data.length; i ++ ) {
let tmp = Math.max( -1, Math.min( 1, THREE.DataUtils.fromHalfFloat( image.data[ i ] ) ) );
tmp = tmp < 0 ? ( tmp * 0x8000 ) : ( tmp * 0x7FFF );
u8[ i ] = tmp / 128.0;
}
let imgData = new ImageData( new Uint8ClampedArray( u8.buffer ), image.width, image.height );
ctx.putImageData( imgData, 0, 0 );
} else if ( image.data && image.data.constructor === Uint8Array ) {
let imgData = new ImageData( new Uint8ClampedArray( image.data.buffer ), image.width, image.height );
ctx.putImageData( imgData, 0, 0 );
} else {
ctx.drawImage( image, 0, 0, canvas.width, canvas.height );
}
resolve( tex = new THREE.CanvasTexture( canvas ) );
});
return tex;
}