Advertisement
Thunder-Menu

PakPixel.html

Aug 20th, 2023
968
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 21.78 KB | Source Code | 0 0
  1. <!DOCTYPE html>
  2. <html lang="fr">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>Compression et Compressor de Fichiers</title>
  7.     <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
  8. </head>
  9. <body>
  10.     <select id="operationSelect">
  11.         <option value="pakobest" selected>best compressor</option>
  12.         <option value="compress">Compresser</option>
  13.         <option value="encode">Encodage</option>
  14.         <option value="decode">Décodage</option>
  15.     </select>
  16.  
  17.     <div id="compressSection" style="display: none;">
  18.         <h2>Compression de Fichiers</h2>
  19.         <input type="file" id="fileInput" multiple>
  20.         <br>
  21.         <button id="compressButton" disabled>Compresser et Enregistrer</button>
  22.     </div>
  23.  
  24.     <div id="encodeSection" style="display: none;">
  25.         <h2>Générateur de Motif de Carrés - Encodage</h2>
  26.         <input type="file" id="encodeFileInput" style="display: none;">
  27.         <br>
  28.         <button id="loadButton">Sélectionner un fichier</button>
  29.         <br>
  30.         <button id="generateButton" disabled>Générer</button>
  31.         <br>
  32.  
  33.     <label>
  34.         <input type="checkbox" id="colorTextCheckbox"> Inclure un texte coloré
  35.     </label>
  36.     <br>
  37.     <!-- Options pour le texte coloré -->
  38.     <div id="colorTextOptions" style="display: none;">
  39.     <textarea id="colorTextBox" rows="4" cols="50"></textarea> <!-- Champ de texte pour le texte coloré -->
  40.     <br>
  41.     <label for="textSize">Taille du texte :</label>
  42.     <input type="number" id="textSize" value="80">
  43.     <br>
  44.     <label for="verticalPosition">Position verticale :</label>
  45.     <select id="verticalPosition">
  46.         <option value="up">Haut</option>
  47.         <option value="down">Bas</option>
  48.         <option value="center">Centre</option>
  49.     </select>
  50.     <br>
  51.     <label for="horizontalPosition">Position horizontale :</label>
  52.     <select id="horizontalPosition">
  53.         <option value="left">Gauche</option>
  54.         <option value="right">Droite</option>
  55.         <option value="center">Centre</option>
  56.     </select>
  57.     <br>
  58.     <button id="addColorTextButton">Ajouter le texte coloré</button>
  59.     <br>
  60.     <input type="color" id="colorPicker" value="#FF0000">
  61.     </div>
  62.    
  63.       <br>
  64.         <button id="saveButton" disabled>Enregistrer le motif</button>
  65.         <br>
  66.         <textarea id="textBox" rows="10" cols="50"></textarea>
  67.         <br>
  68.         <div id="encodePictureBox"></div>
  69.     </div>
  70.  
  71.     <div id="decodeSection" style="display: none;">
  72.         <h2>Générateur de Motif de Carrés - Décodage</h2>
  73.         <input type="file" id="decodeFileInput" class="button">
  74.         <br>
  75.         <button id="decodeGenerateButton" class="button" disabled>Générer</button>
  76.         <br>
  77.         <button id="decodeSaveButton" class="button" style="display: none;">Enregistrer</button>
  78.         <br>
  79.         <textarea id="decodeTextBox" rows="10" cols="50" style="margin-top: 20px;" readonly></textarea>
  80.         <br>
  81.         <canvas id="decodePictureBox"></canvas>
  82.     </div>
  83.  
  84.     <div id="fileCompressorSection" style="display: none;">
  85.         <h2>File Compressor</h2>
  86.         <select id="fileComboBox" size="10"></select>
  87.         <br>
  88.         <button onclick="addFilesToComboBox()">Choisir des fichiers</button>
  89.         <br>
  90.         <input type="file" id="folderInput" multiple directory="" webkitdirectory="" style="display: none;" onchange="addFoldersToComboBox()">
  91.         <button onclick="document.getElementById('folderInput').click()">Choisir un dossier</button>
  92.         <br>
  93.         <button onclick="clearSelectedItems()">Effacer</button>
  94.         <br>
  95.         <button onclick="compressAndSave()">Compresser et Enregistrer</button>
  96.         <br>
  97.         <select id="compressionComboBox">
  98.             <option value="best">Best</option>
  99.             <option value="store">Store</option>
  100.             <option value="normal">Normal</option>
  101.             <option value="maximum">Maximum</option>
  102.         </select>
  103.         <br>
  104.         <select id="extensionComboBox">
  105.             <option value="zip">.zip</option>
  106.             <option value="rar">.rar</option>
  107.             <option value="iso">.iso</option>
  108.         </select>
  109.     </div>
  110.  
  111.     <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  112.  
  113.     <script>
  114.         let selectedFiles = [];
  115.  
  116.         function addFilesToComboBox() {
  117.             const fileInput = document.createElement("input");
  118.             fileInput.type = "file";
  119.             fileInput.multiple = true;
  120.             fileInput.onchange = function () {
  121.                 const fileComboBox = document.getElementById("fileComboBox");
  122.  
  123.                 for (let i = 0; i < fileInput.files.length; i++) {
  124.                    selectedFiles.push(fileInput.files[i]);
  125.  
  126.                    const option = document.createElement("option");
  127.                    option.text = fileInput.files[i].name;
  128.                    fileComboBox.add(option);
  129.                }
  130.            };
  131.            fileInput.click();
  132.        }
  133.  
  134.        function addFoldersToComboBox() {
  135.            const folderInput = document.getElementById("folderInput");
  136.            const fileComboBox = document.getElementById("fileComboBox");
  137.  
  138.            for (let i = 0; i < folderInput.files.length; i++) {
  139.                traverseDirectory(folderInput.files[i], "");
  140.            }
  141.        }
  142.  
  143.        async function traverseDirectory(item, parentPath) {
  144.            if (item.isDirectory) {
  145.                const reader = item.createReader();
  146.                const entries = await reader.readEntries();
  147.                for (const entry of entries) {
  148.                    const fullPath = `${parentPath}/${entry.name}`;
  149.                    traverseDirectory(entry, fullPath);
  150.                }
  151.            } else {
  152.                selectedFiles.push(item);
  153.  
  154.                const option = document.createElement("option");
  155.                option.text = parentPath + "/" + item.webkitRelativePath;
  156.                fileComboBox.add(option);
  157.            }
  158.        }
  159.  
  160.        function clearSelectedItems() {
  161.            const fileComboBox = document.getElementById("fileComboBox");
  162.            for (let i = fileComboBox.options.length - 1; i >= 0; i--) {
  163.                 if (fileComboBox.options[i].selected) {
  164.                     selectedFiles.splice(i, 1);
  165.                     fileComboBox.remove(i);
  166.                 }
  167.             }
  168.         }
  169.  
  170.         async function compressAndSave() {
  171.             const compressionLevel = document.getElementById("compressionComboBox").value;
  172.             const selectedExtension = document.getElementById("extensionComboBox").value;
  173.  
  174.             const compressedData = await compressData(selectedFiles, compressionLevel);
  175.  
  176.             const blob = new Blob([compressedData], { type: 'application/octet-stream' });
  177.             const link = document.createElement('a');
  178.             link.href = URL.createObjectURL(blob);
  179.  
  180.             // Demander le nom du fichier compressé sans l'extension
  181.             const compressedFileName = prompt("Entrer le nom du fichier compressé:", `fichiers_compresses`);
  182.             if (!compressedFileName) {
  183.                 return; // Annuler la compression si le nom de fichier est vide
  184.             }
  185.  
  186.             const fullFileName = `${compressedFileName}.${selectedExtension}`;
  187.             link.download = fullFileName;
  188.             link.click();
  189.         }
  190.  
  191.         async function compressData(files, compressionLevel) {
  192.             // Créer un nouveau FormData pour les fichiers et dossiers sélectionnés
  193.             const zip = new JSZip();
  194.  
  195.             for (const file of files) {
  196.                 const fileContent = await file.arrayBuffer();
  197.                 const filePath = file.webkitRelativePath || file.name;
  198.                 zip.file(filePath, fileContent);
  199.             }
  200.  
  201.             // Utiliser pako pour compresser les données
  202.             const options = { level: compressionLevel === 'store' ? 0 : (compressionLevel === 'maximum' ? 9 : 5) };
  203.             const dataToCompress = await zip.generateAsync({ type: "uint8array", compression: "DEFLATE", compressionOptions: options });
  204.  
  205.             return dataToCompress;
  206.         }
  207.     const colorTextCheckbox = document.getElementById("colorTextCheckbox");
  208.     const colorTextOptions = document.getElementById("colorTextOptions");
  209.    
  210.     colorTextCheckbox.addEventListener("change", () => {
  211.         if (colorTextCheckbox.checked) {
  212.             colorTextOptions.style.display = "block";
  213.         } else {
  214.             colorTextOptions.style.display = "none";
  215.         }
  216.     });
  217.  
  218. $(document).ready(function() {
  219.     const colorPicker = document.getElementById("colorPicker");
  220.     const addColorTextButton = document.getElementById("addColorTextButton");
  221.     const colorTextBox = document.getElementById("colorTextBox");
  222.     const textSizeInput = document.getElementById("textSize");
  223.  
  224.     colorTextBox.addEventListener("input", function() {
  225.         if (colorTextBox.value.trim() !== "") {
  226.             addColorTextButton.disabled = false;
  227.         } else {
  228.             addColorTextButton.disabled = true;
  229.         }
  230.     });
  231.  
  232.     const gridSize = 10; // Taille de la grille pour les carrés
  233.  
  234. addColorTextButton.addEventListener("click", function () {
  235.     const canvas = document.getElementById("encodePictureBox").querySelector("canvas");
  236.     const context = canvas.getContext("2d");
  237.  
  238.     const text = colorTextBox.value;
  239.     const textSize = parseInt(textSizeInput.value, 10);
  240.     const color = colorPicker.value;
  241.  
  242.     context.font = `${textSize}px sans-serif`;
  243.     context.fillStyle = color;
  244.  
  245.     const verticalPositionSelect = document.getElementById("verticalPosition");
  246.     const horizontalPositionSelect = document.getElementById("horizontalPosition");
  247.  
  248.     const selectedVerticalPosition = verticalPositionSelect.value;
  249.     const selectedHorizontalPosition = horizontalPositionSelect.value;
  250.  
  251.     let textX = 0;
  252.     let textY = 0;
  253.  
  254.     switch (selectedVerticalPosition) {
  255.         case "up":
  256.             textY = textSize;
  257.             break;
  258.         case "down":
  259.             textY = canvas.height - textSize;
  260.             break;
  261.         case "center":
  262.             textY = canvas.height / 2 + textSize / 2;
  263.             break;
  264.         default:
  265.             break;
  266.     }
  267.  
  268.     switch (selectedHorizontalPosition) {
  269.         case "left":
  270.             textX = textSize;
  271.             break;
  272.         case "right":
  273.             textX = canvas.width - context.measureText(text).width - textSize;
  274.             break;
  275.         case "center":
  276.             textX = canvas.width / 2 - context.measureText(text).width / 2;
  277.             break;
  278.         default:
  279.             break;
  280.     }
  281.  
  282.     // Copier tous les pixels blancs de l'image
  283.     const whitePixels = copyAllWhitePixels(context);
  284.  
  285.     // Dessiner le texte à la position calculée
  286.     context.fillText(text, textX, textY);
  287.  
  288.     // Restaurer les pixels blancs à leur position d'origine
  289.     restoreAllWhitePixels(context, whitePixels);
  290. });
  291.  
  292. // Copier tous les pixels blancs de l'image
  293. function copyAllWhitePixels(context) {
  294.     const imageData = context.getImageData(0, 0, context.canvas.width, context.canvas.height);
  295.     const whitePixels = [];
  296.  
  297.     for (let i = 0; i < imageData.data.length; i += 4) {
  298.        const r = imageData.data[i];
  299.        const g = imageData.data[i + 1];
  300.        const b = imageData.data[i + 2];
  301.  
  302.        if (r === 255 && g === 255 && b === 255) {
  303.            whitePixels.push({ index: i, data: imageData.data.slice(i, i + 4) });
  304.            // Réinitialiser les pixels blancs à transparents dans l'image source
  305.            imageData.data[i] = 0;
  306.            imageData.data[i + 1] = 0;
  307.            imageData.data[i + 2] = 0;
  308.            imageData.data[i + 3] = 0;
  309.        }
  310.    }
  311.    // Réintégrer les pixels modifiés dans l'image source
  312.    context.putImageData(imageData, 0, 0);
  313.  
  314.    return whitePixels;
  315. }
  316.  
  317. // Restaurer les pixels blancs à leur position d'origine
  318. function restoreAllWhitePixels(context, whitePixels) {
  319.    for (const pixel of whitePixels) {
  320.        const x = pixel.index / 4 % context.canvas.width;
  321.        const y = Math.floor(pixel.index / 4 / context.canvas.width);
  322.        context.putImageData(new ImageData(new Uint8ClampedArray(pixel.data), 1, 1), x, y);
  323.    }
  324. }
  325.            $("#operationSelect").change(function() {
  326.                const selectedOperation = $(this).val();
  327.                $("#compressSection, #encodeSection, #decodeSection, #fileCompressorSection").hide();
  328.                if (selectedOperation === "compress") {
  329.                    $("#compressSection").show();
  330.                } else if (selectedOperation === "encode") {
  331.                    $("#encodeSection").show();
  332.                } else if (selectedOperation === "decode") {
  333.                    $("#decodeSection").show();
  334.                } else if (selectedOperation === "pakobest") {
  335.                    $("#fileCompressorSection").show();
  336.                }
  337.            });
  338.            // Gestionnaires d'événements pour la section de compression
  339.            const fileInput = document.getElementById("fileInput");
  340.            const compressButton = document.getElementById("compressButton");
  341.  
  342.            fileInput.addEventListener("change", function (e) {
  343.                if (e.target.files.length > 0) {
  344.                     compressButton.disabled = false;
  345.                 }
  346.             });
  347.  
  348.  
  349.                 loadButton.addEventListener("click", function () {
  350.         encodeFileInput.click();
  351.     });
  352.  
  353.     // Gestionnaire d'événement pour le chargement du fichier d'encodage
  354.     encodeFileInput.addEventListener("change", function (e) {
  355.         if (e.target.files.length > 0) {
  356.             const file = e.target.files[0];
  357.             const reader = new FileReader();
  358.             reader.onload = function (event) {
  359.                 // Convertir les données du fichier en binaire
  360.                 const arrayBuffer = event.target.result;
  361.                 const byteArray = new Uint8Array(arrayBuffer);
  362.                 let binaryText = "";
  363.                 byteArray.forEach(function (byte) {
  364.                     binaryText += byte.toString(2).padStart(8, "0");
  365.                 });
  366.  
  367.                 // Afficher le texte binaire dans la zone de texte
  368.                 const textBox = document.getElementById("textBox");
  369.                 textBox.value = binaryText;
  370.                 generateButton.disabled = false;
  371.             };
  372.             reader.readAsArrayBuffer(file);
  373.         }
  374.     });
  375.  
  376.     // Gestionnaire d'événement pour le bouton de génération de motif d'encodage
  377.     const generateButton = document.getElementById("generateButton");
  378.  
  379.     generateButton.addEventListener("click", function () {
  380.         const binaryText = textBox.value;
  381.         const imageSize = Math.ceil(Math.sqrt(binaryText.length));
  382.         const bitmap = new ImageData(imageSize, imageSize);
  383.  
  384.         for (let i = 0; i < binaryText.length; i++) {
  385.            const x = i % imageSize;
  386.            const y = Math.floor(i / imageSize);
  387.            const color = binaryText[i] === "1" ? [0, 0, 0, 255] : [255, 255, 255, 255];
  388.            const index = (x + y * imageSize) * 4;
  389.            bitmap.data[index] = color[0];
  390.            bitmap.data[index + 1] = color[1];
  391.            bitmap.data[index + 2] = color[2];
  392.            bitmap.data[index + 3] = color[3];
  393.        }
  394.  
  395.        // Créer un élément canvas pour afficher le motif généré
  396.        const canvas = document.createElement("canvas");
  397.        canvas.width = imageSize;
  398.        canvas.height = imageSize;
  399.        const context = canvas.getContext("2d");
  400.        context.putImageData(bitmap, 0, 0);
  401.  
  402.        // Afficher le motif généré dans la section d'encodage
  403.        const encodePictureBox = document.getElementById("encodePictureBox");
  404.        encodePictureBox.innerHTML = "";
  405.        encodePictureBox.appendChild(canvas);
  406.        saveButton.disabled = false;
  407.    });
  408.    // Gestionnaire d'événement pour le bouton d'enregistrement du motif d'encodage
  409.    const saveButton = document.getElementById("saveButton");
  410.  
  411.    saveButton.addEventListener("click", function () {
  412.        const canvas = encodePictureBox.querySelector("canvas");
  413.        const image = canvas.toDataURL("image/bmp").replace("image/bmp", "image/octet-stream");
  414.        const a = document.createElement("a");
  415.        const fileName = prompt("Entrez le nom du fichier BMP :", "motif.bmp") || "motif.bmp";
  416.        a.href = image;
  417.        a.download = fileName;
  418.        document.body.appendChild(a);
  419.        a.click();
  420.        document.body.removeChild(a);
  421.    });
  422.  
  423.    // Gestionnaire d'événement pour le chargement du fichier de décodage
  424.    const decodeFileInput = document.getElementById("decodeFileInput");
  425.    const decodeGenerateButton = document.getElementById("decodeGenerateButton");
  426.    const decodeSaveButton = document.getElementById("decodeSaveButton");
  427.    const decodePictureBox = document.getElementById("decodePictureBox");
  428.    const decodeTextBox = document.getElementById("decodeTextBox");
  429.    const decodeCanvas = decodePictureBox.getContext("2d");
  430.    let loadedBitmap = null;
  431.    let binaryText = "";
  432.    decodeFileInput.addEventListener("change", (event) => {
  433.         const file = event.target.files[0];
  434.         if (file) {
  435.             const reader = new FileReader();
  436.             reader.onload = (e) => {
  437.                 const image = new Image();
  438.                 image.src = e.target.result;
  439.                 image.onload = () => {
  440.                     decodePictureBox.width = image.width;
  441.                     decodePictureBox.height = image.height;
  442.                     decodeCanvas.drawImage(image, 0, 0);
  443.                     loadedBitmap = image;
  444.                     decodeGenerateButton.disabled = false;
  445.                 };
  446.             };
  447.             reader.readAsDataURL(file);
  448.         }
  449.     });
  450.  
  451.     decodeGenerateButton.addEventListener("click", () => {
  452.         if (!loadedBitmap) {
  453.             alert("Veuillez charger une image d'abord.");
  454.             return;
  455.         }
  456.  
  457.         const imageData = decodeCanvas.getImageData(0, 0, decodePictureBox.width, decodePictureBox.height);
  458.         binaryText = generateBinaryPattern(imageData);
  459.         decodeTextBox.value = binaryText;
  460.         decodeSaveButton.style.display = "block";
  461.     });
  462.  
  463.     decodeSaveButton.addEventListener("click", () => {
  464.         if (!binaryText.trim()) {
  465.             alert("Le contenu du TextBox est vide. Veuillez générer le motif d'abord.");
  466.             return;
  467.         }
  468.  
  469.         const binaryBytes = convertBinaryTextToBytes(binaryText);
  470.         const blob = new Blob([binaryBytes], { type: "application/zip" });
  471.         const a = document.createElement("a");
  472.         const fileName = prompt("Entrez le nom du fichier ZIP :", "binary_pattern.zip") || "binary_pattern.zip";
  473.         a.href = URL.createObjectURL(blob);
  474.         a.download = fileName;
  475.         document.body.appendChild(a);
  476.         a.click();
  477.         document.body.removeChild(a);
  478.         URL.revokeObjectURL(a.href);
  479.     });
  480.  
  481.             function generateBinaryPattern(imageData) {
  482.                 const threshold = 128;
  483.                 let binaryText = "";
  484.  
  485.                 for (let y = 0; y < imageData.height; y++) {
  486.                    for (let x = 0; x < imageData.width; x++) {
  487.                        const index = (y * imageData.width + x) * 4;
  488.                        const r = imageData.data[index];
  489.                        const g = imageData.data[index + 1];
  490.                        const b = imageData.data[index + 2];
  491.                        const luminance = (0.299 * r + 0.587 * g + 0.114 * b);
  492.                        binaryText += (luminance < threshold) ? "1" : "0";
  493.                    }
  494.                }
  495.  
  496.                return binaryText;
  497.            }
  498.  
  499.            function convertBinaryTextToBytes(binaryText) {
  500.                const byteCount = Math.ceil(binaryText.length / 8);
  501.                const bytes = new Uint8Array(byteCount);
  502.  
  503.                for (let i = 0; i < byteCount; i++) {
  504.                    const byteStart = i * 8;
  505.                    const byteEnd = byteStart + 8;
  506.                    const byte = binaryText.slice(byteStart, byteEnd);
  507.                    bytes[i] = parseInt(byte, 2);
  508.                }
  509.  
  510.                return bytes;
  511.            }
  512.    compressButton.addEventListener("click", function () {
  513.        // Récupérer les fichiers sélectionnés
  514.        const filesToCompress = Array.from(fileInput.files);
  515.        // Créer une instance JSZip
  516.        const zip = new JSZip();
  517.  
  518.        // Créer un tableau de promesses pour lire les fichiers et les ajouter à l'archive zip
  519.        const promises = filesToCompress.map(file => {
  520.             return new Promise(resolve => {
  521.                 const reader = new FileReader();
  522.                 reader.onload = function () {
  523.                     zip.file(file.name, reader.result);
  524.                     resolve();
  525.                 };
  526.                 reader.readAsArrayBuffer(file);
  527.             });
  528.         });
  529.  
  530.         // Attendre que toutes les promesses soient résolues, puis générer et télécharger l'archive zip
  531.         Promise.all(promises).then(() => {
  532.             const zipName = prompt("Entrez le nom du fichier ZIP :") || "compressed.zip";
  533.             zip.generateAsync({ type: "blob" }).then(function (content) {
  534.                 // Créer un lien de téléchargement
  535.                 const a = document.createElement("a");
  536.                 a.href = URL.createObjectURL(content);
  537.                 a.download = zipName;
  538.                 document.body.appendChild(a);
  539.                 a.click();
  540.                 document.body.removeChild(a);
  541.                 URL.revokeObjectURL(a.href);
  542.             });
  543.         });
  544.     });
  545. });
  546.     </script>
  547. </body>
  548. </html>
  549.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement