URI:
       version 4.0, add sharpness control - webgbcam - [fork] gameboy webcam
  HTML git clone git://src.adamsgaard.dk/webgbcam
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit d629f0888a8b575c083a15b41ab9eaca14aba2c1
   DIR parent 695f78c361445ce35a9e999d40d3912ef6f49165
  HTML Author: Erin Pinheiro <erin.manal@gmail.com>
       Date:   Wed, 24 May 2023 22:00:36 +0100
       
       version 4.0, add sharpness control
       
       Diffstat:
         M app.js                              |      69 +++++++++++++++++++++++++++++--
         M index.html                          |       4 ++--
         M style.css                           |       6 ++++++
         M sw.js                               |      20 ++++++++++----------
         M ui/ui-main.png                      |       0 
         M ui/ui-settings.png                  |       0 
       
       6 files changed, 83 insertions(+), 16 deletions(-)
       ---
   DIR diff --git a/app.js b/app.js
       @@ -268,6 +268,7 @@ var cameraVars = {
                dither: 0.6,
                contrast: 3,
                gamma: 3,
       +        sharpness: 3,
                xOffset: 0,
                yOffset: 0,
                xScale: 1,
       @@ -294,6 +295,16 @@ const sliderContrast = [
                2.4
        ];
        
       +const sliderSharpness = [
       +        0,
       +        0.50,
       +        0.75,
       +        1.00,
       +        1.25,
       +        2.00,
       +        3.00
       +];
       +
        // 8 x 8 Bayer Matrix
        const bayer8 = [
                [0,48,12,60,3,51,15,63],
       @@ -376,14 +387,17 @@ function loadPrefs() {
                let localContrast = parseInt(localStorage.getItem("cameraContrast"));
                let localGamma = parseInt(localStorage.getItem("cameraGamma"));
                let localPalette = parseInt(localStorage.getItem("cameraPalette"));
       +        let localSharpness = parseInt(localStorage.getItem("cameraSharpness"));
                cameraVars.contrast = (localContrast ? localContrast : 3);
                cameraVars.gamma = (localGamma ? localGamma : 3);
       +        cameraVars.sharpness = (localSharpness ? localSharpness : 3);
                currentPalette = (localPalette ? localPalette : 0);
        }
        
        function savePrefs() {
                localStorage.setItem("cameraContrast", cameraVars.contrast);
                localStorage.setItem("cameraGamma", cameraVars.gamma);
       +        localStorage.setItem("cameraSharpness", cameraVars.sharpness);
                localStorage.setItem("cameraPalette", currentPalette);
        }
        
       @@ -443,6 +457,18 @@ var buttons = {
                        width:15,
                        height:13
                },
       +        sharpnessLeft: {
       +                x:120,
       +                y:126,
       +                width:15,
       +                height:13
       +        },
       +        sharpnessRight: {
       +                x:135,
       +                y:126,
       +                width:15,
       +                height:13
       +        },
                screenHotspot: {
                        x:31,
                        y:31,
       @@ -456,13 +482,13 @@ var buttons = {
                        height:15
                },
                timer: {
       -                x:33,
       +                x:52,
                        y:131,
                        width:13,
                        height:13
                },
                record: {
       -                x:48,
       +                x:95,
                        y:131,
                        width:16,
                        height:13
       @@ -490,13 +516,38 @@ Filters.filterImage = function(filter, canvas, var_args) {
                canvas.getContext("2d").putImageData(idata, 0, 0);
        };
        
       +function xyToIndex(x, y, width) {
       +        return (x + y*width)*4;
       +}
       +
       +Filters.sharpen = function(pixels, sharpness) {
       +        if (sharpness == 0) return pixels;
       +        let d = pixels.data;
       +        let temp_buf = [];
       +
       +        for(i = 0; i < pixels.width; i++) for(j = 0; j < pixels.height; j++)
       +        {
       +                        let ms = d[xyToIndex(i, Math.min(j+1,pixels.height-1), pixels.width)];
       +                        let mn = d[xyToIndex(i, Math.max(0,j-1), pixels.width)];
       +                        let mw = d[xyToIndex(Math.max(0,i-1), j, pixels.width)];
       +                        let me = d[xyToIndex(Math.min(i+1,pixels.width-1), j, pixels.width)];
       +                        let px = d[xyToIndex(i, j, pixels.width)];
       +
       +                        temp_buf[xyToIndex(i, j, pixels.width)] = clampNumber(px+((4*px-mw-me-mn-ms)*sharpness), -128, 127);
       +        }
       +        for (let i = 0; i < d.length; i += 4) {
       +                d[i] = temp_buf[i];
       +        }
       +
       +        return pixels;
       +}
       +
        Filters.gbcamera = function(pixels, ditherFactor) {
                let d = pixels.data;
        
                for(let y = 0; y < pixels.height; y++) {
                        for(let x = 0; x < pixels.width; x++) {
       -                        let n = (x + y*pixels.width);
       -                        let i = n * 4;
       +                        let i = xyToIndex(x, y, pixels.width);
        
                                let bayer = bayer8[(y)%8][(x)%8];
        
       @@ -697,6 +748,12 @@ function initCameraUI() {
                                } else if(isInside(mousePos, buttons.brightnessRight)) {
                                        if(cameraVars.gamma < 6) cameraVars.gamma++;
                                        savePrefs();
       +                        } else if(isInside(mousePos, buttons.sharpnessLeft)) {
       +                                if(cameraVars.sharpness > 0) cameraVars.sharpness--;
       +                                savePrefs();
       +                        } else if(isInside(mousePos, buttons.sharpnessRight)) {
       +                                if(cameraVars.sharpness < 6) cameraVars.sharpness++;
       +                                savePrefs();
                                } else if(isInside(mousePos, buttons.paletteLeft)) {
                                        currentPalette--;
                                        if(currentPalette < 0) currentPalette = palettes.length-1;
       @@ -879,6 +936,7 @@ function drawFrame() {
                let camctx = cameraView.getContext('2d');
                camctx.drawImage(cameraStream, cameraVars.xOffset, cameraVars.yOffset, cameraVars.xScale, cameraVars.yScale, 0, 0, cameraVars.width, cameraVars.height);
                
       +        Filters.filterImage(Filters.sharpen, cameraView, [sliderSharpness[cameraVars.sharpness]]);
                Filters.filterImage(Filters.gbcamera, cameraView, [cameraVars.dither]);
                
                let ctx = appView.getContext("2d");
       @@ -894,6 +952,9 @@ function drawFrame() {
                        for(let i = 1; i <= cameraVars.gamma; i++) {
                                ctx.fillRect(97, 22 - (i*3), 4, 2);
                        }
       +                for(let i = 1; i <= cameraVars.sharpness; i++) {
       +                        ctx.fillRect(152, 135 - (i*3), 4, 2);
       +                }
                } else if (currentUI === uiRecord) {
                        // update record length
                        ctx.fillStyle = "rgb(64,64,64)";
   DIR diff --git a/index.html b/index.html
       @@ -15,7 +15,7 @@
        </head>
        <body>
                <div class="maple-window">
       -                <div class="maple-window-title"><span>webgbcam v3.5</span></div>
       +                <div class="maple-window-title"><span>webgbcam v4.0</span></div>
                        <div id="camera">
                                <canvas id="app-view"></canvas>
                                <canvas id="camera-view"></canvas>
       @@ -27,7 +27,7 @@
                <div class="maple-window centered">
                        <h2 class="blink">NFTs: No Fucking Thanks</h2>
        
       -                <p>made by <a href="https://twitter.com/maplesbian">@maplesbian</a> - inspired by christine love's interstellar selfie station</p>
       +                <p>made by <a href="https://maple.pet">maple</a> - inspired by christine love's interstellar selfie station</p>
        
                        <p>if the app above is blank, make sure you have cameras connected and browser camera permissions enabled!</p>
        
   DIR diff --git a/style.css b/style.css
       @@ -133,4 +133,10 @@ body {
                to {
                        visibility: hidden;
                }
       +}
       +
       +ul {
       +        margin-top: -1em;
       +        padding: 0;
       +        list-style: none;
        }
        \ No newline at end of file
   DIR diff --git a/sw.js b/sw.js
       @@ -1,4 +1,4 @@
       -const cacheName = 'webgbcam-v3.5'
       +const cacheName = 'webgbcam-v4.0'
        
        self.addEventListener('install', function(e) {
        e.waitUntil(
       @@ -8,15 +8,15 @@ e.waitUntil(
                                'index.html',
                                'style.css',
                                'app.js',
       -                        'bg.png',
       -                        'mac-frame.png',
       -                        'ui-capture.png',
       -                        'ui-settings.png',
       -                        'ui-main.png',
       -                        'ui-hidden.png',
       -                        'ui-timer.png',
       -                        'ui-record.png',
       -                        'loading.gif',
       +                        'ui/bg.png',
       +                        'ui/mac-frame.png',
       +                        'ui/ui-capture.png',
       +                        'ui/ui-settings.png',
       +                        'ui/ui-main.png',
       +                        'ui/ui-hidden.png',
       +                        'ui/ui-timer.png',
       +                        'ui/ui-record.png',
       +                        'ui/loading.gif',
                                'gifjs/gif.js',
                                'gifjs/gif.worker.js'
                        ]);
   DIR diff --git a/ui/ui-main.png b/ui/ui-main.png
       Binary files differ.
   DIR diff --git a/ui/ui-settings.png b/ui/ui-settings.png
       Binary files differ.