Add ability to import multiple mural
This commit is contained in:
@@ -7,7 +7,7 @@ import { Store } from "../../lib/store";
|
|||||||
import { MuralList } from "./muralList";
|
import { MuralList } from "./muralList";
|
||||||
import { Coordinates, CordType } from "../../lib/coordinates";
|
import { Coordinates, CordType } from "../../lib/coordinates";
|
||||||
import { Palette } from "../../lib/palette";
|
import { Palette } from "../../lib/palette";
|
||||||
import { importArtWork } from "../importMural";
|
import { importArtWorks } from "../importMural";
|
||||||
import { Popup } from "./Popup";
|
import { Popup } from "./Popup";
|
||||||
import { Storage } from "../../lib/storage";
|
import { Storage } from "../../lib/storage";
|
||||||
import { takeCanvasShot } from "../../lib/canvashot";
|
import { takeCanvasShot } from "../../lib/canvashot";
|
||||||
@@ -106,8 +106,8 @@ export class Menu extends React.Component<Props, State> {
|
|||||||
|
|
||||||
import = async () => {
|
import = async () => {
|
||||||
try {
|
try {
|
||||||
const mural = await importArtWork(this.props.store, this.props.cords, this.props.palette);
|
const murals = await importArtWorks(this.props.store, this.props.cords, this.props.palette);
|
||||||
if (mural) {
|
for (const mural of murals) {
|
||||||
this.props.store.add(mural);
|
this.props.store.add(mural);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import { BIN_FORMATS } from "../importMural";
|
|||||||
import saveAs from "file-saver";
|
import saveAs from "file-saver";
|
||||||
import { Popup } from "./Popup";
|
import { Popup } from "./Popup";
|
||||||
import { Palette } from "../../lib/palette";
|
import { Palette } from "../../lib/palette";
|
||||||
import { Mural } from "../../lib/mural";
|
|
||||||
|
|
||||||
const Margin = styled.div`
|
const Margin = styled.div`
|
||||||
margin: 2px;
|
margin: 2px;
|
||||||
|
|||||||
+77
-56
@@ -85,11 +85,12 @@ export interface ImageToMuralOptions {
|
|||||||
quantizerSetting: DitherSetting;
|
quantizerSetting: DitherSetting;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function importArtWork(store: Store, cords: Coordinates, palette: Palette) {
|
export async function importArtWorks(store: Store, cords: Coordinates, palette: Palette) {
|
||||||
const file = await importFile();
|
const files = await importFiles();
|
||||||
if (file) {
|
const output: MuralOld[] = [];
|
||||||
|
for (const file of files) {
|
||||||
if (file.type === "mural") {
|
if (file.type === "mural") {
|
||||||
return file.data as MuralOld;
|
output.push(file.data);
|
||||||
} else {
|
} else {
|
||||||
const img = file.data as HTMLImageElement;
|
const img = file.data as HTMLImageElement;
|
||||||
const pixels = await imageToMural(img, palette);
|
const pixels = await imageToMural(img, palette);
|
||||||
@@ -111,9 +112,10 @@ export async function importArtWork(store: Store, cords: Coordinates, palette: P
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
validateMural(mural);
|
validateMural(mural);
|
||||||
return mural;
|
output.push(mural);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getQuantizedObjFromUser(quantized: QuantResult[]) {
|
export function getQuantizedObjFromUser(quantized: QuantResult[]) {
|
||||||
@@ -470,65 +472,84 @@ export function imageDataToCanvas(imageData: ImageData) {
|
|||||||
return canvas;
|
return canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function importFile() {
|
async function importFiles() {
|
||||||
const fileInput = new FileInput();
|
const fileInput = new FileInput();
|
||||||
fileInput.setAcceptType(["png", "jpg", "jpeg", ...TEXT_FORMATS, ...BIN_FORMATS]);
|
const images = ["png", "jpg", "jpeg"];
|
||||||
|
fileInput.setAcceptType([...images, ...TEXT_FORMATS, ...BIN_FORMATS]);
|
||||||
|
fileInput.allowMultiple(true);
|
||||||
const files = await fileInput.show();
|
const files = await fileInput.show();
|
||||||
const fileData = files[0];
|
const filteredFiles = [...files].filter(e => e);
|
||||||
if (!fileData) {
|
if (!filteredFiles.length) {
|
||||||
throw new Error("Empty file");
|
throw new Error("Empty file");
|
||||||
}
|
}
|
||||||
const ex = getExtension(fileData.name);
|
const imagesFiles = filteredFiles
|
||||||
const etn = ex.ex.toLowerCase();
|
.filter(e => images.some(r => e.name.toLowerCase().endsWith(r)));
|
||||||
const name = ex.text;
|
|
||||||
if (TEXT_FORMATS.includes(etn)) {
|
|
||||||
const content = await readAsString(fileData);
|
|
||||||
const mural = JSON.parse(content) as MuralOld;
|
|
||||||
if (!mural.name) {
|
|
||||||
mural.name = await Popup
|
|
||||||
.prompt("Missing name for this mural. Please enter it manually", name) || "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
if (imagesFiles.length > 1) {
|
||||||
type: "mural",
|
throw new Error("Only one image files allowed to be imported at the time");
|
||||||
data: mural,
|
}
|
||||||
};
|
|
||||||
} else if (BIN_FORMATS.includes(etn)) {
|
const output: ({
|
||||||
const buffer = await readAsArrayBuffer(fileData);
|
type: "mural",
|
||||||
const mural = await Mural.from(new Uint8Array(buffer));
|
data: MuralOld
|
||||||
const pixelBuffer = mural.pixelBuffer;
|
} | {
|
||||||
const pixels = Array.from({ length: mural.h }, () => Array(mural.w).fill(0));
|
type: "image",
|
||||||
let i = 0;
|
data: HTMLImageElement
|
||||||
let yy = -1;
|
}) [] = [];
|
||||||
leg:
|
for (const file of filteredFiles) {
|
||||||
for (;;) {
|
const ex = getExtension(file.name);
|
||||||
yy++;
|
const etn = ex.ex.toLowerCase();
|
||||||
if (pixelBuffer[i] === undefined) {
|
const name = ex.text;
|
||||||
break;
|
if (TEXT_FORMATS.includes(etn)) {
|
||||||
|
const content = await readAsString(file);
|
||||||
|
const mural = JSON.parse(content) as MuralOld;
|
||||||
|
if (!mural.name) {
|
||||||
|
mural.name = await Popup
|
||||||
|
.prompt("Missing name for this mural. Please enter it manually", name) || "";
|
||||||
}
|
}
|
||||||
// const ref = [];
|
|
||||||
// pixels.push(ref);
|
output.push({
|
||||||
for (let xx = 0; xx < mural.w; xx++) {
|
type: "mural",
|
||||||
const item = pixelBuffer[i++];
|
data: mural,
|
||||||
if (item != undefined) {
|
});
|
||||||
pixels[yy][xx] = item;
|
} else if (BIN_FORMATS.includes(etn)) {
|
||||||
//ref.push(item);
|
const buffer = await readAsArrayBuffer(file);
|
||||||
} else {
|
const mural = await Mural.from(new Uint8Array(buffer));
|
||||||
break leg;
|
const pixelBuffer = mural.pixelBuffer;
|
||||||
|
const pixels = Array.from({ length: mural.h }, () => Array(mural.w).fill(0));
|
||||||
|
let i = 0;
|
||||||
|
let yy = -1;
|
||||||
|
leg:
|
||||||
|
for (;;) {
|
||||||
|
yy++;
|
||||||
|
if (pixelBuffer[i] === undefined) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// const ref = [];
|
||||||
|
// pixels.push(ref);
|
||||||
|
for (let xx = 0; xx < mural.w; xx++) {
|
||||||
|
const item = pixelBuffer[i++];
|
||||||
|
if (item != undefined) {
|
||||||
|
pixels[yy][xx] = item;
|
||||||
|
//ref.push(item);
|
||||||
|
} else {
|
||||||
|
break leg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
output.push({
|
||||||
|
type: "mural",
|
||||||
|
data: {
|
||||||
|
name, x: mural.x, y: mural.y, pixels,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const readData = await readAsDataUrl(file);
|
||||||
|
output.push({
|
||||||
|
type: "image",
|
||||||
|
data: await loadImageSource(`${ex.text}.${ex.ex}`, readData),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return {
|
|
||||||
type: "mural",
|
|
||||||
data: {
|
|
||||||
name, x: mural.x, y: mural.y, pixels,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
const readData = await readAsDataUrl(fileData);
|
|
||||||
return {
|
|
||||||
type: "image",
|
|
||||||
data: await loadImageSource(`${ex.text}.${ex.ex}`, readData),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user