Skip to content

Commit cae9833

Browse files
Basic image import works
1 parent 9aedac3 commit cae9833

File tree

3 files changed

+93
-8
lines changed

3 files changed

+93
-8
lines changed

src/components/BuiltInTools/ImageImporter/index.tsx

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ export type ImageImporterToolInput = {
1717
gif?: boolean | undefined;
1818
};
1919

20+
// TODO: FIX GIFS
21+
// https://pyscript.com/@ckyiu/image-to-makecode-arcade/latest?files=main.py,index.html
2022
export default function ImageImporterTool(): React.ReactNode {
2123
const [inputBuf, setInputBuf] = React.useState<ArrayBuffer | null>(null);
2224

@@ -30,16 +32,65 @@ export default function ImageImporterTool(): React.ReactNode {
3032
const [outputCode, setOutputCode] = React.useState<string | null>(null);
3133
const [outputBuf, setOutputBuf] = React.useState<ArrayBuffer | null>(null);
3234

35+
const [iframeReady, setIframeReady] = React.useState(false);
36+
37+
const handleMessage = React.useCallback((e: MessageEvent) => {
38+
let data = e.data;
39+
console.log("Received message from iframe");
40+
if (e.origin !== "https://ckyiu.pyscriptapps.com") {
41+
console.warn("Received message from unknown origin", e.origin);
42+
return;
43+
}
44+
if (data === "ready") {
45+
setIframeReady(true);
46+
return;
47+
}
48+
try {
49+
data = JSON.parse(data);
50+
setOutputCode(data.output_image_code);
51+
setOutputBuf(Buffer.from(data.output_preview_img, "base64"));
52+
setIframeReady(true);
53+
} catch (e) {
54+
console.warn(e);
55+
}
56+
}, []);
57+
58+
React.useEffect(() => {
59+
window.addEventListener("message", handleMessage);
60+
return () => {
61+
window.removeEventListener("message", handleMessage);
62+
};
63+
}, [handleMessage]);
64+
3365
return (
3466
<div style={{ overflowX: "hidden" }}>
3567
<form
3668
onSubmit={(e) => {
3769
e.preventDefault();
3870
console.log(
3971
// @ts-ignore
40-
`Converting image of size ${inputBuf?.byteLength / 1024} kb`,
72+
`Converting image of size ${Math.round(inputBuf?.byteLength / 1024)} kb`,
4173
);
42-
console.log(`Using options {${JSON.stringify(options)}}`);
74+
console.log(`Using options ${JSON.stringify(options)}`);
75+
76+
const iframe = getElement("worker-iframe") as HTMLIFrameElement;
77+
if (iframe.contentWindow) {
78+
setIframeReady(false);
79+
setOutputCode(null);
80+
setOutputBuf(null);
81+
setTimeout(() => {
82+
iframe.contentWindow!.postMessage(
83+
JSON.stringify({
84+
input_image: Buffer.from(inputBuf!).toString("base64"),
85+
input_options: JSON.stringify(options),
86+
}),
87+
"*",
88+
);
89+
console.log("Posted message to iframe");
90+
});
91+
} else {
92+
console.error("Failed to get worker iframe content window");
93+
}
4394
}}
4495
>
4596
<div>
@@ -274,7 +325,9 @@ export default function ImageImporterTool(): React.ReactNode {
274325
<button
275326
type="submit"
276327
className="btn btn-primary"
277-
disabled={inputBuf == null || inputBuf.byteLength == 0}
328+
disabled={
329+
inputBuf == null || inputBuf.byteLength == 0 || !iframeReady
330+
}
278331
>
279332
Convert
280333
</button>
@@ -288,6 +341,7 @@ export default function ImageImporterTool(): React.ReactNode {
288341
<textarea
289342
id="output-code"
290343
className="form-control"
344+
style={{ fontFamily: "monospace" }}
291345
placeholder="No image code generated yet."
292346
rows={10}
293347
readOnly
@@ -340,6 +394,33 @@ export default function ImageImporterTool(): React.ReactNode {
340394
</div>
341395
<br />
342396
</div>
397+
<div>
398+
<iframe
399+
src="https://ckyiu.pyscriptapps.com/image-to-makecode-arcade/latest/"
400+
sandbox="allow-scripts allow-same-origin"
401+
referrerPolicy="no-referrer"
402+
style={{ width: "50vw", height: "50vh" }}
403+
id="worker-iframe"
404+
/>
405+
<br />
406+
<button
407+
type="button"
408+
className="btn btn-danger"
409+
onClick={() => {
410+
const iframe = getElement("worker-iframe") as HTMLIFrameElement;
411+
const url = iframe.src;
412+
iframe.src = "";
413+
setTimeout(() => {
414+
iframe.src = url;
415+
}, 100);
416+
}}
417+
>
418+
reload iframe
419+
</button>
420+
<p>
421+
iframeReady: <code>{iframeReady.toString()}</code>
422+
</p>
423+
</div>
343424
</div>
344425
);
345426
}

src/components/BuiltInTools/ImagePreview.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ export default function ImagePreview({
3434
className="img-fluid"
3535
src={imageSrc}
3636
alt="Preview"
37-
style={{ maxWidth: "50vw", maxHeight: "50vh" }}
37+
style={{
38+
maxWidth: "50vw",
39+
maxHeight: "50vh",
40+
imageRendering: "pixelated",
41+
}}
3842
onLoad={(e) => {
3943
setImageDims({
4044
width: (e.target as HTMLImageElement).naturalWidth,

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2709,10 +2709,10 @@
27092709
dependencies:
27102710
undici-types "~5.26.4"
27112711

2712-
"@types/node@^21.6.1":
2713-
version "20.16.11"
2714-
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.11.tgz#9b544c3e716b1577ac12e70f9145193f32750b33"
2715-
integrity sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==
2712+
"@types/node@^20.16.11":
2713+
version "20.17.7"
2714+
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.7.tgz#790151a28c5a172773d95d53a0c23d3c59a883c4"
2715+
integrity sha512-sZXXnpBFMKbao30dUAvzKbdwA2JM1fwUtVEq/kxKuPI5mMwZiRElCpTXb0Biq/LMEVpXDZL5G5V0RPnxKeyaYg==
27162716
dependencies:
27172717
undici-types "~6.19.2"
27182718

0 commit comments

Comments
 (0)