aaharu / gifken

JavaScript library that can reverse and split animated GIFs
MIT License
24 stars 3 forks source link

Best way to split and rewrite? #32

Open flyingatm opened 3 years ago

flyingatm commented 3 years ago

Hello! Thank you for your hard work!

I'm trying write a way to resize gif to 2 dimensions (original and small) with gifken and turn them into file object to send server. I wrote a code that works perfectly!

But it tooks 3-4 seconds to resize to 2 dimensions a gif that contains 102 frames.

This is my code:

var thumb = [];
var main = [];
var frame_count;
var delays;
async function thread_image_handler(){
  thumb = [];
  main = [];
  $(".image-send").toggleClass("is-loading");
  $("#fileinput").attr("disabled", "true");
  var imageInput = $('#fileinput').prop('files')[0];
  var imageBlob = (window.URL ? URL : webkitURL).createObjectURL(imageInput);
  var i = 0;
  var scaleRatio;
  var desiredWidth = 75;
  var widthRAW;
  var heightRAW;
  var finalRatio;

  const xhr = new XMLHttpRequest();
  xhr.open("GET", imageBlob, true);
  xhr.responseType = "arraybuffer";
  xhr.onload = (e) => {
    const arrayBuffer = e.target["response"];
    const gif = gifken.Gif.parse(arrayBuffer);

    widthRAW = gif.width;
    heightRAW = gif.height;
    scaleRatio = desiredWidth*100/widthRAW;
    finalRatio = scaleRatio/100;
    frame_count = gif.frameIndex1;

    const smallcanvas = document.createElement("canvas");
    const maincanvas = document.createElement("canvas");
    smallcanvas.width = desiredWidth;
    smallcanvas.height = heightRAW*finalRatio;
    maincanvas.width = widthRAW;
    maincanvas.height = heightRAW;
    const mainCTX = maincanvas.getContext("2d");
    const smallCTX = smallcanvas.getContext("2d");

  //  smallCTX.clearRect(0, 0, desiredWidth, heightRAW*finalRatio);
  //  mainCTX.clearRect(0, 0, widthRAW, heightRAW);

    Promise.all(gif.split().map((splited) => {
      return new Promise((resolve, reject) => {
        const img = new Image();
        img.onload = () => resolve(img);
        img.onerror = (e) => reject(e);
        img.src = gifken.GifPresenter.writeToDataUrl(splited.writeToArrayBuffer());
      })
    })).then((values) => {
      values.forEach(function (img) {
        smallCTX.drawImage(img, 0, 0, desiredWidth, heightRAW*finalRatio);
        mainCTX.drawImage(img, 0, 0);
       var b64small = smallcanvas.toDataURL("image/jpeg");
       var b64full = maincanvas.toDataURL("image/jpeg", 0.75);

       var procMain = dataURLtoFile(b64full, "full");
       var procSmall = dataURLtoFile(b64small, "thumb");

       thumb.push(procMain);
       main.push(procSmall);

/*
        var img_full = new Image();
        img_full.src = b64full;
        document.getElementById("hype_swup").appendChild(img_full);

        var img_small = new Image();
        img_small.src = b64small;
        document.getElementById("hype_swup").appendChild(img_small);
*/

        i++;
        if(i == frame_count){
        $(".image-send").toggleClass("is-loading");
        $("#fileinput").removeAttr("disabled");
        $(".image-dumper").attr("src", imageBlob);
        $(".image-dumper").show();
        }
      });
    });
  };
  xhr.send();

}

I wanted to know if there is a better way to resize and convert each frame into a file object.