Skip to content

Instantly share code, notes, and snippets.

@stu43005
Last active August 5, 2022 10:12
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save stu43005/49ff25325b357053b8e9 to your computer and use it in GitHub Desktop.
Save stu43005/49ff25325b357053b8e9 to your computer and use it in GitHub Desktop.
Pixiv動態圖錄製,完成後在原圖下方會出現gif圖
(function(file){
var script=document.createElement('script');
script.type='text/javascript';
script.src=file;
document.body.appendChild(script);
})("https://rawgit.com/stu43005/49ff25325b357053b8e9/raw/pixiv_gif_encoder.js");
/*
網址列(或書籤)用:
javascript:(function(file){var script=document.createElement('script');script.type='text/javascript';script.src=file;document.body.appendChild(script)})("https://rawgit.com/stu43005/49ff25325b357053b8e9/raw/pixiv_gif_encoder.js")
*/
// Lib: https://github.com/antimatter15/jsgif
LZWEncoder=function()
{var exports={};var EOF=-1;var imgW;var imgH
var pixAry;var initCodeSize;var remaining;var curPixel;var BITS=12;var HSIZE=5003;var n_bits
var maxbits=BITS;var maxcode
var maxmaxcode=1<<BITS;var htab=new Array;var codetab=new Array;var hsize=HSIZE;var free_ent=0;var clear_flg=false;var g_init_bits;var ClearCode;var EOFCode;var cur_accum=0;var cur_bits=0;var masks=[0x0000,0x0001,0x0003,0x0007,0x000F,0x001F,0x003F,0x007F,0x00FF,0x01FF,0x03FF,0x07FF,0x0FFF,0x1FFF,0x3FFF,0x7FFF,0xFFFF];var a_count;var accum=[];var LZWEncoder=exports.LZWEncoder=function LZWEncoder(width,height,pixels,color_depth)
{imgW=width;imgH=height;pixAry=pixels;initCodeSize=Math.max(2,color_depth);}
var char_out=function char_out(c,outs)
{accum[a_count++]=c;if(a_count>=254)flush_char(outs);}
var cl_block=function cl_block(outs)
{cl_hash(hsize);free_ent=ClearCode+2;clear_flg=true;output(ClearCode,outs);}
var cl_hash=function cl_hash(hsize)
{for(var i=0;i<hsize;++i)htab[i]=-1;}
var compress=exports.compress=function compress(init_bits,outs)
{var fcode;var i;var c;var ent;var disp;var hsize_reg;var hshift;g_init_bits=init_bits;clear_flg=false;n_bits=g_init_bits;maxcode=MAXCODE(n_bits);ClearCode=1<<(init_bits-1);EOFCode=ClearCode+1;free_ent=ClearCode+2;a_count=0;ent=nextPixel();hshift=0;for(fcode=hsize;fcode<65536;fcode*=2)
++hshift;hshift=8-hshift;hsize_reg=hsize;cl_hash(hsize_reg);output(ClearCode,outs);outer_loop:while((c=nextPixel())!=EOF)
{fcode=(c<<maxbits)+ent;i=(c<<hshift)^ent;if(htab[i]==fcode)
{ent=codetab[i];continue;}else if(htab[i]>=0)
{disp=hsize_reg-i;if(i==0)
disp=1;do
{if((i-=disp)<0)i+=hsize_reg;if(htab[i]==fcode)
{ent=codetab[i];continue outer_loop;}}while(htab[i]>=0);}
output(ent,outs);ent=c;if(free_ent<maxmaxcode)
{codetab[i]=free_ent++;htab[i]=fcode;}else cl_block(outs);}
output(ent,outs);output(EOFCode,outs);}
var encode=exports.encode=function encode(os)
{os.writeByte(initCodeSize);remaining=imgW*imgH;curPixel=0;compress(initCodeSize+1,os);os.writeByte(0);}
var flush_char=function flush_char(outs)
{if(a_count>0)
{outs.writeByte(a_count);outs.writeBytes(accum,0,a_count);a_count=0;}}
var MAXCODE=function MAXCODE(n_bits)
{return(1<<n_bits)-1;}
var nextPixel=function nextPixel()
{if(remaining==0)return EOF;--remaining;var pix=pixAry[curPixel++];return pix&0xff;}
var output=function output(code,outs)
{cur_accum&=masks[cur_bits];if(cur_bits>0)cur_accum|=(code<<cur_bits);else cur_accum=code;cur_bits+=n_bits;while(cur_bits>=8)
{char_out((cur_accum&0xff),outs);cur_accum>>=8;cur_bits-=8;}
if(free_ent>maxcode||clear_flg)
{if(clear_flg)
{maxcode=MAXCODE(n_bits=g_init_bits);clear_flg=false;}else
{++n_bits;if(n_bits==maxbits)maxcode=maxmaxcode;else maxcode=MAXCODE(n_bits);}}
if(code==EOFCode)
{while(cur_bits>0)
{char_out((cur_accum&0xff),outs);cur_accum>>=8;cur_bits-=8;}
flush_char(outs);}}
LZWEncoder.apply(this,arguments);return exports;}
NeuQuant=function()
{var exports={};var netsize=256;var prime1=499;var prime2=491;var prime3=487;var prime4=503;var minpicturebytes=(3*prime4);var maxnetpos=(netsize-1);var netbiasshift=4;var ncycles=100;var intbiasshift=16;var intbias=(1<<intbiasshift);var gammashift=10;var gamma=(1<<gammashift);var betashift=10;var beta=(intbias>>betashift);var betagamma=(intbias<<(gammashift-betashift));var initrad=(netsize>>3);var radiusbiasshift=6;var radiusbias=(1<<radiusbiasshift);var initradius=(initrad*radiusbias);var radiusdec=30;var alphabiasshift=10;var initalpha=(1<<alphabiasshift);var alphadec
var radbiasshift=8;var radbias=(1<<radbiasshift);var alpharadbshift=(alphabiasshift+radbiasshift);var alpharadbias=(1<<alpharadbshift);var thepicture
var lengthcount;var samplefac;var network;var netindex=new Array();var bias=new Array();var freq=new Array();var radpower=new Array();var NeuQuant=exports.NeuQuant=function NeuQuant(thepic,len,sample)
{var i;var p;thepicture=thepic;lengthcount=len;samplefac=sample;network=new Array(netsize);for(i=0;i<netsize;i++)
{network[i]=new Array(4);p=network[i];p[0]=p[1]=p[2]=(i<<(netbiasshift+8))/netsize;freq[i]=intbias/netsize;bias[i]=0;}}
var colorMap=function colorMap()
{var map=[];var index=new Array(netsize);for(var i=0;i<netsize;i++)
index[network[i][3]]=i;var k=0;for(var l=0;l<netsize;l++){var j=index[l];map[k++]=(network[j][0]);map[k++]=(network[j][1]);map[k++]=(network[j][2]);}
return map;}
var inxbuild=function inxbuild()
{var i;var j;var smallpos;var smallval;var p;var q;var previouscol
var startpos
previouscol=0;startpos=0;for(i=0;i<netsize;i++)
{p=network[i];smallpos=i;smallval=p[1];for(j=i+1;j<netsize;j++)
{q=network[j];if(q[1]<smallval)
{smallpos=j;smallval=q[1];}}
q=network[smallpos];if(i!=smallpos)
{j=q[0];q[0]=p[0];p[0]=j;j=q[1];q[1]=p[1];p[1]=j;j=q[2];q[2]=p[2];p[2]=j;j=q[3];q[3]=p[3];p[3]=j;}
if(smallval!=previouscol)
{netindex[previouscol]=(startpos+i)>>1;for(j=previouscol+1;j<smallval;j++)netindex[j]=i;previouscol=smallval;startpos=i;}}
netindex[previouscol]=(startpos+maxnetpos)>>1;for(j=previouscol+1;j<256;j++)netindex[j]=maxnetpos;}
var learn=function learn()
{var i;var j;var b;var g
var r;var radius;var rad;var alpha;var step;var delta;var samplepixels;var p;var pix;var lim;if(lengthcount<minpicturebytes)samplefac=1;alphadec=30+((samplefac-1)/3);p=thepicture;pix=0;lim=lengthcount;samplepixels=lengthcount/(3*samplefac);delta=(samplepixels/ncycles)|0;alpha=initalpha;radius=initradius;rad=radius>>radiusbiasshift;if(rad<=1)rad=0;for(i=0;i<rad;i++)radpower[i]=alpha*(((rad*rad-i*i)*radbias)/(rad*rad));if(lengthcount<minpicturebytes)step=3;else if((lengthcount%prime1)!=0)step=3*prime1;else
{if((lengthcount%prime2)!=0)step=3*prime2;else
{if((lengthcount%prime3)!=0)step=3*prime3;else step=3*prime4;}}
i=0;while(i<samplepixels)
{b=(p[pix+0]&0xff)<<netbiasshift;g=(p[pix+1]&0xff)<<netbiasshift;r=(p[pix+2]&0xff)<<netbiasshift;j=contest(b,g,r);altersingle(alpha,j,b,g,r);if(rad!=0)alterneigh(rad,j,b,g,r);pix+=step;if(pix>=lim)pix-=lengthcount;i++;if(delta==0)delta=1;if(i%delta==0)
{alpha-=alpha/alphadec;radius-=radius/radiusdec;rad=radius>>radiusbiasshift;if(rad<=1)rad=0;for(j=0;j<rad;j++)radpower[j]=alpha*(((rad*rad-j*j)*radbias)/(rad*rad));}}}
var map=exports.map=function map(b,g,r)
{var i;var j;var dist
var a;var bestd;var p;var best;bestd=1000;best=-1;i=netindex[g];j=i-1;while((i<netsize)||(j>=0))
{if(i<netsize)
{p=network[i];dist=p[1]-g;if(dist>=bestd)i=netsize;else
{i++;if(dist<0)dist=-dist;a=p[0]-b;if(a<0)a=-a;dist+=a;if(dist<bestd)
{a=p[2]-r;if(a<0)a=-a;dist+=a;if(dist<bestd)
{bestd=dist;best=p[3];}}}}
if(j>=0)
{p=network[j];dist=g-p[1];if(dist>=bestd)j=-1;else
{j--;if(dist<0)dist=-dist;a=p[0]-b;if(a<0)a=-a;dist+=a;if(dist<bestd)
{a=p[2]-r;if(a<0)a=-a;dist+=a;if(dist<bestd)
{bestd=dist;best=p[3];}}}}}
return(best);}
var process=exports.process=function process()
{learn();unbiasnet();inxbuild();return colorMap();}
var unbiasnet=function unbiasnet()
{var i;var j;for(i=0;i<netsize;i++)
{network[i][0]>>=netbiasshift;network[i][1]>>=netbiasshift;network[i][2]>>=netbiasshift;network[i][3]=i;}}
var alterneigh=function alterneigh(rad,i,b,g,r)
{var j;var k;var lo;var hi;var a;var m;var p;lo=i-rad;if(lo<-1)lo=-1;hi=i+rad;if(hi>netsize)hi=netsize;j=i+1;k=i-1;m=1;while((j<hi)||(k>lo))
{a=radpower[m++];if(j<hi)
{p=network[j++];try{p[0]-=(a*(p[0]-b))/alpharadbias;p[1]-=(a*(p[1]-g))/alpharadbias;p[2]-=(a*(p[2]-r))/alpharadbias;}catch(e){}}
if(k>lo)
{p=network[k--];try
{p[0]-=(a*(p[0]-b))/alpharadbias;p[1]-=(a*(p[1]-g))/alpharadbias;p[2]-=(a*(p[2]-r))/alpharadbias;}catch(e){}}}}
var altersingle=function altersingle(alpha,i,b,g,r)
{var n=network[i];n[0]-=(alpha*(n[0]-b))/initalpha;n[1]-=(alpha*(n[1]-g))/initalpha;n[2]-=(alpha*(n[2]-r))/initalpha;}
var contest=function contest(b,g,r)
{var i;var dist;var a;var biasdist;var betafreq;var bestpos;var bestbiaspos;var bestd;var bestbiasd;var n;bestd=~(1<<31);bestbiasd=bestd;bestpos=-1;bestbiaspos=bestpos;for(i=0;i<netsize;i++)
{n=network[i];dist=n[0]-b;if(dist<0)dist=-dist;a=n[1]-g;if(a<0)a=-a;dist+=a;a=n[2]-r;if(a<0)a=-a;dist+=a;if(dist<bestd)
{bestd=dist;bestpos=i;}
biasdist=dist-((bias[i])>>(intbiasshift-netbiasshift));if(biasdist<bestbiasd)
{bestbiasd=biasdist;bestbiaspos=i;}
betafreq=(freq[i]>>betashift);freq[i]-=betafreq;bias[i]+=(betafreq<<gammashift);}
freq[bestpos]+=beta;bias[bestpos]-=betagamma;return(bestbiaspos);}
NeuQuant.apply(this,arguments);return exports;}
GIFEncoder=function()
{for(var i=0,chr={};i<256;i++)
chr[i]=String.fromCharCode(i);function ByteArray(){this.bin=[];}
ByteArray.prototype.getData=function(){for(var v='',l=this.bin.length,i=0;i<l;i++)
v+=chr[this.bin[i]];return v;}
ByteArray.prototype.writeByte=function(val){this.bin.push(val);}
ByteArray.prototype.writeUTFBytes=function(string){for(var l=string.length,i=0;i<l;i++)
this.writeByte(string.charCodeAt(i));}
ByteArray.prototype.writeBytes=function(array,offset,length){for(var l=length||array.length,i=offset||0;i<l;i++)
this.writeByte(array[i]);}
var exports={};var width
var height;var transparent=null;var transIndex;var repeat=-1;var delay=0;var started=false;var out;var image;var pixels;var indexedPixels
var colorDepth;var colorTab;var usedEntry=new Array;var palSize=7;var dispose=-1;var closeStream=false;var firstFrame=true;var sizeSet=false;var sample=10;var comment="Generated by jsgif (https://github.com/antimatter15/jsgif/)";var setDelay=exports.setDelay=function setDelay(ms)
{delay=Math.round(ms/10);}
var setDispose=exports.setDispose=function setDispose(code)
{if(code>=0)dispose=code;}
var setRepeat=exports.setRepeat=function setRepeat(iter)
{if(iter>=0)repeat=iter;}
var setTransparent=exports.setTransparent=function setTransparent(c)
{transparent=c;}
var setComment=exports.setComment=function setComment(c)
{comment=c;}
var addFrame=exports.addFrame=function addFrame(im,is_imageData)
{if((im==null)||!started||out==null)
{throw new Error("Please call start method before calling addFrame");return false;}
var ok=true;try{if(!is_imageData){image=im.getImageData(0,0,im.canvas.width,im.canvas.height).data;if(!sizeSet)setSize(im.canvas.width,im.canvas.height);}else{image=im;}
getImagePixels();analyzePixels();if(firstFrame)
{writeLSD();writePalette();if(repeat>=0)
{writeNetscapeExt();}}
writeGraphicCtrlExt();if(comment!=''){writeCommentExt();}
writeImageDesc();if(!firstFrame)writePalette();writePixels();firstFrame=false;}catch(e){ok=false;}
return ok;}
var finish=exports.finish=function finish()
{if(!started)return false;var ok=true;started=false;try{out.writeByte(0x3b);}catch(e){ok=false;}
return ok;}
var reset=function reset()
{transIndex=0;image=null;pixels=null;indexedPixels=null;colorTab=null;closeStream=false;firstFrame=true;}
var setFrameRate=exports.setFrameRate=function setFrameRate(fps)
{if(fps!=0xf)delay=Math.round(100/fps);}
var setQuality=exports.setQuality=function setQuality(quality)
{if(quality<1)quality=1;sample=quality;}
var setSize=exports.setSize=function setSize(w,h)
{if(started&&!firstFrame)return;width=w;height=h;if(width<1)width=320;if(height<1)height=240;sizeSet=true}
var start=exports.start=function start()
{reset();var ok=true;closeStream=false;out=new ByteArray;try{out.writeUTFBytes("GIF89a");}catch(e){ok=false;}
return started=ok;}
var cont=exports.cont=function cont()
{reset();var ok=true;closeStream=false;out=new ByteArray;return started=ok;}
var analyzePixels=function analyzePixels()
{var len=pixels.length;var nPix=len/3;indexedPixels=[];var nq=new NeuQuant(pixels,len,sample);colorTab=nq.process();var k=0;for(var j=0;j<nPix;j++){var index=nq.map(pixels[k++]&0xff,pixels[k++]&0xff,pixels[k++]&0xff);usedEntry[index]=true;indexedPixels[j]=index;}
pixels=null;colorDepth=8;palSize=7;if(transparent!=null){transIndex=findClosest(transparent);}}
var findClosest=function findClosest(c)
{if(colorTab==null)return-1;var r=(c&0xFF0000)>>16;var g=(c&0x00FF00)>>8;var b=(c&0x0000FF);var minpos=0;var dmin=256*256*256;var len=colorTab.length;for(var i=0;i<len;){var dr=r-(colorTab[i++]&0xff);var dg=g-(colorTab[i++]&0xff);var db=b-(colorTab[i]&0xff);var d=dr*dr+dg*dg+db*db;var index=i/3;if(usedEntry[index]&&(d<dmin)){dmin=d;minpos=index;}
i++;}
return minpos;}
var getImagePixels=function getImagePixels()
{var w=width;var h=height;pixels=[];var data=image;var count=0;for(var i=0;i<h;i++)
{for(var j=0;j<w;j++)
{var b=(i*w*4)+j*4;pixels[count++]=data[b];pixels[count++]=data[b+1];pixels[count++]=data[b+2];}}}
var writeGraphicCtrlExt=function writeGraphicCtrlExt()
{out.writeByte(0x21);out.writeByte(0xf9);out.writeByte(4);var transp
var disp;if(transparent==null){transp=0;disp=0;}else{transp=1;disp=2;}
if(dispose>=0){disp=dispose&7;}
disp<<=2;out.writeByte(0|disp|0|transp);WriteShort(delay);out.writeByte(transIndex);out.writeByte(0);}
var writeCommentExt=function writeCommentExt()
{out.writeByte(0x21);out.writeByte(0xfe);out.writeByte(comment.length);out.writeUTFBytes(comment);out.writeByte(0);}
var writeImageDesc=function writeImageDesc()
{out.writeByte(0x2c);WriteShort(0);WriteShort(0);WriteShort(width);WriteShort(height);if(firstFrame){out.writeByte(0);}else{out.writeByte(0x80|0|0|0|palSize);}}
var writeLSD=function writeLSD()
{WriteShort(width);WriteShort(height);out.writeByte((0x80|0x70|0x00|palSize));out.writeByte(0);out.writeByte(0);}
var writeNetscapeExt=function writeNetscapeExt()
{out.writeByte(0x21);out.writeByte(0xff);out.writeByte(11);out.writeUTFBytes("NETSCAPE"+"2.0");out.writeByte(3);out.writeByte(1);WriteShort(repeat);out.writeByte(0);}
var writePalette=function writePalette()
{out.writeBytes(colorTab);var n=(3*256)-colorTab.length;for(var i=0;i<n;i++)out.writeByte(0);}
var WriteShort=function WriteShort(pValue)
{out.writeByte(pValue&0xFF);out.writeByte((pValue>>8)&0xFF);}
var writePixels=function writePixels()
{var myencoder=new LZWEncoder(width,height,indexedPixels,colorDepth);myencoder.encode(out);}
var stream=exports.stream=function stream()
{return out;}
var setProperties=exports.setProperties=function setProperties(has_start,is_first){started=has_start;firstFrame=is_first;}
return exports}
function encode64(input){var output="",i=0,l=input.length,key="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",chr1,chr2,chr3,enc1,enc2,enc3,enc4;while(i<l){chr1=input.charCodeAt(i++);chr2=input.charCodeAt(i++);chr3=input.charCodeAt(i++);enc1=chr1>>2;enc2=((chr1&3)<<4)|(chr2>>4);enc3=((chr2&15)<<2)|(chr3>>6);enc4=chr3&63;if(isNaN(chr2))enc3=enc4=64;else if(isNaN(chr3))enc4=64;output=output+key.charAt(enc1)+key.charAt(enc2)+key.charAt(enc3)+key.charAt(enc4);}
return output;}
function b64ToUint6(nChr){return nChr>64&&nChr<91?nChr-65:nChr>96&&nChr<123?nChr-71:nChr>47&&nChr<58?nChr+4:nChr===43?62:nChr===47?63:0;}
function base64DecToArr(sBase64,nBlocksSize){var sB64Enc=sBase64.replace(/[^A-Za-z0-9\+\/]/g,""),nInLen=sB64Enc.length,nOutLen=nBlocksSize?Math.ceil((nInLen*3+1>>2)/nBlocksSize)*nBlocksSize:nInLen*3+1>>2,taBytes=new Uint8Array(nOutLen);for(var nMod3,nMod4,nUint24=0,nOutIdx=0,nInIdx=0;nInIdx<nInLen;nInIdx++){nMod4=nInIdx&3;nUint24|=b64ToUint6(sB64Enc.charCodeAt(nInIdx))<<18-6*nMod4;if(nMod4===3||nInLen-nInIdx===1){for(nMod3=0;nMod3<3&&nOutIdx<nOutLen;nMod3++,nOutIdx++){taBytes[nOutIdx]=nUint24>>>(16>>>nMod3&24)&255;}
nUint24=0;}}
return taBytes;}
(function() {
var canvas = $("canvas").get(0);
var context = canvas.getContext('2d');
var framesLength = pixiv.context.ugokuIllustData.frames.length;
var delay = pixiv.context.ugokuIllustData.frames[0].delay;
var encoder = window.gifencoder = new GIFEncoder();
encoder.setRepeat(0);
encoder.setDelay(delay);
encoder.start();
console.log("start GIFEncoder", "frames" + framesLength, "delay:" + delay);
var i = 0;
function addFrame() {
if (i < framesLength) {
encoder.addFrame(context);
setTimeout(addFrame, delay);
} else {
encoder.finish();
console.log("finish GIFEncoder");
var binary_gif = encoder.stream().getData();
var b64Str = encode64(binary_gif);
var buffer = base64DecToArr(b64Str);
var blob = new Blob([buffer.buffer], {
type: "image/gif"
});
var url = URL.createObjectURL(blob);
$("._ugoku-illust-player-container.ready").append($("<img/>", {
src: url
}));
}
i++;
}
addFrame();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment