Git Product home page Git Product logo

gifcompress's Introduction

header

gifcompress's People

Contributors

seminseminsemin avatar

Watchers

 avatar

gifcompress's Issues

gif.js.optimized로 gif 생성 후 감귤 마켓 서버에 이미지 업로드가 안 되는 문제

문제 상황

gif 압축을 하고자 했습니다. gif 압축을 위한 라이브러리로 gif.js.optimizedgifler를 이용했습니다.

gifler를 사용한 이유는 gif 압축을 위해서 입니다. 우선 gif 파일에서 각 프레임을 추출합니다. 이를 캔버스에 그리면서 리사이징을 통해 각 프레임의 사이즈를 줄입니다. 이렇게 리사이징된 각 프레임을 다시 gif로 만들기 위해 gif.js.optimized를 사용했습니다.

일단 압축은 따로 진행하지 않고 gif를 프레임마다 나눠서 다시 gif로 합칠 수 있는지 확인만 했습니다.

문제가 발생한 것은 이렇게 만든 gif를 서버에 업로드했을 때입니다. 응답 결과를 콘솔에 찍어보면 {}로 빈 객체가 나옵니다. 서버에 요청은 가는데 응답이 왜 빈 객체가 나오는지 잘 이해가 되지 않습니다.

App.jsx 설명

🔗 App.jsx 코드로 바로가기

실행 화면

screen-recording.webm

코드 설명

// 95번째 라인~
// gifler를 이용해 gif에서 프레임 추출 후, gif.js.optimized를 이용해 다시 합친 것을 src로 갖는 img 태그 리턴
return <img src={output} alt="rendering" />;
// 8번째 라인~
// gif.js.optimized를 이용해 다시 합쳐진 gif를 렌더링하기 위한 state
const [output, setOutput] = useState();
// 10번째 라인~
// 앱이 시작될 때 한 번만 실행되도록(gif를 불러오고 압축 후 서버에 보내는 과정) 의존성 x
useEffect(() => {
    // 기타 코드: 아래에 더 자세히 설명하도록 하겠습니다
}, []);
// 11번째 라인~
// gif.js.optimized를 GIF로 임포트 했음(3번 라인)
// workerScript에서 public에 있는 gif.worker.js를 쓰는 이유: https://github.com/jnordberg/gif.js/issues/115
const gif = new GIF({
    workers: 2,
    workerScript: process.env.PUBLIC_URL + "/gif.worker.js", 
    quality: 10,
});
// 17번째 라인~
// 메인 코드: 프레임 추출 => 다시 gif로 만들기 => 서버 제출

window.gifler(QQ).get((a) => {
    // gifler를 이용해 QQ(assets 폴더 하에 있는 gif 파일)에서 각 프레임을 추출합니다.
    // 사실 [gifler의 createBufferCanvas](https://themadcreator.github.io/gifler/docs.html#animator::createBufferCanvas())를 이용해서 해야하는데, 어떻게 그 함수를 불러와야 하는지 모르겠어서, createBufferCanvas 코드를 참고해 제가 직접 코드를 적었습니다. 이 부분도 해결해야 할 문제점 중 하나입니다.
    const res = a["_frames"].map((frame) => {
        let bufferCanvas, bufferContext, imageData;
        bufferCanvas = document.createElement("canvas");
        bufferContext = bufferCanvas.getContext("2d");
        bufferCanvas.width = frame.width;
        bufferCanvas.height = frame.height;
        imageData = bufferContext.createImageData(
            frame.width,
            frame.height
        );
        imageData.data.set(frame.pixels);
        bufferContext.putImageData(imageData, -frame.x, -frame.y);
        // 프레임이 잘 추출됐는지 화면에서 확인하기 위해 편의상 state를 이용하지 않고 DOM을 직접 조작했습니다.
        document.body.append(bufferCanvas);
        return bufferCanvas;
    });

    const exportCuts = async () => {
        const cuts = res;

        // 각 canvas를 이용해 gif 생성
        cuts.forEach((canvas) => {
            gif.addFrame(canvas, { delay: 100 });
        });

        gif.on("finished", async (blob) => {
            console.log("blob:")
            console.log(blob);
            console.log("---------------");

            const url = URL.createObjectURL(blob);
            const file = new File([blob], "흑흑", {
                type: "image/gif",
            });

            console.log("blob to file:")
            console.log(file);
            console.log("---------------");
            setOutput(url);

            const formData = new FormData();
            formData.append("image", file);

            // https://velog.io/@josworks27/formData-console.log
            for (let value of formData.values()) {
                console.log("formdata에 file이 제대로 담겼는지 확인:")
                console.log(value);
                console.log("---------------");
            }

            const requestUrl = "https://mandarin.api.weniv.co.kr/";

            const res = await fetch(requestUrl + "image/uploadfile", {
                method: "POST",
                body: formData,
                headers: {
                    "Content-type": "multipart/form-data",
                },
            });
            console.log("res:")
            console.log(res);
            console.log("---------------");

            const json = await res.json();
            console.log("res.json:")
            console.log(json);
        });

        gif.render();
    };

    exportCuts();
});

스크린샷 2023-01-16 오전 1 04 55

문제 원인 및 해결 방법

문제를 해결하기 위해 멘토님께 질문을 드렸습니다.

  • new File을 이용해 blob을 파일로 변경시 name을 "흑흑"이라고 함 => "흑흑.gif"로 바꿈
  • headers 지움

서버에 업로드된 이미지: https://mandarin.api.weniv.co.kr/1673833296342.gif

배운 점

  • new File을 이용해 파일 생성시 file name에 확장자를 명시해야 한다는 점을 배웠습니다.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.