Add image segment
This commit is contained in:
parent
afe9b3c869
commit
99eb75f758
4 changed files with 87 additions and 34 deletions
|
|
@ -6,9 +6,10 @@ import CSegmentText from "./CSegmentText.vue";
|
||||||
import CSegmentTictactoe from "./CSegmentTictactoe.vue";
|
import CSegmentTictactoe from "./CSegmentTictactoe.vue";
|
||||||
import CSegmentCells from "./CSegmentCells.vue";
|
import CSegmentCells from "./CSegmentCells.vue";
|
||||||
import CSegmentChat from "./CSegmentChat.vue";
|
import CSegmentChat from "./CSegmentChat.vue";
|
||||||
|
import CSegmentImage from "./CSegmentImage.vue";
|
||||||
|
|
||||||
const mode = ref<
|
const mode = ref<
|
||||||
"calendar" | "chat" | "cells" | "egg" | "text" | "tictactoe"
|
"calendar" | "chat" | "cells" | "egg" | "image" | "text" | "tictactoe"
|
||||||
>();
|
>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -19,6 +20,7 @@ const mode = ref<
|
||||||
<CSegmentChat v-if="mode === 'chat'" />
|
<CSegmentChat v-if="mode === 'chat'" />
|
||||||
<CSegmentCells v-if="mode === 'cells'" />
|
<CSegmentCells v-if="mode === 'cells'" />
|
||||||
<CSegmentEgg v-if="mode === 'egg'" />
|
<CSegmentEgg v-if="mode === 'egg'" />
|
||||||
|
<CSegmentImage v-if="mode === 'image'" />
|
||||||
<CSegmentText v-if="mode === 'text'" />
|
<CSegmentText v-if="mode === 'text'" />
|
||||||
<CSegmentTictactoe v-if="mode === 'tictactoe'" />
|
<CSegmentTictactoe v-if="mode === 'tictactoe'" />
|
||||||
<hr v-if="mode !== undefined" />
|
<hr v-if="mode !== undefined" />
|
||||||
|
|
@ -29,6 +31,7 @@ const mode = ref<
|
||||||
<button @click="mode = 'cells'">Cellular Automaton</button>
|
<button @click="mode = 'cells'">Cellular Automaton</button>
|
||||||
<button @click="mode = 'chat'">Chat Message</button>
|
<button @click="mode = 'chat'">Chat Message</button>
|
||||||
<button @click="mode = 'egg'">Easter Egg</button>
|
<button @click="mode = 'egg'">Easter Egg</button>
|
||||||
|
<button @click="mode = 'image'">Image</button>
|
||||||
<button @click="mode = 'text'">Text</button>
|
<button @click="mode = 'text'">Text</button>
|
||||||
<button @click="mode = 'tictactoe'">Tic Tac Toe</button>
|
<button @click="mode = 'tictactoe'">Tic Tac Toe</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
81
showbits-thermal-printer-ui/src/components/CSegmentImage.vue
Normal file
81
showbits-thermal-printer-ui/src/components/CSegmentImage.vue
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useApiRequest } from "@/apiRequest";
|
||||||
|
import { ref, useTemplateRef } from "vue";
|
||||||
|
import CSegmentError from "./CSegmentError.vue";
|
||||||
|
|
||||||
|
const { disabled, error, makeRequest } = useApiRequest();
|
||||||
|
const image = useTemplateRef<HTMLInputElement>("image");
|
||||||
|
|
||||||
|
const title = ref("");
|
||||||
|
const caption = ref("");
|
||||||
|
const algo = ref("stucki");
|
||||||
|
const bright = ref(true);
|
||||||
|
const seamless = ref(false);
|
||||||
|
const feed = ref(true);
|
||||||
|
|
||||||
|
function submit() {
|
||||||
|
const data = new FormData();
|
||||||
|
|
||||||
|
const file = image.value?.files?.[0];
|
||||||
|
if (file !== undefined) data.append("image", file);
|
||||||
|
|
||||||
|
if (title.value) data.append("title", title.value);
|
||||||
|
if (caption.value) data.append("caption", caption.value);
|
||||||
|
data.append("algo", algo.value);
|
||||||
|
data.append("bright", String(bright.value));
|
||||||
|
data.append("seamless", String(seamless.value));
|
||||||
|
data.append("feed", String(feed.value));
|
||||||
|
void makeRequest("/api/image", data);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<form @submit.prevent="submit">
|
||||||
|
<h2>Image</h2>
|
||||||
|
|
||||||
|
<input ref="image" type="file" accept="image/*" required :disabled />
|
||||||
|
|
||||||
|
<label class="wide">
|
||||||
|
Title:
|
||||||
|
<input v-model="title" type="text" placeholder="none" :disabled />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="wide">
|
||||||
|
Caption:
|
||||||
|
<input v-model="caption" type="text" placeholder="none" :disabled />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="wide">
|
||||||
|
Algorithm:
|
||||||
|
<select v-model="algo" :disabled>
|
||||||
|
<option value="stucki">Stucki</option>
|
||||||
|
<option value="floyd-steinberg">Floyd-Steinberg</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="wide">
|
||||||
|
<label><input v-model="bright" type="checkbox" :disabled /> Bright</label>
|
||||||
|
<label>
|
||||||
|
<input v-model="seamless" type="checkbox" :disabled />
|
||||||
|
Seamless
|
||||||
|
</label>
|
||||||
|
<label><input v-model="feed" type="checkbox" :disabled /> Feed</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button :disabled>Print</button>
|
||||||
|
<CSegmentError :message="error" />
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wide {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -4,7 +4,7 @@ use anyhow::Context;
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Multipart, State},
|
extract::{Multipart, State},
|
||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
response::{IntoResponse, Redirect, Response},
|
response::{IntoResponse, Response},
|
||||||
};
|
};
|
||||||
use image::ImageFormat;
|
use image::ImageFormat;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
@ -77,5 +77,5 @@ pub async fn post(server: State<Server>, mut multipart: Multipart) -> somehow::R
|
||||||
.with_main_file(include_str!("main.typ"));
|
.with_main_file(include_str!("main.typ"));
|
||||||
|
|
||||||
server.print_typst(typst).await;
|
server.print_typst(typst).await;
|
||||||
Ok(Redirect::to("image").into_response())
|
Ok(().into_response())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<title>TP: Image</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Upload an image</h1>
|
|
||||||
<form method="post" enctype="multipart/form-data">
|
|
||||||
<ol>
|
|
||||||
<li><input type="file" name="image" /></li>
|
|
||||||
<li>
|
|
||||||
<label><input type="checkbox" name="bright" checked /> Bright</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Dithering algorithm:
|
|
||||||
<select name="algo">
|
|
||||||
<option value="floyd-steinberg">Floyd-Steinberg</option>
|
|
||||||
<option value="stucki">Stucki</option>
|
|
||||||
</select>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Scale:
|
|
||||||
<input name="scale" type="number" min="1" max="8" value="1" />
|
|
||||||
</li>
|
|
||||||
<li><button>Print!</button></li>
|
|
||||||
</ol>
|
|
||||||
</form>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue