Add ability to import multiple mural

This commit is contained in:
2025-02-11 22:40:17 +01:00
parent 909188ba7a
commit 49f1cf008b
3 changed files with 80 additions and 60 deletions
+3 -3
View File
@@ -7,7 +7,7 @@ import { Store } from "../../lib/store";
import { MuralList } from "./muralList";
import { Coordinates, CordType } from "../../lib/coordinates";
import { Palette } from "../../lib/palette";
import { importArtWork } from "../importMural";
import { importArtWorks } from "../importMural";
import { Popup } from "./Popup";
import { Storage } from "../../lib/storage";
import { takeCanvasShot } from "../../lib/canvashot";
@@ -106,8 +106,8 @@ export class Menu extends React.Component<Props, State> {
import = async () => {
try {
const mural = await importArtWork(this.props.store, this.props.cords, this.props.palette);
if (mural) {
const murals = await importArtWorks(this.props.store, this.props.cords, this.props.palette);
for (const mural of murals) {
this.props.store.add(mural);
}
} catch (error) {
-1
View File
@@ -14,7 +14,6 @@ import { BIN_FORMATS } from "../importMural";
import saveAs from "file-saver";
import { Popup } from "./Popup";
import { Palette } from "../../lib/palette";
import { Mural } from "../../lib/mural";
const Margin = styled.div`
margin: 2px;
+40 -19
View File
@@ -85,11 +85,12 @@ export interface ImageToMuralOptions {
quantizerSetting: DitherSetting;
}
export async function importArtWork(store: Store, cords: Coordinates, palette: Palette) {
const file = await importFile();
if (file) {
export async function importArtWorks(store: Store, cords: Coordinates, palette: Palette) {
const files = await importFiles();
const output: MuralOld[] = [];
for (const file of files) {
if (file.type === "mural") {
return file.data as MuralOld;
output.push(file.data);
} else {
const img = file.data as HTMLImageElement;
const pixels = await imageToMural(img, palette);
@@ -111,9 +112,10 @@ export async function importArtWork(store: Store, cords: Coordinates, palette: P
});
});
validateMural(mural);
return mural;
output.push(mural);
}
}
return output;
}
export function getQuantizedObjFromUser(quantized: QuantResult[]) {
@@ -470,31 +472,48 @@ export function imageDataToCanvas(imageData: ImageData) {
return canvas;
}
async function importFile() {
async function importFiles() {
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 fileData = files[0];
if (!fileData) {
const filteredFiles = [...files].filter(e => e);
if (!filteredFiles.length) {
throw new Error("Empty file");
}
const ex = getExtension(fileData.name);
const imagesFiles = filteredFiles
.filter(e => images.some(r => e.name.toLowerCase().endsWith(r)));
if (imagesFiles.length > 1) {
throw new Error("Only one image files allowed to be imported at the time");
}
const output: ({
type: "mural",
data: MuralOld
} | {
type: "image",
data: HTMLImageElement
}) [] = [];
for (const file of filteredFiles) {
const ex = getExtension(file.name);
const etn = ex.ex.toLowerCase();
const name = ex.text;
if (TEXT_FORMATS.includes(etn)) {
const content = await readAsString(fileData);
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) || "";
}
return {
output.push({
type: "mural",
data: mural,
};
});
} else if (BIN_FORMATS.includes(etn)) {
const buffer = await readAsArrayBuffer(fileData);
const buffer = await readAsArrayBuffer(file);
const mural = await Mural.from(new Uint8Array(buffer));
const pixelBuffer = mural.pixelBuffer;
const pixels = Array.from({ length: mural.h }, () => Array(mural.w).fill(0));
@@ -518,17 +537,19 @@ async function importFile() {
}
}
}
return {
output.push({
type: "mural",
data: {
name, x: mural.x, y: mural.y, pixels,
},
};
});
} else {
const readData = await readAsDataUrl(fileData);
return {
const readData = await readAsDataUrl(file);
output.push({
type: "image",
data: await loadImageSource(`${ex.text}.${ex.ex}`, readData),
};
});
}
}
return output;
}