mirror of
https://github.com/gocivici/astrosketch.git
synced 2025-01-08 10:52:53 -06:00
first commit
This commit is contained in:
commit
8ab769575b
144
astrosketch.css
Normal file
144
astrosketch.css
Normal file
@ -0,0 +1,144 @@
|
||||
body{
|
||||
background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)), var(--theme-3);
|
||||
}
|
||||
canvas{
|
||||
width:100%;
|
||||
}
|
||||
|
||||
#outputWindow{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#img{
|
||||
display:none;
|
||||
}
|
||||
.astroContainer{
|
||||
|
||||
font-size:16px;
|
||||
text-align:center;
|
||||
align-items: center;
|
||||
|
||||
/* flex-wrap: wrap; */
|
||||
/* {# width: 100%; #} */
|
||||
}
|
||||
|
||||
.astroContainer hr{
|
||||
|
||||
border:0;
|
||||
height:20px;
|
||||
background:url("/images/divider.gif") 0 0;
|
||||
|
||||
}
|
||||
.astroFlex{
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
.astrotext{
|
||||
order:1;
|
||||
text-align: left;
|
||||
}
|
||||
.astroContainer figure{
|
||||
order:2;
|
||||
margin: auto;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.astroContainer label{
|
||||
font-size:16px;
|
||||
font-family:IBM;
|
||||
/* {# margin:10px; #} */
|
||||
}
|
||||
|
||||
.astroContainer button{
|
||||
width:auto;
|
||||
height:auto;
|
||||
font-size:20px;
|
||||
}
|
||||
.astroContainer form{
|
||||
font-size:16px;
|
||||
}
|
||||
.astroContainer input{
|
||||
font-size:10px;
|
||||
/* {# margin: 0 auto !important; #} */
|
||||
|
||||
}
|
||||
input::file-selector-button{
|
||||
font-size:18px;
|
||||
|
||||
}
|
||||
|
||||
.astroContainer input[type=checkbox]{
|
||||
/* {# margin:15px; #} */
|
||||
}
|
||||
|
||||
.centerButton {
|
||||
width:auto;
|
||||
text-align:center;
|
||||
margin: auto;
|
||||
justify-content:center;
|
||||
/* {# max-width:200px; #} */
|
||||
}
|
||||
#dl{
|
||||
display:none;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
margin: 15px;
|
||||
}
|
||||
#result{
|
||||
text-align:center;
|
||||
font-size:22px;
|
||||
display:none;
|
||||
}
|
||||
.settings{
|
||||
|
||||
font-size:16px !important;
|
||||
max-width:400px;
|
||||
text-align:center;
|
||||
margin:auto;
|
||||
}
|
||||
|
||||
.field-row{
|
||||
margin-top:20px;
|
||||
margin-bottom:20px;
|
||||
width: 100%;
|
||||
/* flex-wrap: wrap; */
|
||||
}
|
||||
|
||||
.flexwrap{
|
||||
display:flex;
|
||||
flex-wrap: wrap;
|
||||
width:auto;
|
||||
text-align:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.invert, .grayscale{
|
||||
display: flex;
|
||||
float:left;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.checkboxContainer{
|
||||
/* margin:10px; */
|
||||
margin-bottom: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
#submitButton{
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
|
||||
.invert, .grayscale{
|
||||
float:none;
|
||||
|
||||
}
|
||||
.checkboxContainer{
|
||||
margin: 0px;
|
||||
}
|
||||
.left-box{
|
||||
padding-right: 5px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
}
|
81
astrosketch.html
Normal file
81
astrosketch.html
Normal file
@ -0,0 +1,81 @@
|
||||
|
||||
|
||||
<link rel="stylesheet" href="astrosketch.css">
|
||||
|
||||
<form id="settings">
|
||||
<div class="field-row">
|
||||
<input class="centerButton" type="file" accept="image/*;capture=camera" name="image" id="file" onchange="loadFile(event)">
|
||||
|
||||
<div class="invert">
|
||||
<input checked disabled="true" type="checkbox" id="invertBox">
|
||||
<label for="invertBox">Invert</label>
|
||||
</div>
|
||||
|
||||
<div class="grayscale">
|
||||
<input checked disabled="true" type="checkbox" id="grayscaleBox">
|
||||
<label for="grayscaleBox">Grayscale</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="field-row">
|
||||
<label for="BrightnessSlider">Brightness:</label>
|
||||
<label for="BrightnessSlider" style="">L</label>
|
||||
<input id="BrightnessSlider" width="200px" type="range" value="-25" min="-100" max="100">
|
||||
<label for="BrightnessSlider">H</label>
|
||||
<label for="BrightnessSlider">(<span style="width:24px; color:orange;" id="BrightnessValue">-25</span>)</label>
|
||||
</div>
|
||||
<div class="field-row">
|
||||
<label for="ContrastSlider">Contrast: </label>
|
||||
<label for="ContrastSlider">L</label>
|
||||
|
||||
<input id="ContrastSlider" type="range" value="38" min="-100" max="100">
|
||||
<label for="ContrastSlider">H</label>
|
||||
<label for="ContrastSlider">(<span style="width:24px; color:orange;" id="ContrastValue">38</span>)</label>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<img id="img" />
|
||||
|
||||
</form>
|
||||
<button id="submitButton">Submit</button>
|
||||
|
||||
</main>
|
||||
|
||||
|
||||
<script type="text/javascript" src="astrosketch.js"></script>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p id="result">⬇️Converted Image⬇️</p>
|
||||
|
||||
|
||||
|
||||
<canvas id="myCanvas"></canvas>
|
||||
<a id="dl" download="Sketch.png" href="#">Download Result</a>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
102
astrosketch.js
Normal file
102
astrosketch.js
Normal file
@ -0,0 +1,102 @@
|
||||
brightnessSlider = document.getElementById("BrightnessSlider");
|
||||
brightnessValue = document.getElementById("BrightnessValue");
|
||||
contrastSlider = document.getElementById("ContrastSlider");
|
||||
contrastValue = document.getElementById("ContrastValue");
|
||||
|
||||
brightnessSlider.oninput = function () {
|
||||
brightnessValue.innerHTML = this.value;
|
||||
};
|
||||
|
||||
contrastSlider.oninput = function () {
|
||||
contrastValue.innerHTML = this.value;
|
||||
};
|
||||
|
||||
//console.log(contrastSlider.value);
|
||||
|
||||
document.getElementById("submitButton").disabled = true;
|
||||
|
||||
submitButton = document.getElementById("submitButton");
|
||||
|
||||
let loadFile = function (event) {
|
||||
let image = document.getElementById("img");
|
||||
image.crossOrigin = "anonymous";
|
||||
image.src = URL.createObjectURL(event.target.files[0]);
|
||||
document.getElementById("submitButton").disabled = false;
|
||||
};
|
||||
|
||||
submitButton.addEventListener("click", function () {
|
||||
var brightness = parseInt(brightnessSlider.value, 10);
|
||||
var contrast = parseInt(contrastSlider.value, 10);
|
||||
|
||||
uploadedImage = document.getElementById("img");
|
||||
let canvas = document.getElementById("myCanvas");
|
||||
let context = canvas.getContext("2d");
|
||||
canvas.width = uploadedImage.width;
|
||||
canvas.height = uploadedImage.height;
|
||||
context.drawImage(uploadedImage, 0, 0);
|
||||
let imageData = context.getImageData(0, 0, canvas.width, canvas.height);
|
||||
let data = imageData.data;
|
||||
|
||||
//Grayscale image
|
||||
for (let i = 0; i < data.length; i += 4) {
|
||||
const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
|
||||
data[i] = avg; // red
|
||||
data[i + 1] = avg; // green
|
||||
data[i + 2] = avg; // blue
|
||||
}
|
||||
|
||||
//Invert image
|
||||
for (var i = 0; i < data.length; i += 4) {
|
||||
data[i] = 255 - data[i]; // red
|
||||
data[i + 1] = 255 - data[i + 1]; // green
|
||||
data[i + 2] = 255 - data[i + 2]; // blue
|
||||
}
|
||||
|
||||
applyBrightness(imageData.data, brightness);
|
||||
contrastImage(imageData.data, contrast);
|
||||
|
||||
context.putImageData(imageData, 0, 0);
|
||||
|
||||
//Thanks Nippey from: https://stackoverflow.com/questions/12796513/html5-canvas-to-png-file
|
||||
function dlCanvas() {
|
||||
var dt = canvas.toDataURL("image/png");
|
||||
/* Change MIME type to trick the browser to downlaod the file instead of displaying it */
|
||||
dt = dt.replace(/^data:image\/[^;]*/, "data:application/octet-stream");
|
||||
|
||||
/* In addition to <a>'s "download" attribute, you can define HTTP-style headers */
|
||||
dt = dt.replace(
|
||||
/^data:application\/octet-stream/,
|
||||
"data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=Sketch.png"
|
||||
);
|
||||
|
||||
this.href = dt;
|
||||
}
|
||||
|
||||
document.getElementById("dl").addEventListener("click", dlCanvas, false);
|
||||
document.getElementById("outputWindow").style.display = "block";
|
||||
document.getElementById("result").style.display = "block";
|
||||
document.getElementById("dl").style.display = "block";
|
||||
window.scrollTo(0, document.body.scrollHeight);
|
||||
|
||||
});
|
||||
|
||||
function applyBrightness(data, brightness) {
|
||||
for (var i = 0; i < data.length; i += 4) {
|
||||
data[i] += 255 * (brightness / 100);
|
||||
data[i + 1] += 255 * (brightness / 100);
|
||||
data[i + 2] += 255 * (brightness / 100);
|
||||
}
|
||||
}
|
||||
|
||||
function contrastImage(d, contrast) {
|
||||
contrast = contrast / 100 + 1;
|
||||
var intercept = 128 * (1 - contrast);
|
||||
for (var i = 0; i < d.length; i += 4) {
|
||||
//r,g,b,a
|
||||
d[i] = d[i] * contrast + intercept;
|
||||
d[i + 1] = d[i + 1] * contrast + intercept;
|
||||
d[i + 2] = d[i + 2] * contrast + intercept;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user