Welcome to Code Forum!

Join a community that supports you and your coding journey from day one. We strive to be a friendly, supportive community that empowers everyone to be better developers. By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.

    GIF shows where to locate </> in the thread and or post editor toolbar.
    To learn more about how to use our BBCode feature, review our "How to post your code into threads" here.

    Thank you, Code Forum.

JavaScript GIF Frame Extractor

masood.designs

New Coder
Hi,

A few days back, I created this HTML with JavaScript to extract Frames from the GIF file. The code works well on some GIF files, but fails on others. Can you please refine the code so that it can extract the frames from every GIF.
https://digidemo.expresskcs.com/penna/masood_solutions/Animated_GIF/11250545-01_300x250.gif
https://digidemo.expresskcs.com/penna/masood_solutions/Animated_GIF/B0063544_V4_C1_728x90.gif

In addition, I also like to add a button to extract the frames from the animated web banners, like:
https://digidemo.expresskcs.com/penna/masood_solutions/html5_mpu/

https://digidemo.expresskcs.com/penna/masood_solutions/html5_mobilebanner/

HTML:
<!DOCTYPE html>
<html>
<head>
    <title>GIF Frame Extractor</title>
    <styl   e>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px 50px;
            background-color: #f4f4f4;
        }

        #container {
            max-width: 80%;
            margin: 160px auto 0; /* Adjust margin to accommodate fixed header and input */
            background: #fff;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }

        h1 {
            text-align: center;
            color: #333;
            position: fixed;
            width: 100%;
            background: #c0f5db;
            /* Updated background color */
            top: 0;
            left: 0;
            padding: 10px 0;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
            z-index: 1000;
        }

        .input-wrapper {
            text-align: center;
            position: fixed;
            width: 100%;
            background: #c0f5db;
            /* Updated background color */
            top: 60px;
            /* Adjust based on header height */
            left: 0;
            padding: 10px;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
            z-index: 1000;
        }

        input[type="file"] {
            display: none;
        }

        .custom-file-input, .custom-url-input, .url-button {
            display: inline-block;
            padding: 10px 20px;
            border-radius: 5px;
            background-color: #007bff;
            color: #fff;
            cursor: pointer;
            font-size: 16px;
            transition: background-color 0.3s ease;
            margin: 5px;
        }

        .custom-file-input:hover, .custom-url-input:hover, .url-button:hover {
            background-color: #0056b3;
        }

        .url-input {
            padding: 10px;
            width: 300px;
            border-radius: 5px;
            border: 1px solid #ccc;
            margin-right: 10px;
        }

        #filename {
            margin-top: 10px;
            font-size: 14px;
            text-align: center;
        }

        .filename-color {
            color: red;
            font-weight: bold;
        }
        #framesContainer {
            /* size: 20%; */
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            gap: 10px;
        }
        
        .frame {
            border: 1px solid #ddd;
            border-radius: 5px;
            overflow: hidden;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
        }

        .frame canvas {
            display: block;
        }
    </styl>
</head>
<body>
    <h1 style="margin-top: 10px;">GIF Frame Extractor</h1>
    <div class="input-wrapper">
        <input type="file" id="gifInput" accept="image/gif" />
        <input type="text" id="urlInput" class="url-input" placeholder="Enter GIF URL" />
        <submit class="url-button" id="fetchUrlButton">Fetch GIF</submit>
        <label class="custom-file-input" for="gifInput">Upload GIF</label>
        <div id="filename"></div>
    </div>
    <div id="container">
        <div id="framesContainer"></div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/omggif.min.js"></script>
    <script>
        document.getElementById("gifInput").addEventListener("change", function(event) {
            const file = event.target.files[0];
            const filenameDisplay = document.getElementById("filename");

            if (file) {
                filenameDisplay.innerHTML = `Selected file: <span class="filename-color">${file.name}</span>`;
                const reader = new FileReader();
                reader.onload = function(e) {
                    const arrayBuffer = e.target.result;
                    extractFrames(arrayBuffer);
                };
                reader.readAsArrayBuffer(file);
            } else {
                filenameDisplay.textContent = "";
            }
        });

        document.getElementById("fetchUrlButton").addEventListener("click", function() {
            const url = document.getElementById("urlInput").value;
            const filenameDisplay = document.getElementById("filename");

            if (url) {
                filenameDisplay.innerHTML = `Selected URL: <span class="filename-color">${url}</span>`;
                fetch(url)
                    .then(response => response.arrayBuffer())
                    .then(arrayBuffer => extractFrames(arrayBuffer))
                    .catch(error => {
                        console.error("Error fetching the GIF from URL:", error);
                        filenameDisplay.textContent = "Error fetching the GIF from URL.";
                    });
            }
        });

        function extractFrames(arrayBuffer) {
            const gif = new GifReader(new Uint8Array(arrayBuffer));
            const framesContainer = document.getElementById("framesContainer");
            framesContainer.innerHTML = ""; // Clear previous frames

            const mainCanvas = document.createElement("canvas");
            mainCanvas.width = gif.width;
            mainCanvas.height = gif.height;
            const mainContext = mainCanvas.getContext("2d");

            const offscreenCanvas = document.createElement("canvas");
            offscreenCanvas.width = gif.width;
            offscreenCanvas.height = gif.height;
            const offscreenContext = offscreenCanvas.getContext("2d");

            for (let i = 0; i < gif.numFrames(); i++) {
                const frameInfo = gif.frameInfo(i);

                if (frameInfo.disposal === 2) {
                    mainContext.clearRect(0, 0, mainCanvas.width, mainCanvas.height);
                } else if (frameInfo.disposal === 3) {
                    mainContext.putImageData(offscreenContext.getImageData(0, 0, gif.width, gif.height), 0, 0);
                }

                const imageData = mainContext.createImageData(gif.width, gif.height);
                gif.decodeAndBlitFrameRGBA(i, imageData.data);
                mainContext.putImageData(imageData, 0, 0);

                const frameCanvas = document.createElement("canvas");
                frameCanvas.width = gif.width;
                frameCanvas.height = gif.height;
                frameCanvas.getContext("2d").drawImage(mainCanvas, 0, 0);

                const frameDiv = document.createElement("div");
                frameDiv.className = "frame";
                frameDiv.appendChild(frameCanvas);
                framesContainer.appendChild(frameDiv);

                if (frameInfo.disposal === 3) {
                    offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
                    offscreenContext.drawImage(mainCanvas, 0, 0);
                }
            }
        }
    </script>
</body>
</html>
 

Buy us a coffee!

Buy me a coffee.
Back
Top Bottom