register photon extensions. add more .ctb target machines
This commit is contained in:
parent
a1af70b496
commit
304a2a4e24
10 changed files with 329 additions and 89 deletions
15
src/kiri/dev/sla/Creality.LD-002H.CTB.json
Normal file
15
src/kiri/dev/sla/Creality.LD-002H.CTB.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"no_clone": true,
|
||||
"cmd": {},
|
||||
"settings": {
|
||||
"bed_width": 127,
|
||||
"bed_depth": 80,
|
||||
"bed_height": 1,
|
||||
"max_height": 160,
|
||||
"resolution_x": 2560,
|
||||
"resolution_y": 1620,
|
||||
"sla_format": "ctb",
|
||||
"sla_file_ext": "ctb",
|
||||
"sla_format_version": 3
|
||||
}
|
||||
}
|
||||
15
src/kiri/dev/sla/Creality.LD-002R.CTB.json
Normal file
15
src/kiri/dev/sla/Creality.LD-002R.CTB.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"no_clone": true,
|
||||
"cmd": {},
|
||||
"settings": {
|
||||
"bed_width": 119,
|
||||
"bed_depth": 65,
|
||||
"bed_height": 1,
|
||||
"max_height": 160,
|
||||
"resolution_x": 2560,
|
||||
"resolution_y": 1440,
|
||||
"sla_format": "ctb",
|
||||
"sla_file_ext": "ctb",
|
||||
"sla_format_version": 3
|
||||
}
|
||||
}
|
||||
15
src/kiri/dev/sla/Elegoo.Mars.2.Pro.CTB.json
Normal file
15
src/kiri/dev/sla/Elegoo.Mars.2.Pro.CTB.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"no_clone": true,
|
||||
"cmd": {},
|
||||
"settings": {
|
||||
"bed_width": 129,
|
||||
"bed_depth": 80,
|
||||
"bed_height": 1,
|
||||
"max_height": 160,
|
||||
"resolution_x": 1620,
|
||||
"resolution_y": 2560,
|
||||
"sla_format": "ctb",
|
||||
"sla_file_ext": "ctb",
|
||||
"sla_format_version": 3
|
||||
}
|
||||
}
|
||||
15
src/kiri/dev/sla/Elegoo.Saturn.CTB.json
Normal file
15
src/kiri/dev/sla/Elegoo.Saturn.CTB.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"no_clone": true,
|
||||
"cmd": {},
|
||||
"settings": {
|
||||
"bed_width": 192,
|
||||
"bed_depth": 120,
|
||||
"bed_height": 1,
|
||||
"max_height": 200,
|
||||
"resolution_x": 3840,
|
||||
"resolution_y": 2400,
|
||||
"sla_format": "ctb",
|
||||
"sla_file_ext": "ctb",
|
||||
"sla_format_version": 3
|
||||
}
|
||||
}
|
||||
|
|
@ -45,6 +45,41 @@ export const SLA_FORMATS = {
|
|||
available: true,
|
||||
priority: 1,
|
||||
family: 'chitubox'
|
||||
},
|
||||
pwmo: {
|
||||
id: 'pwmo',
|
||||
ext: 'pwmo',
|
||||
proprietary: true,
|
||||
available: false,
|
||||
family: 'photon-workshop'
|
||||
},
|
||||
pwma: {
|
||||
id: 'pwma',
|
||||
ext: 'pwma',
|
||||
proprietary: true,
|
||||
available: false,
|
||||
family: 'photon-workshop'
|
||||
},
|
||||
pwmb: {
|
||||
id: 'pwmb',
|
||||
ext: 'pwmb',
|
||||
proprietary: true,
|
||||
available: false,
|
||||
family: 'photon-workshop'
|
||||
},
|
||||
pm3n: {
|
||||
id: 'pm3n',
|
||||
ext: 'pm3n',
|
||||
proprietary: true,
|
||||
available: false,
|
||||
family: 'photon-workshop'
|
||||
},
|
||||
pm4n: {
|
||||
id: 'pm4n',
|
||||
ext: 'pm4n',
|
||||
proprietary: true,
|
||||
available: false,
|
||||
family: 'photon-workshop'
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
import { CXDLP } from './x_cxdlp.js';
|
||||
import { CTB } from './x_ctb.js';
|
||||
import { photon } from './x_photon.js';
|
||||
import { PW } from './x_pw.js';
|
||||
import { SLA } from './init-work.js';
|
||||
import { RSLA } from './x_rsla.js';
|
||||
import { VSLA } from './x_vsla.js';
|
||||
|
|
@ -66,6 +67,11 @@ export function sla_export(print, online, ondone) {
|
|||
});
|
||||
}
|
||||
|
||||
if (format === 'pwmo' || format === 'pwma' || format === 'pwmb' ||
|
||||
format === 'pm3n' || format === 'pm4n') {
|
||||
return PW.encode(format);
|
||||
}
|
||||
|
||||
if (format === 'photon' || format === 'photons') {
|
||||
let legacyMode = SLA.legacy || alias > 1,
|
||||
part1 = legacyMode ? 0.25 : 0.85,
|
||||
|
|
|
|||
76
src/kiri/mode/sla/work/raster.js
Normal file
76
src/kiri/mode/sla/work/raster.js
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
export function createRasterContext(print) {
|
||||
let { settings, widgets } = print;
|
||||
let { device, process } = settings;
|
||||
let width = device.resolutionX;
|
||||
let height = device.resolutionY;
|
||||
let layermax = 0;
|
||||
|
||||
widgets = widgets.filter(w => !w.track.ignore && !w.meta.disabled);
|
||||
widgets.forEach(widget => {
|
||||
layermax = Math.max(layermax, widget.slices.length);
|
||||
});
|
||||
|
||||
return {
|
||||
settings,
|
||||
device,
|
||||
process,
|
||||
widgets,
|
||||
width,
|
||||
height,
|
||||
scaleX: width / device.bedWidth,
|
||||
scaleY: height / device.bedDepth,
|
||||
layermax
|
||||
};
|
||||
}
|
||||
|
||||
export function renderRasterLayers(print, renderer, onlayer, progress) {
|
||||
let ctx = createRasterContext(print);
|
||||
let { process, widgets, width, height, scaleX, scaleY, layermax } = ctx;
|
||||
let volume = 0;
|
||||
let count = 0;
|
||||
|
||||
for (let index=0; index<layermax; index++) {
|
||||
let rendered = renderer.renderLayerWasm({
|
||||
index,
|
||||
width,
|
||||
height,
|
||||
widgets,
|
||||
scaleX,
|
||||
scaleY,
|
||||
masks: []
|
||||
});
|
||||
if (rendered.end) break;
|
||||
|
||||
volume += rendered.area * process.slaSlice;
|
||||
onlayer({
|
||||
ctx,
|
||||
index,
|
||||
rendered,
|
||||
bottom: index < process.slaBaseLayers,
|
||||
z: process.slaFirstOffset + process.slaSlice * (index + 1)
|
||||
});
|
||||
count++;
|
||||
if (progress) progress(index / layermax);
|
||||
}
|
||||
|
||||
return { ctx, layers: count, volume };
|
||||
}
|
||||
|
||||
export function imageToRowMajor(image, width, height, map) {
|
||||
let data = new Uint8Array(width * height);
|
||||
|
||||
for (let x=0; x<width; x++) {
|
||||
for (let y=0; y<height; y++) {
|
||||
let value = image[x * height + y] || 0;
|
||||
data[y * width + x] = map ? map(value) : value;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
export function round(value) {
|
||||
return Number.parseFloat(Number(value || 0).toFixed(5));
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import { JSZip } from '../../../../ext/jszip-esm.js';
|
||||
import { PNG } from '../../../../ext/pngjs.esm.js';
|
||||
import { imageToRowMajor, renderRasterLayers, round } from './raster.js';
|
||||
|
||||
const CTB_V3_MAGIC = 0x12fd0086;
|
||||
const HEADER_SIZE = 0x70;
|
||||
|
|
@ -20,55 +21,34 @@ function encode(print, progress, renderer) {
|
|||
}
|
||||
|
||||
function encodeWithPhoton(print, progress, photon) {
|
||||
let { settings, widgets } = print;
|
||||
let { device, process } = settings;
|
||||
let width = device.resolutionX;
|
||||
let height = device.resolutionY;
|
||||
let scaleX = width / device.bedWidth;
|
||||
let scaleY = height / device.bedDepth;
|
||||
let layermax = 0;
|
||||
let layers = [];
|
||||
let volume = 0;
|
||||
let seed = makeSeed(print);
|
||||
let previews = [
|
||||
createPreview(400, 300),
|
||||
createPreview(200, 125)
|
||||
];
|
||||
|
||||
widgets = widgets.filter(w => !w.track.ignore && !w.meta.disabled);
|
||||
widgets.forEach(widget => {
|
||||
layermax = Math.max(layermax, widget.slices.length);
|
||||
});
|
||||
|
||||
for (let index=0; index<layermax; index++) {
|
||||
let rendered = photon.renderLayerWasm({
|
||||
index,
|
||||
width,
|
||||
height,
|
||||
widgets,
|
||||
scaleX,
|
||||
scaleY,
|
||||
masks: []
|
||||
});
|
||||
if (rendered.end) {
|
||||
break;
|
||||
}
|
||||
let { ctx, volume } = renderRasterLayers(print, photon, params => {
|
||||
let { index, rendered, bottom, z, ctx } = params;
|
||||
let { process, width, height } = ctx;
|
||||
|
||||
let pixels = renderToCTBPixels(rendered.image, width, height);
|
||||
let encoded = encipher(seed, index, encodeRLE(pixels));
|
||||
let bottom = index < process.slaBaseLayers;
|
||||
previews.forEach(preview => accumulatePreview(preview, rendered.image, width, height));
|
||||
|
||||
volume += rendered.area * process.slaSlice;
|
||||
layers.push({
|
||||
index,
|
||||
z: process.slaFirstOffset + process.slaSlice * (index + 1),
|
||||
z,
|
||||
exposure: bottom ? process.slaBaseOn : process.slaLayerOn,
|
||||
lightOffDelay: bottom ? process.slaBaseOff : process.slaLayerOff,
|
||||
liftDistance: bottom ? process.slaBasePeelDist : process.slaPeelDist,
|
||||
liftSpeed: (bottom ? process.slaBasePeelLiftRate : process.slaPeelLiftRate) * 60,
|
||||
data: encoded
|
||||
});
|
||||
}, progress ? (value) => progress(value * 0.85, "ctb_encode") : null);
|
||||
|
||||
if (progress) progress((index / layermax) * 0.85, "ctb_encode");
|
||||
}
|
||||
|
||||
let file = writeCTB({ device, process, layers, volume, seed });
|
||||
let { device, process } = ctx;
|
||||
let file = writeCTB({ device, process, layers, volume, seed, previews });
|
||||
if (progress) progress(1, "ctb_write");
|
||||
|
||||
return { file, layers: layers.length, volume };
|
||||
|
|
@ -86,6 +66,7 @@ function read(input) {
|
|||
header,
|
||||
print: readPrintParams(view, header),
|
||||
machine: readMachineName(view, header),
|
||||
previews: readPreviews(view, header),
|
||||
layers,
|
||||
layout: inferLayout(header, layers)
|
||||
};
|
||||
|
|
@ -141,12 +122,17 @@ function decodeLayer(view, header, layer) {
|
|||
}
|
||||
|
||||
function writeCTB(params) {
|
||||
let { device, process, layers, volume, seed } = params;
|
||||
let { device, process, layers, volume, seed, previews } = params;
|
||||
let machine = device.deviceName || "Generic CTB";
|
||||
let machineBytes = new TextEncoder().encode(machine);
|
||||
let previewData = previews.map(encodePreview);
|
||||
let printTime = Math.round((process.slaBaseLayers * process.slaBaseOn) +
|
||||
Math.max(0, layers.length - process.slaBaseLayers) * process.slaLayerOn);
|
||||
let printParamsOffset = HEADER_SIZE;
|
||||
let previewLargeOffset = HEADER_SIZE;
|
||||
let previewLargeDataOffset = previewLargeOffset + 32;
|
||||
let previewSmallOffset = previewLargeDataOffset + previewData[0].length;
|
||||
let previewSmallDataOffset = previewSmallOffset + 32;
|
||||
let printParamsOffset = previewSmallDataOffset + previewData[1].length;
|
||||
let machineInfoOffset = printParamsOffset + PRINT_PARAMS_SIZE;
|
||||
let nameOffset = machineInfoOffset + MACHINE_INFO_SIZE;
|
||||
let layerTableOffset = nameOffset + machineBytes.length;
|
||||
|
|
@ -169,10 +155,20 @@ function writeCTB(params) {
|
|||
layers,
|
||||
seed,
|
||||
printTime,
|
||||
previewLargeOffset,
|
||||
previewSmallOffset,
|
||||
printParamsOffset,
|
||||
machineInfoOffset,
|
||||
layerTableOffset
|
||||
});
|
||||
writer.seek(previewLargeOffset);
|
||||
writePreviewRecord(writer, previews[0], previewLargeDataOffset, previewData[0]);
|
||||
writer.seek(previewLargeDataOffset);
|
||||
writer.writeBytes(previewData[0]);
|
||||
writer.seek(previewSmallOffset);
|
||||
writePreviewRecord(writer, previews[1], previewSmallDataOffset, previewData[1]);
|
||||
writer.seek(previewSmallDataOffset);
|
||||
writer.writeBytes(previewData[1]);
|
||||
writer.seek(printParamsOffset);
|
||||
writePrintParams(writer, { process, volume });
|
||||
writer.seek(machineInfoOffset);
|
||||
|
|
@ -193,6 +189,7 @@ function writeCTB(params) {
|
|||
function writeHeader(writer, params) {
|
||||
let {
|
||||
device, process, layers, seed, printTime,
|
||||
previewLargeOffset, previewSmallOffset,
|
||||
printParamsOffset, machineInfoOffset, layerTableOffset
|
||||
} = params;
|
||||
|
||||
|
|
@ -209,10 +206,10 @@ function writeHeader(writer, params) {
|
|||
writer.writeU32(process.slaBaseLayers);
|
||||
writer.writeU32(device.resolutionX);
|
||||
writer.writeU32(device.resolutionY);
|
||||
writer.writeU32(0);
|
||||
writer.writeU32(previewLargeOffset);
|
||||
writer.writeU32(layerTableOffset);
|
||||
writer.writeU32(layers.length);
|
||||
writer.writeU32(0);
|
||||
writer.writeU32(previewSmallOffset);
|
||||
writer.writeU32(printTime);
|
||||
writer.writeU32(1);
|
||||
writer.writeU32(printParamsOffset);
|
||||
|
|
@ -225,6 +222,17 @@ function writeHeader(writer, params) {
|
|||
writer.writeU32(MACHINE_INFO_SIZE);
|
||||
}
|
||||
|
||||
function writePreviewRecord(writer, preview, dataOffset, data) {
|
||||
writer.writeU32(preview.width);
|
||||
writer.writeU32(preview.height);
|
||||
writer.writeU32(dataOffset);
|
||||
writer.writeU32(data.length);
|
||||
writer.writeU32(0);
|
||||
writer.writeU32(0);
|
||||
writer.writeU32(0);
|
||||
writer.writeU32(0);
|
||||
}
|
||||
|
||||
function writePrintParams(writer, params) {
|
||||
let { process, volume } = params;
|
||||
|
||||
|
|
@ -316,9 +324,10 @@ function readHeader(view) {
|
|||
resolutionX: view.getUint32(0x34, true),
|
||||
resolutionY: view.getUint32(0x38, true),
|
||||
previewOffset: view.getUint32(0x3c, true),
|
||||
previewLargeOffset: view.getUint32(0x3c, true),
|
||||
layerTableOffset: view.getUint32(0x40, true),
|
||||
layerCount: view.getUint32(0x44, true),
|
||||
previewOneLength: view.getUint32(0x48, true),
|
||||
previewSmallOffset: view.getUint32(0x48, true),
|
||||
printParamsOffset: view.getUint32(0x54, true),
|
||||
printParamsLength: view.getUint32(0x58, true),
|
||||
antiAliasLevel: view.getUint32(0x5c, true),
|
||||
|
|
@ -330,6 +339,27 @@ function readHeader(view) {
|
|||
};
|
||||
}
|
||||
|
||||
function readPreviews(view, header) {
|
||||
return [header.previewLargeOffset, header.previewSmallOffset]
|
||||
.filter(offset => offset > 0)
|
||||
.map((offset, index) => readPreviewRecord(view, offset, index));
|
||||
}
|
||||
|
||||
function readPreviewRecord(view, offset, index) {
|
||||
return {
|
||||
index,
|
||||
offset,
|
||||
width: view.getUint32(offset + 0, true),
|
||||
height: view.getUint32(offset + 4, true),
|
||||
imageOffset: view.getUint32(offset + 8, true),
|
||||
imageLength: view.getUint32(offset + 12, true),
|
||||
unknown16: view.getUint32(offset + 16, true),
|
||||
unknown20: view.getUint32(offset + 20, true),
|
||||
unknown24: view.getUint32(offset + 24, true),
|
||||
unknown28: view.getUint32(offset + 28, true)
|
||||
};
|
||||
}
|
||||
|
||||
function readLayerTable(view, header) {
|
||||
let layers = [];
|
||||
let offset = header.layerTableOffset;
|
||||
|
|
@ -500,14 +530,71 @@ function createRSLAManifest(ctb, layers) {
|
|||
};
|
||||
}
|
||||
|
||||
function renderToCTBPixels(image, width, height) {
|
||||
let data = new Uint8Array(width * height);
|
||||
for (let x=0; x<width; x++) {
|
||||
for (let y=0; y<height; y++) {
|
||||
data[y * width + x] = image[x * height + y] || 0;
|
||||
function createPreview(width, height) {
|
||||
return {
|
||||
width,
|
||||
height,
|
||||
image: new Uint8Array(width * height)
|
||||
};
|
||||
}
|
||||
|
||||
function accumulatePreview(preview, image, width, height) {
|
||||
let { image: target } = preview;
|
||||
let xscale = width / preview.width;
|
||||
let yscale = height / preview.height;
|
||||
|
||||
for (let y=0; y<preview.height; y++) {
|
||||
let sy = Math.min(height - 1, Math.floor(y * yscale));
|
||||
for (let x=0; x<preview.width; x++) {
|
||||
let sx = Math.min(width - 1, Math.floor(x * xscale));
|
||||
if (image[sx * height + sy]) {
|
||||
target[y * preview.width + x] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function encodePreview(preview) {
|
||||
let output = [];
|
||||
let data = preview.image;
|
||||
let color = previewColor(data[0]);
|
||||
let run = 1;
|
||||
|
||||
for (let i=1; i<data.length; i++) {
|
||||
let next = previewColor(data[i]);
|
||||
if (next === color && run < 0xfff) {
|
||||
run++;
|
||||
continue;
|
||||
}
|
||||
writePreviewRun(output, color, run);
|
||||
color = next;
|
||||
run = 1;
|
||||
}
|
||||
|
||||
writePreviewRun(output, color, run);
|
||||
return new Uint8Array(output);
|
||||
}
|
||||
|
||||
function writePreviewRun(output, color, length) {
|
||||
if (length === 1) {
|
||||
writePreviewU16(output, color);
|
||||
return;
|
||||
}
|
||||
|
||||
writePreviewU16(output, color | 0x0020);
|
||||
writePreviewU16(output, 0x3000 | (length - 1));
|
||||
}
|
||||
|
||||
function previewColor(value) {
|
||||
return value ? 0xffdf : 0x0000;
|
||||
}
|
||||
|
||||
function writePreviewU16(output, value) {
|
||||
output.push(value & 0xff, (value >> 8) & 0xff);
|
||||
}
|
||||
|
||||
function renderToCTBPixels(image, width, height) {
|
||||
return imageToRowMajor(image, width, height);
|
||||
}
|
||||
|
||||
function encodeRLE(input) {
|
||||
|
|
@ -675,10 +762,6 @@ function toDataView(input) {
|
|||
: new DataView(input.buffer || input, input.byteOffset || 0, input.byteLength);
|
||||
}
|
||||
|
||||
function round(value) {
|
||||
return Number.parseFloat(Number(value || 0).toFixed(5));
|
||||
}
|
||||
|
||||
function makeSeed(print) {
|
||||
let { device, process } = print.settings;
|
||||
let hash = 0x811c9dc5;
|
||||
|
|
|
|||
14
src/kiri/mode/sla/work/x_pw.js
Normal file
14
src/kiri/mode/sla/work/x_pw.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
const FAMILY = "Photon Workshop";
|
||||
|
||||
function encode(format) {
|
||||
return Promise.reject(new Error([
|
||||
`${FAMILY} format .${format} is registered but not implemented.`,
|
||||
"Add a fixture sliced by Photon Workshop before enabling this output target."
|
||||
].join(" ")));
|
||||
}
|
||||
|
||||
export const PW = {
|
||||
encode
|
||||
};
|
||||
|
|
@ -3,41 +3,18 @@
|
|||
import { JSZip } from '../../../../ext/jszip-esm.js';
|
||||
import { PNG } from '../../../../ext/pngjs.esm.js';
|
||||
import { photon } from './x_photon.js';
|
||||
import { imageToRowMajor, renderRasterLayers, round } from './raster.js';
|
||||
|
||||
const FORMAT = "rsla";
|
||||
const MIME = "application/vnd.gridspace.rsla+zip";
|
||||
|
||||
function encode(print, progress) {
|
||||
let { settings, widgets } = print;
|
||||
let { device, process } = settings;
|
||||
let width = device.resolutionX;
|
||||
let height = device.resolutionY;
|
||||
let scaleX = width / device.bedWidth;
|
||||
let scaleY = height / device.bedDepth;
|
||||
let layermax = 0;
|
||||
|
||||
widgets = widgets.filter(w => !w.track.ignore && !w.meta.disabled);
|
||||
widgets.forEach(widget => {
|
||||
layermax = Math.max(layermax, widget.slices.length);
|
||||
});
|
||||
|
||||
let layers = [];
|
||||
let volume = 0;
|
||||
let zip = new JSZip();
|
||||
|
||||
for (let index=0; index<layermax; index++) {
|
||||
let rendered = photon.renderLayerWasm({
|
||||
index,
|
||||
width,
|
||||
height,
|
||||
widgets,
|
||||
scaleX,
|
||||
scaleY,
|
||||
masks: []
|
||||
});
|
||||
if (rendered.end) {
|
||||
break;
|
||||
}
|
||||
let { ctx, volume } = renderRasterLayers(print, photon, params => {
|
||||
let { index, rendered, ctx } = params;
|
||||
let { process, width, height } = ctx;
|
||||
|
||||
let file = `layers/${index.toString().padStart(6, "0")}.png`;
|
||||
let layer = {
|
||||
|
|
@ -47,13 +24,11 @@ function encode(print, progress) {
|
|||
file
|
||||
};
|
||||
|
||||
volume += rendered.area * process.slaSlice;
|
||||
layers.push(layer);
|
||||
zip.file(file, imageToPNG(rendered.image, width, height));
|
||||
}, progress ? (value) => progress(value * 0.85, "raster_gen") : null);
|
||||
|
||||
if (progress) progress((index / layermax) * 0.85, "raster_gen");
|
||||
}
|
||||
|
||||
let { device, process } = ctx;
|
||||
let manifest = createManifest({ device, process, layers, volume });
|
||||
zip.file("manifest.json", JSON.stringify(manifest, null, 2));
|
||||
|
||||
|
|
@ -122,12 +97,7 @@ function createManifest(params) {
|
|||
}
|
||||
|
||||
function imageToPNG(image, width, height) {
|
||||
let data = new Uint8Array(width * height);
|
||||
for (let x=0; x<width; x++) {
|
||||
for (let y=0; y<height; y++) {
|
||||
data[y * width + x] = image[x * height + y] ? 255 : 0;
|
||||
}
|
||||
}
|
||||
let data = imageToRowMajor(image, width, height, value => value ? 255 : 0);
|
||||
return PNG.sync.write({ width, height, data }, {
|
||||
colorType: 0,
|
||||
inputColorType: 0,
|
||||
|
|
@ -135,10 +105,6 @@ function imageToPNG(image, width, height) {
|
|||
});
|
||||
}
|
||||
|
||||
function round(value) {
|
||||
return Number.parseFloat(Number(value || 0).toFixed(5));
|
||||
}
|
||||
|
||||
export const RSLA = {
|
||||
encode
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue