Loading js/elphel.js +51 −0 Original line number Original line Diff line number Diff line Loading @@ -105,6 +105,55 @@ var Elphel = { // Pixel manipulation // Pixel manipulation Pixels:{ Pixels:{ reorderBlocksJP4_lowres: function(pixels,width,height,format="JP4",mosaic=[["Gr","R"],["B" ,"Gb"]],lowres){ var oPixels = new Uint8Array(pixels.length/4); // check if ((lowres!=1)&&(lowres!=2)&&(lowres!=4)&&(lowres!=8)){ lowres = 4; } var K0 = 3-Math.log(lowres)/Math.log(2); var K1 = 1<<K0; var K2 = K1-1; for(var y=0;y<height/2;y++){ for(var x=0;x<width/2;x++){ offset = y*width/2+x; y0 = 2*K1*(y>>K0)+(y&K2); x0 = 4*K1*(x>>K0)+(x&K2); if (x0>=width){ x0 = x0 - width; y0 = y0 + K1; } offset0 = width*y0 + x0; for(var k=0;k<4;k++){ ym = (k>>1)&1; xm = k&1; if (mosaic[ym][xm]=="R") r = pixels[4*(offset0+K1*k)+0]; else if (mosaic[ym][xm]=="Gr") gr = pixels[4*(offset0+K1*k)+0]; else if (mosaic[ym][xm]=="Gb") gb = pixels[4*(offset0+K1*k)+0]; else if (mosaic[ym][xm]=="B") b = pixels[4*(offset0+K1*k)+0]; } g = (gr+gb)>>1; oPixels[4*(offset)+0] = r;//pixels[4*(4*offset+1)+0]; oPixels[4*(offset)+1] = g;//pixels[4*(4*offset+0)+0]; oPixels[4*(offset)+2] = b;//pixels[4*(4*offset+2)+0]; oPixels[4*(offset)+3] = 255; } } return oPixels; }, /** /** * Name: reorderJP4Blocks * Name: reorderJP4Blocks * Description: clear from the function's name * Description: clear from the function's name Loading @@ -130,6 +179,8 @@ var Elphel = { */ */ reorderBlocksJPx: function(pixels,width,height,format="JP4",mosaic=[["Gr","R"],["B" ,"Gb"]],nwd=false){ reorderBlocksJPx: function(pixels,width,height,format="JP4",mosaic=[["Gr","R"],["B" ,"Gb"]],nwd=false){ var nwd2 = true; var t0 = Date.now(); var t0 = Date.now(); // pixels is a long 1-D array with the following structure: // pixels is a long 1-D array with the following structure: Loading js/jquery-jp4.js +92 −21 Original line number Original line Diff line number Diff line Loading @@ -34,12 +34,14 @@ var obj = this; var obj = this; var settings = $.extend({ var settings = $.extend({ ip: "", port: "", port: "", image: "test.jp4", image: "test.jp4", refresh: false, refresh: false, mosaic: [["Gr","R"],["B" ,"Gb"]], mosaic: [["Gr","R"],["B" ,"Gb"]], fast: false, fast: false, precise: false, precise: false, lowres: 0, // valid values: 1,2,4,8. 0 to disable width: 600, width: 600, channel: "all", channel: "all", diff: false, diff: false, Loading @@ -51,6 +53,10 @@ } } },options); },options); // working time var T0; var TX; var BAYER = settings.mosaic; var BAYER = settings.mosaic; var FLIPV = 0; var FLIPV = 0; var FLIPH = 0; var FLIPH = 0; Loading @@ -64,6 +70,13 @@ // hide working canvas // hide working canvas cnv_working.css({display:"none"}); cnv_working.css({display:"none"}); /* cnv_working.css({ position:"absolute", top: "500px", left: "500px" }); */ elem.append(cnv_working); elem.append(cnv_working); elem.append(cnv_display); elem.append(cnv_display); Loading @@ -81,34 +94,66 @@ var http = new XMLHttpRequest(); var http = new XMLHttpRequest(); var rq = ""; var rq = ""; if (settings.port!=""){ if (settings.port!=""&&settings.ip!=""){ rq = "get-image.php?port="+settings.port+"&rel=bimg&ts="+Date.now(); rq = "get-image.php?ip="+settings.ip+"&port="+settings.port+"&rel=bimg&ts="+Date.now(); settings.refresh = true; //rq = "get-image.php?ip="+settings.ip+"&port="+settings.port+"&rel=img&ts="+Date.now(); //settings.refresh = true; }else{ }else{ rq = settings.image; rq = settings.image; } } http.open("GET", rq, true); http.open("GET", rq, true); TX = Date.now(); T0 = Date.now(); http.responseType = "blob"; http.responseType = "blob"; http.onload = function(e) { http.onload = function(e) { console.log("#"+elem.attr("id")+", file load time: "+(Date.now()-TX)/1000+" s"); TX = Date.now(); if (this.status === 200) { if (this.status === 200) { var heavyImage = new Image(); var heavyImage = new Image(); heavyImage.onload = function(){ heavyImage.onload = function(){ EXIF.getData(this, function() { EXIF.getData(this, function() { var cnv_w; var cnv_h; if (settings.lowres!=0){ cnv_w = this.width/settings.lowres; cnv_h = this.height/settings.lowres; }else{ cnv_w = this.width; cnv_h = this.height; } //update canvas size //update canvas size canvas.attr("width",this.width); canvas.attr("width",cnv_w); canvas.attr("height",this.height); canvas.attr("height",cnv_h); parseEXIFMakerNote(this); parseEXIFMakerNote(this); canvas.drawImage({ canvas.drawImage({ x:0, y:0, x:0, y:0, source: heavyImage, source: this, width: cnv_w, height: cnv_h, //source: heavyImage, load: redraw, load: redraw, sx: 0, sy: 0, sWidth: this.width, sHeight: this.height, //scale: scale, fromCenter: false fromCenter: false }); }); }); }); }; }; heavyImage.src = URL.createObjectURL(http.response); heavyImage.src = URL.createObjectURL(http.response); } } Loading @@ -118,15 +163,28 @@ } } var T0; function redraw(){ function redraw(){ //for debugging //IMAGE_FORMAT="JPEG"; $(this).draw({ $(this).draw({ fn: function(ctx){ fn: function(ctx){ T0 = Date.now(); console.log("#"+elem.attr("id")+", raw image drawn time: "+(Date.now()-TX)/1000+" s"); TX = Date.now(); if (IMAGE_FORMAT=="JPEG"){ // if JP4/JP46 it will work through webworker and exit later on workers message Elphel.Canvas.drawScaled(cnv_working,cnv_display,settings.width); console.log("#"+elem.attr("id")+", Total time: "+(Date.now()-T0)/1000+" s"); $(this).trigger("canvas_ready"); }else if ((IMAGE_FORMAT=="JP4")||(IMAGE_FORMAT=="JP46")){ if ((IMAGE_FORMAT=="JP4")||(IMAGE_FORMAT=="JP46")){ if (settings.fast){ if (settings.fast){ quickestPreview(ctx); quickestPreview(ctx); }/*else{ }/*else{ Loading Loading @@ -165,12 +223,9 @@ //saturation(ctx,SATURATION[0]); //saturation(ctx,SATURATION[0]); } } // too early //console.log("#"+elem.attr("id")+", time: "+(Date.now()-t0)/1000+" s"); //console.log("#"+elem.attr("id")+", time: "+(Date.now()-t0)/1000+" s"); // custom event //$(this).trigger("canvas_ready"); //console.log($(this)); if (settings.refresh) get_image(); if (settings.refresh) get_image(); } } }); }); Loading @@ -180,11 +235,21 @@ var worker = new Worker('js/webworker.js'); var worker = new Worker('js/webworker.js'); TX = Date.now(); //ctx.canvas.width = ctx.canvas.width/2; //ctx.canvas.height = ctx.canvas.height/2; //ctx.canvas.style.width = ctx.canvas.style.width/4; //ctx.canvas.style.height = ctx.canvas.style.height/4; var width = ctx.canvas.width; var width = ctx.canvas.width; var height = ctx.canvas.height; var height = ctx.canvas.height; var image = ctx.getImageData(0,0,width,height); var image = ctx.getImageData(0,0,width,height); var pixels = image.data; var pixels = image.data; console.log("#"+elem.attr("id")+", data from canvas for webworker time: "+(Date.now()-TX)/1000+" s"); TX = Date.now(); worker.postMessage({ worker.postMessage({ mosaic: settings.mosaic, mosaic: settings.mosaic, format: IMAGE_FORMAT, format: IMAGE_FORMAT, Loading @@ -195,10 +260,12 @@ fast: settings.fast, fast: settings.fast, channel: settings.channel, channel: settings.channel, diff: settings.diff, diff: settings.diff, ndvi: settings.ndvi ndvi: settings.ndvi, lowres: settings.lowres }, }, },[pixels.buffer]); },[pixels.buffer]); worker.onmessage = function(e){ worker.onmessage = function(e){ var pixels = new Uint8Array(e.data.pixels); var pixels = new Uint8Array(e.data.pixels); Loading @@ -207,10 +274,14 @@ var width = e.data.width; var width = e.data.width; var height = e.data.height; var height = e.data.height; console.log("#"+elem.attr("id")+", worker time: "+(Date.now()-TX)/1000+" s"); TX = Date.now(); Elphel.Canvas.putImageData(working_context,pixels,width,height); Elphel.Canvas.putImageData(working_context,pixels,width,height); Elphel.Canvas.drawScaled(cnv_working,cnv_display,settings.width); Elphel.Canvas.drawScaled(cnv_working,cnv_display,settings.width); console.log("#"+elem.attr("id")+", time: "+(Date.now()-T0)/1000+" s"); // report time console.log("#"+elem.attr("id")+", Total time: "+(Date.now()-T0)/1000+" s"); //trigger here //trigger here cnv_working.trigger("canvas_ready"); cnv_working.trigger("canvas_ready"); } } Loading js/panorama_preview.js +1 −1 Original line number Original line Diff line number Diff line Loading @@ -208,7 +208,7 @@ function image_full_name(folder, image_number) { for (var i=0;i<8;i++){ for (var i=0;i<8;i++){ remove_hidden_div(i); remove_hidden_div(i); append_hidden_div(i); append_hidden_div(i); $("#div_"+i).jp4({image:image_name[cams[i].index-1],width:200,fast:true}); $("#div_"+i).jp4({image:image_name[cams[i].index-1],width:200,fast:true,lowres:4}); } } } } }); }); Loading js/webworker.js +9 −4 Original line number Original line Diff line number Diff line Loading @@ -12,13 +12,18 @@ self.onmessage = function(e) { var Pixels = new Uint8Array(e.data.pixels); var Pixels = new Uint8Array(e.data.pixels); if (settings.lowres==0){ var reorderedPixels = Elphel.Pixels.reorderBlocksJPx(Pixels,W,H,Format,Mosaic,settings.fast); var reorderedPixels = Elphel.Pixels.reorderBlocksJPx(Pixels,W,H,Format,Mosaic,settings.fast); //reorder first then downscale //reorder first then downscale if (settings.fast){ if (settings.fast){ W = W/2; W = W/2; H = H/2; H = H/2; } } }else{ var reorderedPixels = Elphel.Pixels.reorderBlocksJP4_lowres(Pixels,W,H,Format,Mosaic,settings.lowres); W = W/2; H = H/2; } Elphel.Pixels.applySaturation(reorderedPixels,W,H,2); Elphel.Pixels.applySaturation(reorderedPixels,W,H,2); Loading Loading
js/elphel.js +51 −0 Original line number Original line Diff line number Diff line Loading @@ -105,6 +105,55 @@ var Elphel = { // Pixel manipulation // Pixel manipulation Pixels:{ Pixels:{ reorderBlocksJP4_lowres: function(pixels,width,height,format="JP4",mosaic=[["Gr","R"],["B" ,"Gb"]],lowres){ var oPixels = new Uint8Array(pixels.length/4); // check if ((lowres!=1)&&(lowres!=2)&&(lowres!=4)&&(lowres!=8)){ lowres = 4; } var K0 = 3-Math.log(lowres)/Math.log(2); var K1 = 1<<K0; var K2 = K1-1; for(var y=0;y<height/2;y++){ for(var x=0;x<width/2;x++){ offset = y*width/2+x; y0 = 2*K1*(y>>K0)+(y&K2); x0 = 4*K1*(x>>K0)+(x&K2); if (x0>=width){ x0 = x0 - width; y0 = y0 + K1; } offset0 = width*y0 + x0; for(var k=0;k<4;k++){ ym = (k>>1)&1; xm = k&1; if (mosaic[ym][xm]=="R") r = pixels[4*(offset0+K1*k)+0]; else if (mosaic[ym][xm]=="Gr") gr = pixels[4*(offset0+K1*k)+0]; else if (mosaic[ym][xm]=="Gb") gb = pixels[4*(offset0+K1*k)+0]; else if (mosaic[ym][xm]=="B") b = pixels[4*(offset0+K1*k)+0]; } g = (gr+gb)>>1; oPixels[4*(offset)+0] = r;//pixels[4*(4*offset+1)+0]; oPixels[4*(offset)+1] = g;//pixels[4*(4*offset+0)+0]; oPixels[4*(offset)+2] = b;//pixels[4*(4*offset+2)+0]; oPixels[4*(offset)+3] = 255; } } return oPixels; }, /** /** * Name: reorderJP4Blocks * Name: reorderJP4Blocks * Description: clear from the function's name * Description: clear from the function's name Loading @@ -130,6 +179,8 @@ var Elphel = { */ */ reorderBlocksJPx: function(pixels,width,height,format="JP4",mosaic=[["Gr","R"],["B" ,"Gb"]],nwd=false){ reorderBlocksJPx: function(pixels,width,height,format="JP4",mosaic=[["Gr","R"],["B" ,"Gb"]],nwd=false){ var nwd2 = true; var t0 = Date.now(); var t0 = Date.now(); // pixels is a long 1-D array with the following structure: // pixels is a long 1-D array with the following structure: Loading
js/jquery-jp4.js +92 −21 Original line number Original line Diff line number Diff line Loading @@ -34,12 +34,14 @@ var obj = this; var obj = this; var settings = $.extend({ var settings = $.extend({ ip: "", port: "", port: "", image: "test.jp4", image: "test.jp4", refresh: false, refresh: false, mosaic: [["Gr","R"],["B" ,"Gb"]], mosaic: [["Gr","R"],["B" ,"Gb"]], fast: false, fast: false, precise: false, precise: false, lowres: 0, // valid values: 1,2,4,8. 0 to disable width: 600, width: 600, channel: "all", channel: "all", diff: false, diff: false, Loading @@ -51,6 +53,10 @@ } } },options); },options); // working time var T0; var TX; var BAYER = settings.mosaic; var BAYER = settings.mosaic; var FLIPV = 0; var FLIPV = 0; var FLIPH = 0; var FLIPH = 0; Loading @@ -64,6 +70,13 @@ // hide working canvas // hide working canvas cnv_working.css({display:"none"}); cnv_working.css({display:"none"}); /* cnv_working.css({ position:"absolute", top: "500px", left: "500px" }); */ elem.append(cnv_working); elem.append(cnv_working); elem.append(cnv_display); elem.append(cnv_display); Loading @@ -81,34 +94,66 @@ var http = new XMLHttpRequest(); var http = new XMLHttpRequest(); var rq = ""; var rq = ""; if (settings.port!=""){ if (settings.port!=""&&settings.ip!=""){ rq = "get-image.php?port="+settings.port+"&rel=bimg&ts="+Date.now(); rq = "get-image.php?ip="+settings.ip+"&port="+settings.port+"&rel=bimg&ts="+Date.now(); settings.refresh = true; //rq = "get-image.php?ip="+settings.ip+"&port="+settings.port+"&rel=img&ts="+Date.now(); //settings.refresh = true; }else{ }else{ rq = settings.image; rq = settings.image; } } http.open("GET", rq, true); http.open("GET", rq, true); TX = Date.now(); T0 = Date.now(); http.responseType = "blob"; http.responseType = "blob"; http.onload = function(e) { http.onload = function(e) { console.log("#"+elem.attr("id")+", file load time: "+(Date.now()-TX)/1000+" s"); TX = Date.now(); if (this.status === 200) { if (this.status === 200) { var heavyImage = new Image(); var heavyImage = new Image(); heavyImage.onload = function(){ heavyImage.onload = function(){ EXIF.getData(this, function() { EXIF.getData(this, function() { var cnv_w; var cnv_h; if (settings.lowres!=0){ cnv_w = this.width/settings.lowres; cnv_h = this.height/settings.lowres; }else{ cnv_w = this.width; cnv_h = this.height; } //update canvas size //update canvas size canvas.attr("width",this.width); canvas.attr("width",cnv_w); canvas.attr("height",this.height); canvas.attr("height",cnv_h); parseEXIFMakerNote(this); parseEXIFMakerNote(this); canvas.drawImage({ canvas.drawImage({ x:0, y:0, x:0, y:0, source: heavyImage, source: this, width: cnv_w, height: cnv_h, //source: heavyImage, load: redraw, load: redraw, sx: 0, sy: 0, sWidth: this.width, sHeight: this.height, //scale: scale, fromCenter: false fromCenter: false }); }); }); }); }; }; heavyImage.src = URL.createObjectURL(http.response); heavyImage.src = URL.createObjectURL(http.response); } } Loading @@ -118,15 +163,28 @@ } } var T0; function redraw(){ function redraw(){ //for debugging //IMAGE_FORMAT="JPEG"; $(this).draw({ $(this).draw({ fn: function(ctx){ fn: function(ctx){ T0 = Date.now(); console.log("#"+elem.attr("id")+", raw image drawn time: "+(Date.now()-TX)/1000+" s"); TX = Date.now(); if (IMAGE_FORMAT=="JPEG"){ // if JP4/JP46 it will work through webworker and exit later on workers message Elphel.Canvas.drawScaled(cnv_working,cnv_display,settings.width); console.log("#"+elem.attr("id")+", Total time: "+(Date.now()-T0)/1000+" s"); $(this).trigger("canvas_ready"); }else if ((IMAGE_FORMAT=="JP4")||(IMAGE_FORMAT=="JP46")){ if ((IMAGE_FORMAT=="JP4")||(IMAGE_FORMAT=="JP46")){ if (settings.fast){ if (settings.fast){ quickestPreview(ctx); quickestPreview(ctx); }/*else{ }/*else{ Loading Loading @@ -165,12 +223,9 @@ //saturation(ctx,SATURATION[0]); //saturation(ctx,SATURATION[0]); } } // too early //console.log("#"+elem.attr("id")+", time: "+(Date.now()-t0)/1000+" s"); //console.log("#"+elem.attr("id")+", time: "+(Date.now()-t0)/1000+" s"); // custom event //$(this).trigger("canvas_ready"); //console.log($(this)); if (settings.refresh) get_image(); if (settings.refresh) get_image(); } } }); }); Loading @@ -180,11 +235,21 @@ var worker = new Worker('js/webworker.js'); var worker = new Worker('js/webworker.js'); TX = Date.now(); //ctx.canvas.width = ctx.canvas.width/2; //ctx.canvas.height = ctx.canvas.height/2; //ctx.canvas.style.width = ctx.canvas.style.width/4; //ctx.canvas.style.height = ctx.canvas.style.height/4; var width = ctx.canvas.width; var width = ctx.canvas.width; var height = ctx.canvas.height; var height = ctx.canvas.height; var image = ctx.getImageData(0,0,width,height); var image = ctx.getImageData(0,0,width,height); var pixels = image.data; var pixels = image.data; console.log("#"+elem.attr("id")+", data from canvas for webworker time: "+(Date.now()-TX)/1000+" s"); TX = Date.now(); worker.postMessage({ worker.postMessage({ mosaic: settings.mosaic, mosaic: settings.mosaic, format: IMAGE_FORMAT, format: IMAGE_FORMAT, Loading @@ -195,10 +260,12 @@ fast: settings.fast, fast: settings.fast, channel: settings.channel, channel: settings.channel, diff: settings.diff, diff: settings.diff, ndvi: settings.ndvi ndvi: settings.ndvi, lowres: settings.lowres }, }, },[pixels.buffer]); },[pixels.buffer]); worker.onmessage = function(e){ worker.onmessage = function(e){ var pixels = new Uint8Array(e.data.pixels); var pixels = new Uint8Array(e.data.pixels); Loading @@ -207,10 +274,14 @@ var width = e.data.width; var width = e.data.width; var height = e.data.height; var height = e.data.height; console.log("#"+elem.attr("id")+", worker time: "+(Date.now()-TX)/1000+" s"); TX = Date.now(); Elphel.Canvas.putImageData(working_context,pixels,width,height); Elphel.Canvas.putImageData(working_context,pixels,width,height); Elphel.Canvas.drawScaled(cnv_working,cnv_display,settings.width); Elphel.Canvas.drawScaled(cnv_working,cnv_display,settings.width); console.log("#"+elem.attr("id")+", time: "+(Date.now()-T0)/1000+" s"); // report time console.log("#"+elem.attr("id")+", Total time: "+(Date.now()-T0)/1000+" s"); //trigger here //trigger here cnv_working.trigger("canvas_ready"); cnv_working.trigger("canvas_ready"); } } Loading
js/panorama_preview.js +1 −1 Original line number Original line Diff line number Diff line Loading @@ -208,7 +208,7 @@ function image_full_name(folder, image_number) { for (var i=0;i<8;i++){ for (var i=0;i<8;i++){ remove_hidden_div(i); remove_hidden_div(i); append_hidden_div(i); append_hidden_div(i); $("#div_"+i).jp4({image:image_name[cams[i].index-1],width:200,fast:true}); $("#div_"+i).jp4({image:image_name[cams[i].index-1],width:200,fast:true,lowres:4}); } } } } }); }); Loading
js/webworker.js +9 −4 Original line number Original line Diff line number Diff line Loading @@ -12,13 +12,18 @@ self.onmessage = function(e) { var Pixels = new Uint8Array(e.data.pixels); var Pixels = new Uint8Array(e.data.pixels); if (settings.lowres==0){ var reorderedPixels = Elphel.Pixels.reorderBlocksJPx(Pixels,W,H,Format,Mosaic,settings.fast); var reorderedPixels = Elphel.Pixels.reorderBlocksJPx(Pixels,W,H,Format,Mosaic,settings.fast); //reorder first then downscale //reorder first then downscale if (settings.fast){ if (settings.fast){ W = W/2; W = W/2; H = H/2; H = H/2; } } }else{ var reorderedPixels = Elphel.Pixels.reorderBlocksJP4_lowres(Pixels,W,H,Format,Mosaic,settings.lowres); W = W/2; H = H/2; } Elphel.Pixels.applySaturation(reorderedPixels,W,H,2); Elphel.Pixels.applySaturation(reorderedPixels,W,H,2); Loading