summary refs log tree commit diff stats
path: root/commands/compose/edit.go
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2019-06-02 15:22:48 -0400
committerDrew DeVault <sir@cmpwn.com>2019-06-02 15:22:48 -0400
commitd1ea18113533ae14818411725a692ffe4672e490 (patch)
treeecb22e0433e28656cd66218fe275523bc84e15e2 /commands/compose/edit.go
parent92b10fcef561074208b725e79c71c9a60e52b6b6 (diff)
downloadaerc-d1ea18113533ae14818411725a692ffe4672e490.tar.gz
hldiff.py: don't highlight -/+ in filenames
Diffstat (limited to 'commands/compose/edit.go')
0 files changed, 0 insertions, 0 deletions
nt.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
const upload = document.getElementById('upload');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

upload.addEventListener('change', function (e) {
    const file = e.target.files[0];
    const reader = new FileReader();
    reader.onload = function (event) {
        const img = new Image();
        img.onload = function () {
            canvas.width = img.width;
            canvas.height = img.height;
            ctx.drawImage(img, 0, 0);
            applyDithering();
        };
        img.src = event.target.result;
    };
    reader.readAsDataURL(file);
});

// TIL how to do this!
document.getElementById('download').addEventListener('click', function() {
    const dataUrl = canvas.toDataURL('image/png'); // Convert the canvas to a data URL
    const a = document.createElement('a'); // Create an anchor element
    a.href = dataUrl; // Set the href of the anchor to the data URL
    a.download = 'dithered-image.png'; // Set the download attribute to the desired file name
    a.setAttribute('rel', 'noopener noreferrer');
    a.setAttribute('target', '_blank');
    document.body.appendChild(a); // Append the anchor to the body
    a.click(); // Trigger a click on the anchor to start the download
    document.body.removeChild(a); // Remove the anchor from the body
});

function applyDithering() {
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const data = imageData.data;
    const width = canvas.width;
    const height = canvas.height;

    // Find the gray value of a pixel
    const getGrayValue = (r, g, b) => 0.299 * r + 0.587 * g + 0.114 * b;

    // Set the pixel value
    const setPixel = (x, y, value) => {
        const index = (y * width + x) * 4;
        const gray = value < 128 ? 0 : 255;
        data[index] = gray;
        data[index + 1] = gray;
        data[index + 2] = gray;
        data[index + 3] = 255;
    };

    // https://en.wikipedia.org/wiki/Floyd–Steinberg_dithering

    // Loop through each pixel in the image
    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const index = (y * width + x) * 4;
            const oldR = data[index];
            const oldG = data[index + 1];
            const oldB = data[index + 2];
            const oldGray = getGrayValue(oldR, oldG, oldB);
            const newGray = oldGray < 128 ? 0 : 255;
            const error = oldGray - newGray;

            setPixel(x, y, oldGray);

            // Spread error to neighboring pixels
            if (x + 1 < width) {
                data[(y * width + x + 1) * 4] += error * 7 / 16;
                data[(y * width + x + 1) * 4 + 1] += error * 7 / 16;
                data[(y * width + x + 1) * 4 + 2] += error * 7 / 16;
            }
            if (y + 1 < height) {
                if (x - 1 >= 0) {
                    data[((y + 1) * width + x - 1) * 4] += error * 3 / 16;
                    data[((y + 1) * width + x - 1) * 4 + 1] += error * 3 / 16;
                    data[((y + 1) * width + x - 1) * 4 + 2] += error * 3 / 16;
                }
                data[((y + 1) * width + x) * 4] += error * 5 / 16;
                data[((y + 1) * width + x) * 4 + 1] += error * 5 / 16;
                data[((y + 1) * width + x) * 4 + 2] += error * 5 / 16;
                if (x + 1 < width) {
                    data[((y + 1) * width + x + 1) * 4] += error * 1 / 16;
                    data[((y + 1) * width + x + 1) * 4 + 1] += error * 1 / 16;
                    data[((y + 1) * width + x + 1) * 4 + 2] += error * 1 / 16;
                }
            }
        }
    }

    ctx.putImageData(imageData, 0, 0);
}