uploadImagemain.tsx6 matches
1/**
2* upload an image to val.town
3* @param {Blob} image - image must have image/jpeg, image/png, image/webp, image/gif or image/svg+xml content-type
4* @returns {string} - uploaded image url
5*/
6export async function uploadImage(image: Blob): Promise<string> {
7const fd = new FormData();
8fd.append(
9"file",
10image,
11);
12const data = await (await fetch(await getUploadURL(), {
24}
25async function getUploadURL(): Promise<string> {
26const data = await (await fetch("https://www.val.town/api/trpc/generateImageUploadUrl", {
27"headers": {
28"content-type": "application/json",
asciiNycCamerasmain.tsx11 matches
34import valTownBadge from "https://esm.town/v/jxnblk/valTownBadge?v=16";
5import { imageToAscii } from "https://esm.town/v/maxm/imageToAscii";
6import { extractValInfo } from "https://esm.town/v/pomdtr/extractValInfo";
7import { Hono } from "npm:hono@3";
35document.getElementById("message").style.display = "none";
36document.getElementById("close-btn").style.display = "flex";
37await fetchImage(id);
38};
39152<p>
153Click on a circle to select a traffic camera. <br />{" "}
154The traffic images will be converted to ASCII and streamed to your browser.
155<br /> <a className="underline" href={info.htmlUrl}>Source code & info</a>.
156</p>
196);
197app.get("/camera-ascii/:id", async (c) => {
198const url = "https://webcams.nyctmc.org/api/cameras/" + c.req.param("id") + "/image";
199const { stringColor } = await imageToAscii(url, 150);
200return new Response(stringColor, { headers: { "Content-Type": "text/plain" } });
201});
203"/camera/:id",
204async (c) => {
205const url = "https://webcams.nyctmc.org/api/cameras/" + c.req.param("id") + "/image";
206const { string, stringColor } = await imageToAscii(url, 150);
207return new Response(
208`<style>
228<p class="loading"></p>
229<p>
230<a target="_blank" href="${url}">view source image</a>
231</p>
232<script>
258app.get("/camera-text-stream/:id", async (c) => {
259let timerId: number | undefined;
260const url = "https://webcams.nyctmc.org/api/cameras/" + c.req.param("id") + "/image";
261const body = new ReadableStream({
262async start(controller) {
264controller.enqueue(new TextEncoder().encode("data: " + JSON.stringify(msg) + "\r\n\r\n"));
265};
266const { stringColor } = await imageToAscii(url, 150);
267write(stringColor);
268timerId = setInterval(async () => {
269const { stringColor } = await imageToAscii(url, 150);
270write(stringColor);
271}, 2000);
asciiImageExamplemain.tsx3 matches
1import { imageToAscii } from "https://esm.town/v/maxm/imageToAscii";
23export default async function(req: Request): Promise<Response> {
4const { string, stringColor } = await imageToAscii(
5"https://webcams.nyctmc.org/api/cameras/9fa5b0dd-e955-449e-97e1-9c53ad9c23a8/image",
6150,
7);
imageToAsciimain.tsx11 matches
2526// Converted from: https://github.com/victorqribeiro/imgToAscii/blob/ca7e181b9bb9770798ed3a0d3dfeb344c60953f2/src/imgToAscii.js
27import { createCanvas, loadImage } from "https://deno.land/x/canvas@v1.4.1/mod.ts";
28export async function imageToAscii(src: string, maxWidth?: number) {
29let string = "";
30let stringColor = "";
38"`","'","."," "]
39}
40const image = await loadImage(src);
41let width = image.width();
42const scale = maxWidth ? maxWidth / width : 1;
43const height = Math.floor(image.height() * scale * 0.6);
44width = Math.floor(width * scale);
45const canvas = createCanvas(width, height);
46const context = canvas.getContext("2d");
47context.drawImage(image, 0, 0, canvas.width, canvas.height);
48const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
49let grayStep = Math.ceil(255 / alphabet[charType].length);
50for (let i = 0; i < imageData.data.length; i += 4) {
51for (let j = 0; j < alphabet[charType].length; j++) {
52let r = imageData.data[i];
53let g = imageData.data[i + 1];
54let b = imageData.data[i + 2];
55if ((r * 0.2126) + (g * 0.7152) + (b * 0.0722) < (j + 1) * grayStep) {
56const char = alphabet[charType][j];
asciiNycCamerasREADME.md3 matches
1# ASCII NYC Traffic Cameras
23All of NYC's traffic cameras available as streaming ASCII images: https://maxm-asciinyccameras.web.val.run/
45<p align=center>
6<a href="https://maxm-asciinyccameras.web.val.run/">
7<!-- <img width=700 src="https://imagedelivery.net/iHX6Ovru0O7AjmyT5yZRoA/9c4e7e22-ae90-420e-4238-df0013d2a300/public"> -->
8<img width=700 src="https://i.imgur.com/83LBOcN.gif">
9</a>
121314NYC has a bunch of traffic cameras and makes them available through static images [like this one](https://webcams.nyctmc.org/api/cameras/858ef4e8-5058-4db2-96e2-70f71b65aa24/image). If you refresh the page you'll see the image update every 2 seconds or so. I thought it might be fun to make these cameras viewable as an ASCII art video feed. I made a [small library](https://www.val.town/v/maxm/imageToAscii) that takes most of its logic from [this repo](https://github.com/victorqribeiro/imgToAscii). You can see a basic example of how to convert [any image to ASCII here](https://www.val.town/v/maxm/asciiImageExample).
1516I pull in [NYC GeoJSON from here](https://observablehq.com/@miaozhang/maps) and then hook up a Server-Sent Events endpoint to stream the ASCII updates to the browser. (Polling would work just as well, I've just been on a bit of a SSE kick lately.)
asciiImageExampleREADME.md1 match
1null
23Migrated from folder: asciiNyc/asciiImageExample
106Your description should include:
107- What content is on the page
108- Other elements like sidebars, links, images that may be in the page
109- The author and origin of the page
110- The stylistic aesthetic of the page
143- A footer with author information.
144- Some reasonable links in the body text.
145- An image. You can create an image by using the following markup:
146<img src="https://maxm-imggenurl.web.val.run/{your image alt text}" height={image height} />
147- Specific, concrete information only. NEVER use placeholders or other generic text.
148`,
3Move circles around. State is synced with the server. Open a window in another tab and watch the circles update as you move them .
45
6
endlessMazeStreamREADME.md1 match
12
3
multiplayerCirclesREADME.md1 match
3Move circles around. State is synced with the server. Open a window in another tab and watch the circles update as you move them .
45
6