mirror of
https://github.com/javl/image2cpp.git
synced 2026-09-11 17:13:20 +00:00
Add option to view preview image in separate tab
This commit is contained in:
+8
-3
@@ -796,13 +796,18 @@ input[type="file"]::file-selector-button {
|
|||||||
/* background: var(--primary-container); */
|
/* background: var(--primary-container); */
|
||||||
margin: var(--space-2) var(--space-4) var(--space-2) 0;
|
margin: var(--space-2) var(--space-4) var(--space-2) 0;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
/* Display width/height/aspect-ratio are set in JS (setCanvasDisplaySize)
|
cursor: pointer;
|
||||||
so small glyphs get enlarged without distorting their aspect ratio;
|
/* Display width/height are set in JS (setCanvasDisplaySize), capped to
|
||||||
independent min-width/min-height here would stretch non-square canvases. */
|
128px on the largest side while preserving aspect ratio, and never
|
||||||
|
scaled up beyond the canvas' actual pixel size. */
|
||||||
image-rendering: crisp-edges;
|
image-rendering: crisp-edges;
|
||||||
image-rendering: pixelated;
|
image-rendering: pixelated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#preview-note {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.inlineImg {
|
.inlineImg {
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
margin-top: var(--space-2);
|
margin-top: var(--space-2);
|
||||||
|
|||||||
+2
-1
@@ -59,6 +59,7 @@
|
|||||||
<h2>1. Select image</h2>
|
<h2>1. Select image</h2>
|
||||||
<div class="note upload-note">You can import multiple images at once.<br>All processing is done locally in your browser: your images are not uploaded or stored anywhere online.</div>
|
<div class="note upload-note">You can import multiple images at once.<br>All processing is done locally in your browser: your images are not uploaded or stored anywhere online.</div>
|
||||||
<input type="file" id="file-input" name="file-input" multiple/><br />
|
<input type="file" id="file-input" name="file-input" multiple/><br />
|
||||||
|
<div id="only-images-file-error" class="msg error-msg">Only images file type are allowed</div>
|
||||||
<div id="file-input-column-items"></div>
|
<div id="file-input-column-items"></div>
|
||||||
<template id="file-input-entry-template">
|
<template id="file-input-entry-template">
|
||||||
<div class="file-input-entry">
|
<div class="file-input-entry">
|
||||||
@@ -122,7 +123,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
<div id="only-images-file-error" class="msg error-msg">Only images file type are allowed</div>
|
|
||||||
<div class="no-file-selected msg">Select one or more images at <a href="#step-1">step 1</a> first.</div>
|
<div class="no-file-selected msg">Select one or more images at <a href="#step-1">step 1</a> first.</div>
|
||||||
<button id="all-same-size" onclick="allSameSize()">Apply first image size to all images</button>
|
<button id="all-same-size" onclick="allSameSize()">Apply first image size to all images</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -230,6 +230,7 @@
|
|||||||
<section class="section step bottom-divider" id="step-3">
|
<section class="section step bottom-divider" id="step-3">
|
||||||
<!-- <div class="step-num">3</div> -->
|
<!-- <div class="step-num">3</div> -->
|
||||||
<h2>Preview</h2>
|
<h2>Preview</h2>
|
||||||
|
<div id="preview-note" class="note">Click image to view at actual size</div>
|
||||||
<section class="sub-section">
|
<section class="sub-section">
|
||||||
<div class="no-file-selected msg">No files selected</div>
|
<div class="no-file-selected msg">No files selected</div>
|
||||||
<div id="images-canvas-container"></div>
|
<div id="images-canvas-container"></div>
|
||||||
|
|||||||
+41
-21
@@ -260,17 +260,32 @@ function invert(canvas, ctx) {
|
|||||||
ctx.putImageData(imageData, 0, 0);
|
ctx.putImageData(imageData, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size the on-screen canvas so tiny glyphs stay legible without distorting
|
// Open the canvas' current contents as a full-size image in a new tab,
|
||||||
// their aspect ratio (independent min-width/min-height would stretch them).
|
// like a right-click "open image in new tab" on a regular <img>.
|
||||||
|
function openCanvasInNewTab(canvas) {
|
||||||
|
canvas.toBlob((blob) => {
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
window.open(url, '_blank');
|
||||||
|
// Give the new tab time to load the image before freeing the blob.
|
||||||
|
setTimeout(() => URL.revokeObjectURL(url), 30000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size the on-screen canvas, preserving aspect ratio: shown at its actual
|
||||||
|
// pixel size up to 128px on its largest side, scaled down to fit within
|
||||||
|
// 128px otherwise. Never scaled up. Wires up click-to-open-in-new-tab
|
||||||
|
// (the "click to open at actual size" hint lives once in the Preview
|
||||||
|
// header, not per canvas).
|
||||||
function setCanvasDisplaySize(canvas) {
|
function setCanvasDisplaySize(canvas) {
|
||||||
const minVisibleSize = 96;
|
const maxPreviewSize = 128;
|
||||||
const scale = Math.max(1, minVisibleSize / Math.min(canvas.width, canvas.height));
|
const largestSide = Math.max(canvas.width, canvas.height);
|
||||||
// eslint-disable-next-line no-param-reassign
|
const scale = largestSide > maxPreviewSize ? maxPreviewSize / largestSide : 1;
|
||||||
canvas.style.aspectRatio = `${canvas.width} / ${canvas.height}`;
|
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
canvas.style.width = `${Math.round(canvas.width * scale)}px`;
|
canvas.style.width = `${Math.round(canvas.width * scale)}px`;
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
canvas.style.height = 'auto';
|
canvas.style.height = `${Math.round(canvas.height * scale)}px`;
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
canvas.onclick = () => openCanvasInNewTab(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the image onto the canvas, taking into account color and scaling
|
// Draw the image onto the canvas, taking into account color and scaling
|
||||||
@@ -655,9 +670,11 @@ function setTextInputSize(width, height) {
|
|||||||
function checkImagesAvailable() {
|
function checkImagesAvailable() {
|
||||||
const error = document.getElementById('no-images-error');
|
const error = document.getElementById('no-images-error');
|
||||||
const glyphNameNote = document.getElementById('glyph-name-note');
|
const glyphNameNote = document.getElementById('glyph-name-note');
|
||||||
|
const previewNote = document.getElementById('preview-note');
|
||||||
const hasImages = images.length() > 0;
|
const hasImages = images.length() > 0;
|
||||||
error.style.display = hasImages ? 'none' : 'block';
|
error.style.display = hasImages ? 'none' : 'block';
|
||||||
glyphNameNote.style.display = hasImages ? 'block' : 'none';
|
glyphNameNote.style.display = hasImages ? 'block' : 'none';
|
||||||
|
previewNote.style.display = hasImages ? 'block' : 'none';
|
||||||
return hasImages;
|
return hasImages;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,6 +729,7 @@ function handleTextInput(drawMode) {
|
|||||||
: listToImageVertical(list, canvas);
|
: listToImageVertical(list, canvas);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
setCanvasDisplaySize(canvas);
|
||||||
document.getElementById('text-input-error').style.display = 'none';
|
document.getElementById('text-input-error').style.display = 'none';
|
||||||
document.querySelectorAll('.no-file-selected').forEach((el) => {
|
document.querySelectorAll('.no-file-selected').forEach((el) => {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
@@ -927,32 +945,34 @@ function wrapFullExample(arrayCode, varName, width, height) {
|
|||||||
#include <Adafruit_GFX.h>
|
#include <Adafruit_GFX.h>
|
||||||
#include <Adafruit_SSD1306.h>
|
#include <Adafruit_SSD1306.h>
|
||||||
|
|
||||||
#define OLED_RESET 4
|
#define SCREEN_WIDTH 128
|
||||||
Adafruit_SSD1306 display(OLED_RESET);
|
#define SCREEN_HEIGHT 64
|
||||||
|
|
||||||
#if (SSD1306_LCDHEIGHT != ${settings.screenHeight})
|
// Initialize display with standard I2C reset pin config (-1)
|
||||||
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
|
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
|
||||||
#endif
|
|
||||||
|
|
||||||
${arrayCode}
|
${arrayCode}
|
||||||
void setup() {
|
void setup() {
|
||||||
// initialize with the I2C addr 0x3D for the 128x64
|
Serial.begin(9600);
|
||||||
// replace with 0x3C for the 128x32
|
|
||||||
display.begin(SSD1306_SWITCHCAPVCC, 0x3D);
|
// Initialize with I2C address 0x3C. You might have to change this to 0x3D for your display.
|
||||||
|
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
|
||||||
|
Serial.println(F("SSD1306 allocation failed. Check your wiring or I2C address!"));
|
||||||
|
for(;;);
|
||||||
|
}
|
||||||
|
|
||||||
display.clearDisplay(); // Make sure the display is cleared
|
display.clearDisplay(); // Make sure the display is cleared
|
||||||
// Draw the bitmap:
|
|
||||||
// drawBitmap(x position, y position, bitmap data, bitmap width, bitmap height, color)
|
|
||||||
display.drawBitmap(0, 0, ${varName}, ${width}, ${height}, WHITE);
|
|
||||||
|
|
||||||
// Update the display
|
// drawBitmap(x_coordinate, y_coordinate, array_name, width, height, color)
|
||||||
|
display.drawBitmap(0, 0, ${varName}, ${width}, ${height}, SSD1306_WHITE);
|
||||||
|
|
||||||
|
// Push the memory buffer out to the physical display
|
||||||
display.display();
|
display.display();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|
||||||
}
|
}`;
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removes the trailing separator comma left after the last byte value.
|
// Removes the trailing separator comma left after the last byte value.
|
||||||
|
|||||||
Reference in New Issue
Block a user