<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Редактор Изображений</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            padding: 20px;
        }
        #controls {
            margin-bottom: 20px;
        }
        canvas {
            border: 1px solid #ccc;
            cursor: pointer;
        }
        label {
            display: block;
            margin-top: 10px;
        }
    </style>
</head>
<body>
    <h1>Редактор Изображений</h1>
    <div id="controls">
        <input type="file" id="upload" accept="image/*"><br><br>
        <label>
            Ширина (px):
            <input type="number" id="width" min="1" readonly>
        </label>
        <label>
            Высота (px):
            <input type="number" id="height" min="1">
        </label>
        <button id="rotate">Повернуть на 90°</button>
        <label>
            Дизеринг (%):
            <input type="range" id="dithering" min="0" max="100" value="0">
        </label>
        <label>
            Режим цвета:
            <select id="colorMode">
                <option value="bw">Черно-белое</option>
                <option value="bwr">Черно-бело-красное</option>
            </select>
        </label>
    </div>
    <canvas id="canvas"></canvas>

    <script>
        const upload = document.getElementById('upload');
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        const widthInput = document.getElementById('width');
        const heightInput = document.getElementById('height');
        const rotateButton = document.getElementById('rotate');
        const ditheringInput = document.getElementById('dithering');
        const colorModeSelect = document.getElementById('colorMode');

        let image = null;
        let originalAspectRatio = null;
        let degrees = 0;
        let showOriginal = false;

        upload.addEventListener('change', (event) => {
            const file = event.target.files[0];
            if (file) {
                const reader = new FileReader();
                reader.onload = (e) => {
                    image = new Image();
                    image.onload = () => {
                        originalAspectRatio = image.width / image.height;
                        widthInput.value = image.width;
                        heightInput.value = image.height;
                        drawImage();
                    }
                    image.src = e.target.result;
                };
                reader.readAsDataURL(file);
            }
        });

        heightInput.addEventListener('input', () => {
            if (originalAspectRatio) {
                widthInput.value = Math.round(heightInput.value * originalAspectRatio);
            }
            drawImage();
        });

        canvas.addEventListener('click', () => {
            showOriginal = !showOriginal;
            drawImage();
        });

        rotateButton.addEventListener('click', () => {
            degrees = (degrees + 90) % 360;
            drawImage();
        });

        ditheringInput.addEventListener('input', drawImage);
        colorModeSelect.addEventListener('change', drawImage);

        function drawImage() {
            if (!image) return;

            const width = parseInt(widthInput.value);
            const height = parseInt(heightInput.value);
            const ditheringLevel = parseInt(ditheringInput.value) / 100;

            const radians = degrees * Math.PI / 180;
            canvas.width = Math.abs(width * Math.cos(radians)) + Math.abs(height * Math.sin(radians));
            canvas.height = Math.abs(width * Math.sin(radians)) + Math.abs(height * Math.cos(radians));

            ctx.save();
            ctx.translate(canvas.width / 2, canvas.height / 2);
            ctx.rotate(radians);

            if (showOriginal) {
                ctx.drawImage(image, -width / 2, -height / 2, width, height);
            } else {
                ctx.drawImage(image, -width / 2, -height / 2, width, height);
                applyRandomDithering(ditheringLevel);
            }

            ctx.restore();
        }

        function applyRandomDithering(level) {
            const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
            const data = imageData.data;
            const colorMode = colorModeSelect.value;

            for (let i = 0; i < data.length; i += 4) {
                const grayscale = data[i] * 0.3 + data[i + 1] * 0.59 + data[i + 2] * 0.11;
                const randomThreshold = 128 + (Math.random() - 0.5) * 256 * level;
                
                data[i] = grayscale < randomThreshold ? 0 : 255;
                data[i + 1] = 0;
                data[i + 2] = grayscale < randomThreshold ? 0 : 255;

                if (colorMode === 'bwr' && grayscale >= randomThreshold) {
                    data[i] = 255; // set to red if above threshold
                    data[i + 2] = 0;
                }

                if (colorMode === 'bw' && grayscale >= randomThreshold) {
                    data[i + 1] = 255; // keeping green channel to identify white
                }
            }
            ctx.putImageData(imageData, 0, 0);
        }
    </script>
</body>
</html>