Last active
April 19, 2021 16:14
-
-
Save mikeemoo/3780b4d98732f6bfd7b0b662cc02db66 to your computer and use it in GitHub Desktop.
Node - Image to DDS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//@ts-ignore | |
import dxt from 'dxt-js'; | |
import { createCanvas, loadImage } from 'canvas'; | |
import fs from 'fs'; | |
import { Buffer } from 'buffer'; | |
(async () => { | |
const image = await loadImage('${__dirname}/input.jpg'); | |
const { width, height } = image; | |
const canvas = createCanvas(width, height); | |
const ctx = canvas.getContext('2d') | |
ctx.drawImage(image, 0, 0); | |
ctx.scale(1, -1); | |
// need to check this is actually correct | |
const pitch = Math.floor(((width * height) * 4 + 7) / 8); | |
let offset = 0; | |
const headerBuffer = Buffer.allocUnsafe(128); | |
headerBuffer.write('DDS ', offset++ * 4, 'ascii'); // [0] magic | |
headerBuffer.writeUInt32LE(124, offset++ * 4); // [1] header size | |
headerBuffer.writeUInt32LE(528391, offset++ * 4); // [2] flags | |
headerBuffer.writeUInt32LE(height, offset++ * 4); // [3] height | |
headerBuffer.writeUInt32LE(width, offset++ * 4); // [4] width | |
headerBuffer.writeUInt32LE(pitch, offset++ * 4); // [5] pitch | |
headerBuffer.writeUInt32LE(0, offset++ * 4); // [6] depth | |
headerBuffer.writeUInt32LE(1, offset++ * 4); // [7] mipMapCount | |
for (let i = 0; i < 11; i++) { | |
headerBuffer.writeUInt32LE(0, offset++ * 4); // [8 - 18] reserved | |
} | |
headerBuffer.writeUInt32LE(32, offset++ * 4); // [19] pf size | |
headerBuffer.writeUInt32LE(5, offset++ * 4); // [20] pf flags | |
headerBuffer.write('DXT1', offset++ * 4, 'ascii'); // [21] pf fourcc | |
headerBuffer.writeUInt32LE(32, offset++ * 4); // [22] pf rgbbitcount | |
headerBuffer.writeUInt32LE(0xFF000000, offset++ * 4);// [23] pf rbitmask | |
headerBuffer.writeUInt32LE(0xFF0000, offset++ * 4); // [24] pf gbitmask | |
headerBuffer.writeUInt32LE(0xFF00, offset++ * 4); // [25] pf bbitmask | |
headerBuffer.writeUInt32LE(0xFF, offset++ * 4); // [26] pf abitmask | |
headerBuffer.writeUInt32LE(0x1000, offset++ * 4); // [27] caps | |
headerBuffer.writeUInt32LE(0, offset++ * 4); // [28] caps2 | |
headerBuffer.writeUInt32LE(0, offset++ * 4); // [29] caps3 | |
headerBuffer.writeUInt32LE(0, offset++ * 4); // [30] reserved2 | |
let flags = dxt.flags.DXT1 | dxt.flags.ColourIterativeClusterFit | dxt.flags.ColourMetricPerceptual; | |
const compressed = dxt.compress( | |
ctx.getImageData(0, 0, width, height).data, | |
width, | |
height, | |
flags | |
); | |
let finalBuffer = Buffer.concat([ | |
headerBuffer, | |
Buffer.from(compressed) | |
]); | |
fs.writeFileSync(`${__dirname}/output.dds`, finalBuffer); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment