From 53ab0dde73a645cf6db54c0f9a190440e2d58e05 Mon Sep 17 00:00:00 2001 From: Kai Philipp Date: Fri, 20 Dec 2013 11:40:54 +0100 Subject: [PATCH 1/2] q4z1\'s contributions --- .gitignore | 1 + index.html | 131 ++++++- jquery/css/prettyLoader.css | 1 + jquery/images/prettyLoader/ajax-loader.gif | Bin 0 -> 1849 bytes jquery/images/prettyLoader/prettyLoader.gif | Bin 0 -> 107 bytes jquery/images/prettyLoader/prettyLoader.png | Bin 0 -> 707 bytes jquery/js/jquery.prettyLoader.js | 11 + js/app.js | 188 ++++++++-- js/canvaspainter.js | 20 +- js/glpainter.js | 230 ++++++++++-- js/presentation.js | 49 ++- js/shaders.js | 151 +++++++- js/tools.js | 384 +++++++++++++++++--- main.css | 48 ++- 14 files changed, 1065 insertions(+), 149 deletions(-) create mode 100644 .gitignore create mode 100755 jquery/css/prettyLoader.css create mode 100755 jquery/images/prettyLoader/ajax-loader.gif create mode 100755 jquery/images/prettyLoader/prettyLoader.gif create mode 100755 jquery/images/prettyLoader/prettyLoader.png create mode 100755 jquery/js/jquery.prettyLoader.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..06a2fa6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.komodo* diff --git a/index.html b/index.html index 3a19730..e19eb16 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,7 @@ DICOM + @@ -12,6 +13,7 @@ + @@ -41,7 +43,7 @@ return; app.curr_file_idx = i; app.draw_image(); - setTimeout((function(a, b) { + setTimeout((function(a, b) { return function() { testscroll(a, b); }})(i+1, len), 0); @@ -50,6 +52,16 @@ $(document).ready(function() { + // @XXX: prettyLoader + $.prettyLoader({ + animation_speed: 'fast', /* fast/normal/slow/integer */ + bind_to_ajax: true, /* true/false */ + delay: false, /* false OR time in milliseconds (ms) */ + loader: 'jquery/images/prettyLoader/ajax-loader.gif', /* Path to your loader gif */ + offset_top: 13, /* integer */ + offset_left: 10 /* integer */ + }); + app.init(); $("input[type=file]").change(function(evt) { //app.load_files(evt); @@ -65,15 +77,80 @@ // Setup tools for(tool in tools) { var button = $("
").addClass("tool-button").text(tool); + if (tool == "Brigthness/Contrast") button.css("width", "120px"); $("#button-bar-horz").prepend(button); $(button).click(function() { $(this).parent().find("div").removeClass("butt-selected"); $(this).addClass("butt-selected"); - app.activate_tool(tool); + app.activate_tool(this.innerHTML); }); } - $("#slider").slider(); + $("#slider_slices").slider(); + + + $("#zoom_slider").slider + ({ + range: "min", + value: 100, + min: 1, + max: 1000, + slide: function( event, ui ){ app.set_scale(ui.value/100);} + }); + + $("#w_slider").slider + ({ + range: "min", + value: 4096, + min: 0, + max: 10000, + slide: function( event, ui ) + { + wl = app.get_windowing(); + app.set_windowing(wl[0], ui.value, 0); + app.draw_image(); + } + }); + + $("#l_slider").slider + ({ + range: "min", + value: 2047, + min: 0, + max: 5000, + slide: function( event, ui ) + { + wl = app.get_windowing(); + app.set_windowing(ui.value, wl[1], 0); + app.draw_image(); + } + }); + + $("#b_slider").slider + ({ + range: "min", + value: 0, + min: -192, + max: 192, + slide: function( event, ui ) + { + app.set_brightness(ui.value); + app.draw_image(); + } + }); + + $("#c_slider").slider + ({ + range: "min", + value: 1000, + min: 0, + max: 2000, + slide: function( event, ui ) + { + app.set_contrast(ui.value); + app.draw_image(); + } + }); $("button").button(); @@ -154,7 +231,8 @@ */ $("#butt-reset").click(function() { - app.reset_levels(); + //app.reset_levels(); + app.reset_all(); }); $("#clut-select").change(function() { app.set_clut($(this).val()); @@ -208,10 +286,47 @@

Viewer

Reset
- -
-
+
+ + + + + +
+
+
+ + + + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ +
+
+
@@ -228,7 +343,7 @@

Viewer

PACS:
-
+
diff --git a/jquery/css/prettyLoader.css b/jquery/css/prettyLoader.css new file mode 100755 index 0000000..1e89eb3 --- /dev/null +++ b/jquery/css/prettyLoader.css @@ -0,0 +1 @@ +.prettyLoader{background: url(../images/prettyLoader/prettyLoader.png) top left no-repeat;height:30px;position:absolute;width:30px;z-index:30000;}.prettyLoader img{display:block;margin:7px 0 0 7px;}.pl_ie6{background-image: url(../images/prettyLoader/prettyLoader.gif);} \ No newline at end of file diff --git a/jquery/images/prettyLoader/ajax-loader.gif b/jquery/images/prettyLoader/ajax-loader.gif new file mode 100755 index 0000000000000000000000000000000000000000..d42f72c723644bbf8cf8d6e1b7ff0bea7ddd305a GIT binary patch literal 1849 zcma*odr%wI9tZGc_iT2vk7P+x3@LU(2yGIQCcHvgYTblq0THkTesI znR7n#{hi;OjP2?A&1ME-pkE;9;lqaz1T8KudOV)_`T6wp^p=(uf2Fv%SSFK=kB@u3 zUZGGpJUk2l(CKv5)z$vpzrP~?FHUK&nD<(COPZ{Et0m?db93z;^X^U7=d1QWkq-bw z_z#PGNam*Pcq+w^mln54i-h<~s=yrqB!o6eBrwd4{B{&hHR9I{{bQLC?)mG!al!d3 z<_YADRELlGj+H!fNocrRe7`?$gk5?^y3^@6pC85jwesu>G6*{Wrto)mL5D?z)j-L++&!SNH!MDuhyZ1*)jGIdEgHH>qdP6}DTp>kJ!bZd!oke!Q0J5vRHHSl&=?=ft+HzcfBB?ZKg#rgtngf(C zDL)0I;%QR6Z_49x&crpS#vVCUpEoP)gxevZsOEytw5Vq|*bf39%i#K5VVMGzL^=13 zR-}G|UaU(m68*HWc{(R=BrQG$CK$N`HcDv@S=IAWm(o~Np>ZF8X|_V%3_!1*u`vm}?t+-#K2Qs= zlXouK&f(YJG|lD7kLqye?NcYji#s*HOSm|xQ~{R)Ao3VZxwQ7l4$VQO;kkhWM?7Tq zV7I5-(5BO!(yinIf+@AjEfNKCk>b~u*83@)>qu(a3nA*y_1a7za7?y8mYaN9Z=br4iilUPLeBE8>z7SjUY!R@qdmA$~nkLiZ z9qy{OsKf4~y1^q+D*!YY&=vr^tMUUJQrx*Do>dYDlPO!l`DoZR5vApf95=i4Lz;yXc(}m~6Zh#oS@fHF;-MHT+t;8_YoNLuk zSUE;16g_GThjJ{n2e=qnXWb70jIOhk#;lMy!K4=hr0tBKfB(rz4e z+1U)aJZHl#TYU{%(($JI!F!<+%Jp+Jdk!#Y(|CzO!nka;h@9x_wBI_{i{tgbHY(SI zVOYV2N)E%tOc-CGkW(0fy>Or+s~>c2t0?1P8+jRZNqDzxRf7dRy(%%W_#a<6{e3caEW8DdD|KsdZBw z(K6nRmw&K{D1uvtp&1a;%;nPiAvOlI0*Zq9*kdsS7JEd^O*1FLwTe{>9&A}oMlrlF z`pQPbaQ2zQZ_j_#qk8qy|9IetJFQG!>l{9_AvsafGtVRnQr)xR?bImN4qo-#?gP`}S)0UYaWY9t`6HQwY4B_($TWNu`l?!*nIBy_|7=pQc9cnFU zs%%oO^oje|8ddh7^1-E9_|T~KBxydL{KcW06CqFQ?Ym3~cb^|wPx?lUyCBD|_nRZU zsA}@ctKd0_^(q#G?{G;+$w=8-md|N>W6e5@3AT19SLRCCSyG z=oV%uMus5!Ry9PhrZMnpmb0lXJuACSOl2|krLXzwsrVsNe(8N);u`z?E#W-RKNi9E z;z;dGgCSKfqEhya^?xWt|DBmvWexQ%SfTtu(C0Mdv9@(g3WttPh3GsE1Niv~Ituk; zXltbvX7Jn^Z4>QMtd0~JELrW+CaT^$N~khm@~tceYLLGjk=3uK@XnOQ1!btG^Pus9 zYDnDM@%;wTR-(h+ec@l>g6c`Cs7=j$FkqTfajDLuzmAAh_qHK0!$~G+eL?P46^V2( gTVr?dnQ{(H{Ie1a9NS3OKPMyDfF?Qc5iPGj047fkWdHyG literal 0 HcmV?d00001 diff --git a/jquery/images/prettyLoader/prettyLoader.gif b/jquery/images/prettyLoader/prettyLoader.gif new file mode 100755 index 0000000000000000000000000000000000000000..daeb7f6364c9bc45d7b1ac47f9a71883529d1981 GIT binary patch literal 107 zcmV-x0F?hnNk%w1VIBY;0Du7i|Ns90001HR1OWg50RSuj0000U03HAU0z!GiHlXOeLXH N$5VpMYPZ?~06T+aDZT&z literal 0 HcmV?d00001 diff --git a/jquery/images/prettyLoader/prettyLoader.png b/jquery/images/prettyLoader/prettyLoader.png new file mode 100755 index 0000000000000000000000000000000000000000..dba86153af30ed2697c0e32a9c1c32cf46f4a245 GIT binary patch literal 707 zcmV;!0zCbRP)%tGP&Y7BFI%iJF!Tql|>+(ja}N5DFgW{ENlWc@d`r-cw8YNO^SfUkwPRn!?}r< zWX3n^d-B*KUS!uo?!k}Uon7YJH#;-?Jz@O{fk%l%fDMG&EZ?*K(CmB(C_FCMwWj9; z>&S>iku4<3USgFf7uP5>2QH8wc)g$(AYs$-CU6aiAr4?;`-U&;RY6%Au_^E!ae*0$ zN3g>viX?!YOeS-uUa!AMr_=kkZEtI>g|$WqA@q1WK5e(#A4;XtJ7_vX9r_$5doQDH z;2v;LsZ?H1CX+8Zpco7WA9K0fGw3@5+{V!~3423&%iJgw3eRV=*|`oly4~&(^nVDX z&4^;M-td}iA9gyOw>qRKm&>m}V-J(GC7aE*`KDG#kaI2McT z@)aU+Ie9Oz?(AJBlv0v!N?cf4AqFNziHXZ>g+U7oE9@*+#g*`t@c%8W!xS?AXl{Mz z=d6%_C9EYgWkfhbE2UzdOOdeWkzCh33riSW%~v#j3ld&p!?fS;pMIMzc4k z&uUEGP2fQ`n|&Ij-=b)>T5q8LN5Fj`N!G`hfa}0rV82)_z8sB4r$LGKdcF6lRO*RI z3~i6`coD&^5BjfUJRaYvR;!QqAQFkh4f7Mfj7cyv*I*{na5((jY&MT;wc01R^$j^E zbI%PuRS*tZP#Zl`bPYqV*($j}L+_%YpYqA&FJY*nAR>tLl{0)return;scrollPos=_getScroll();$('
').addClass('prettyLoader').addClass('prettyLoader_'+settings.theme).appendTo('body').hide();if($.support.msie&&$.support.version==6) +$('.prettyLoader').addClass('pl_ie6');$('').attr('src',settings.loader).appendTo('.prettyLoader');$('.prettyLoader').fadeIn(settings.animation_speed);$(document).bind('click',$.prettyLoader.positionLoader);$(document).bind('mousemove',$.prettyLoader.positionLoader);$(window).scroll(function(){scrollPos=_getScroll();$(document).triggerHandler('mousemove');});delay=(delay)?delay:settings.delay;if(delay){setTimeout(function(){$.prettyLoader.hide()},delay);}};$.prettyLoader.hide=function(){$(document).unbind('click',$.prettyLoader.positionLoader);$(document).unbind('mousemove',$.prettyLoader.positionLoader);$(window).unbind('scroll');$('.prettyLoader').fadeOut(settings.animation_speed,function(){$(this).remove();});};function _getScroll(){if(self.pageYOffset){return{scrollTop:self.pageYOffset,scrollLeft:self.pageXOffset};}else if(document.documentElement&&document.documentElement.scrollTop){return{scrollTop:document.documentElement.scrollTop,scrollLeft:document.documentElement.scrollLeft};}else if(document.body){return{scrollTop:document.body.scrollTop,scrollLeft:document.body.scrollLeft};};};return this;};})(jQuery); diff --git a/js/app.js b/js/app.js index bc21a5f..d6f527b 100644 --- a/js/app.js +++ b/js/app.js @@ -21,7 +21,7 @@ function log_element(elem_repr) { this.i++; var elem_div = $("
").html(elem_repr); if(this.i % 2 == 0) - elem_div.addClass("even"); + elem_div.addClass("even"); $("#dicomheader").append(elem_div); } @@ -44,6 +44,14 @@ function DcmApp(viewareaid) { this.curr_clut_r = ClutManager.r('Plain'); this.curr_clut_g = ClutManager.g('Plain'); this.curr_clut_b = ClutManager.b('Plain'); + + // @XXX: additional variables + this.pixel_spacing = false; + this.unit = "mm"; + this.mlength = 0; + this.blured = false; + this.sharpen = false; + this.angle = 0; } DcmApp.prototype.load_files = function(files) @@ -56,7 +64,7 @@ DcmApp.prototype.load_files = function(files) for(var i=0;i this.files.length - 1) return; @@ -279,18 +343,72 @@ DcmApp.prototype.fill_metadata_table = function() { fill_metadata_table(this.files[this.curr_file_idx]); } -DcmApp.prototype.activate_tool = function(tool_identifier) { +DcmApp.prototype.activate_tool = function(tool_identifier) { + //this.curr_tool = new tools[tool_identifier](this); + //this.curr_tool.set_file(this.files[this.curr_file_idx]); + if (tool_identifier == "Sharpen") + { + if (this.sharpen == false) + { + this.sharpen = true; + this.blured = false; + this.set_kernel("sharpen") + } + else + { + this.sharpen = false; + this.blured = false; + this.set_kernel("normal"); + } + } + if (tool_identifier == "Blur") + { + if (this.blured == false) + { + this.blured = true; + this.sharpen = false; + this.set_kernel("gaussianBlur") + } + else + { + this.blured = false; + this.sharpen = false; + this.set_kernel("normal"); + } + } + else + { + if (typeof this.curr_tool.deactivate == "function") + { + this.curr_tool.deactivate(); + } this.curr_tool = new tools[tool_identifier](this); this.curr_tool.set_file(this.files[this.curr_file_idx]); + } } -DcmApp.prototype.reset_levels = function() { +DcmApp.prototype.reset_levels = function() { this.painter.reset_pan(); this.painter.reset_windowing(); this.painter.reset_scale(); this.draw_image(); } +DcmApp.prototype.reset_all = function() { + this.painter.reset_pan(); + this.painter.reset_scale(); + this.painter.reset_windowing(); + this.painter.reset_bc(); + this.set_kernel("normal"); + this.macanvas.width = this.macanvas.width; + $('#w_slider').slider("option", "value", 4096); + $('#l_slider').slider("option", "value", 2047); + $('#c_slider').slider("option", "value", 1000); + $('#b_slider').slider("option", "value", 0); + $('#angle_info').text('0' + ' ' + this.unit); + $('#length_info').text('0 ' + unescape("%B0")); +} + DcmApp.prototype.mousemoveinfo = function(canvas_pos, image_pos) { if (this.files.length <= this.curr_file_idx) { $("#density_info").html(""); @@ -311,12 +429,16 @@ DcmApp.prototype.mousemoveinfo = function(canvas_pos, image_pos) { $("#density").html(""); return; } - + if (coord != undefined) { $("#density_info").html("value(" + coord.map(function(x) {return x.toFixed(1);}) + ") = " + ctval.toFixed(1)); } else { $("#density_info").html("r,c = (" + row + ", " + col + "), val = " + ctval); } + // @XXX: angle and measure length + $('#length_info').text(this.mlength + " " + this.unit); + var angle2 = (this.angle == 0) ? 0 : (360-this.angle); + $('#angle_info').text(this.angle + " " + unescape("%B0") + " / " + angle2 + " " + unescape("%B0")); } DcmApp.prototype.set_clut = function(clutname) { @@ -330,7 +452,7 @@ DcmApp.prototype.refreshmousemoveinfo = function() { this.mousemoveinfo(this.last_mouse_canvas_pos, this.last_mouse_image_pos); } -DcmApp.prototype.update_window_preset_list = function(wls, wws) { +DcmApp.prototype.update_window_preset_list = function(wls, wws) { var optgroup = $("#window-presets").find("optgroup") optgroup.empty(); for(var i=0;i 1.0) intensity = 1.0; + // @XXX: invert MONOCHROME1 + if (invert){ + intensity = 1 - intensity; + } + intensity *= 255.0; var canvas_idx = (col + row*this.file.Columns)*4; diff --git a/js/glpainter.js b/js/glpainter.js index 69938e2..279b0b8 100644 --- a/js/glpainter.js +++ b/js/glpainter.js @@ -12,6 +12,118 @@ var FRAG_SHADER_8 = 0; var FRAG_SHADER_16 = 1; var FRAG_SHADER_RGB_8 = 2; +var FRAG_SHADER_16_MC1 = 3; +var FRAG_SHADER_8_MC1 = 4; + + +// Filter Kernel +var KERNELS = { + normal: [ + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0 + ], + smoothen: [ + 0.0225, 0.0511, 0.0225, + 0.0511, 0.166, 0.0511, + 0.0225, 0.0511, 0.0225 + ], + gaussianBlur: [ + 0.045, 0.122, 0.045, + 0.122, 0.332, 0.122, + 0.045, 0.122, 0.045 + ], + gaussianBlur2: [ + 1.0, 2.0, 1.0, + 2.0, 4.0, 2.0, + 1.0, 2.0, 1.0 + ], + gaussianBlur3: [ + 0.0, 1.0, 0.0, + 1.0, 1.0, 1.0, + 0.0, 1.0, 0.0 + ], + unsharpen: [ + -1.0, -1.0, -1.0, + -1.0, 9.0, -1.0, + -1.0, -1.0, -1.0 + ], + sharpness: [ + 0.0,-1.0, 0.0, + -1.0, 5.0,-1.0, + 0.0,-1.0, 0.0 + ], + sharpen: [ + -1.0, -1.0, -1.0, + -1.0, 16.0, -1.0, + -1.0, -1.0, -1.0 + ], + edgeDetect: [ + -0.125, -0.125, -0.125, + -0.125, 1.0, -0.125, + -0.125, -0.125, -0.125 + ], + edgeDetect2: [ + -1.0, -1.0, -1.0, + -1.0, 8.0, -1.0, + -1.0, -1.0, -1.0 + ], + edgeDetect3: [ + -5.0, 0.0, 0.0, + 0.0, 0.0, 0.0, + 0.0, 0.0, 5.0 + ], + edgeDetect4: [ + -1.0, -1.0, -1.0, + 0.0, 0.0, 0.0, + 1.0, 1.0, 1.0 + ], + edgeDetect5: [ + -1, -1, -1, + 2, 2, 2, + -1, -1, -1 + ], + edgeDetect6: [ + -5, -5, -5, + -5, 39, -5, + -5, -5, -5 + ], + sobelHorizontal: [ + 1, 2, 1, + 0, 0, 0, + -1, -2, -1 + ], + sobelVertical: [ + 1, 0, -1, + 2, 0, -2, + 1, 0, -1 + ], + previtHorizontal: [ + 1, 1, 1, + 0, 0, 0, + -1, -1, -1 + ], + previtVertical: [ + 1, 0, -1, + 1, 0, -1, + 1, 0, -1 + ], + boxBlur: [ + 0.111, 0.111, 0.111, + 0.111, 0.111, 0.111, + 0.111, 0.111, 0.111 + ], + triangleBlur: [ + 0.0625, 0.125, 0.0625, + 0.125, 0.25, 0.125, + 0.0625, 0.125, 0.0625 + ], + emboss: [ + -2, -1, 0, + -1, 1, 1, + 0, 1, 2 + ] + }; function ImageSlice(file, texture, rs, ri, alpha) { this.file = file; @@ -32,8 +144,10 @@ function GLPainter(canvasid) { //this.THE_TEXTURE; this.CLUT_TEXTURE; - this.ww = 200; - this.wl = 40; + //this.ww = 200; + //this.wl = 40; + this.ww = 4096; + this.wl = 2047; this.clut_r; this.clut_g; this.clut_b; @@ -47,6 +161,10 @@ function GLPainter(canvasid) { this.images = []; this.shaderPrograms = {}; this.clut_bar_enabled = false; + + this.br = 0; // brightness + this.c = 1000; // contrast + this.kernel = "normal"; } GLPainter.prototype.fuse_files = function(file1, file2, alpha) { @@ -67,8 +185,8 @@ GLPainter.prototype.fuse_files = function(file1, file2, alpha) { GLPainter.prototype.set_file = function(dcmfile) { this.images = [new ImageSlice(dcmfile, - this.file_to_texture(dcmfile), - dcmfile.RescaleSlope || 1.0, + this.file_to_texture(dcmfile), + dcmfile.RescaleSlope || 1.0, dcmfile.RescaleIntercept || 0.0, 1.0)]; this.rows = dcmfile.Rows; @@ -105,14 +223,14 @@ GLPainter.prototype.file_to_texture = function(dcmfile) { return; } - var texture = this.gl.createTexture(); - this.gl.bindTexture(this.gl.TEXTURE_2D, texture); + var texture = this.gl.createTexture(); + this.gl.bindTexture(this.gl.TEXTURE_2D, texture); this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, true); this.gl.texImage2D(this.gl.TEXTURE_2D, // target 0, // level internalFormat, // internalformat dcmfile.Columns, // width - dcmfile.Rows, // height + dcmfile.Rows, // height 0, // border internalFormat, // format this.gl.UNSIGNED_BYTE, // type @@ -121,7 +239,7 @@ GLPainter.prototype.file_to_texture = function(dcmfile) { this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR); this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE); this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE); - + this.gl.bindTexture(this.gl.TEXTURE_2D, null); return texture; } @@ -156,8 +274,16 @@ GLPainter.prototype.reset_pan = function() { } GLPainter.prototype.reset_windowing = function() { - this.ww = 200; - this.wl = 40; + //this.ww = 200; + //this.wl = 40; + // @XXX: following values worked better for me + this.ww = 4096; + this.wl = 2047; +} + +GLPainter.prototype.reset_bc = function() { + this.br = 0; + this.c = 1000; } GLPainter.prototype.set_cluts = function(clut_r, clut_g, clut_b) { @@ -182,7 +308,7 @@ GLPainter.prototype.set_cluts = function(clut_r, clut_g, clut_b) { 0, // level this.gl.RGB, // internalformat 256, // width - 1, // height + 1, // height 0, // border this.gl.RGB, // format this.gl.UNSIGNED_BYTE, // type @@ -203,14 +329,29 @@ GLPainter.prototype.get_windowing = function() { return [this.wl, this.ww]; } +GLPainter.prototype.set_brightness = function(br) { + this.br = br; + this.draw_image(); +} + +GLPainter.prototype.set_contrast = function(c) { + this.c = c; + this.draw_image(); +} + +GLPainter.prototype.set_kernel = function(kernel) { + this.kernel = kernel; + this.draw_image(); +} + GLPainter.prototype.unproject = function(canvas_pos) { var viewportArray = [ 0, 0, this.gl.viewportWidth, this.gl.viewportHeight ]; - + var projectedPoint = []; var unprojectedPoint = []; - + var flippedmvMatrix = mat4.create(); mat4.identity(flippedmvMatrix); @@ -227,7 +368,7 @@ GLPainter.prototype.unproject = function(canvas_pos) { 0,0,0, flippedmvMatrix, this.pMatrix, viewportArray, projectedPoint); - + var successFar = GLU.unProject( canvas_pos[0], canvas_pos[1], projectedPoint[2], //windowPointX, windowPointY, windowPointZ, flippedmvMatrix, this.pMatrix, @@ -262,7 +403,8 @@ GLPainter.prototype.draw_clut_bar = function() { if(!this.clut_bar_enabled) return; // Draw clut bar - this.gl.viewport(10, 10, 50, this.canvas.height-100); + //this.gl.viewport(10, 10, 50, this.canvas.height-100); + this.gl.viewport(this.canvas.width-60, 10, 50, this.canvas.height-100); var pMatrix = mat4.create(); mat4.perspective(this.fovy, this.gl.viewportWidth / this.gl.viewportHeight, 0.1, 100.0, pMatrix); var mvMatrix = mat4.create(); @@ -319,7 +461,12 @@ GLPainter.prototype.draw_image = function() { var shaderProgram; switch(jQuery.trim(image.file.PhotometricInterpretation)) { case "MONOCHROME1": - // TODO: MONOCHROME1 should use inverse cluts. + if(image.file.BitsStored <= 8) { + shaderProgram = this.shaderPrograms[FRAG_SHADER_8_MC1]; + } else { + shaderProgram = this.shaderPrograms[FRAG_SHADER_16_MC1]; + } + break; case "MONOCHROME2": if(image.file.BitsStored <= 8) { shaderProgram = this.shaderPrograms[FRAG_SHADER_8]; @@ -337,18 +484,18 @@ GLPainter.prototype.draw_image = function() { this.gl.useProgram(shaderProgram); this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.squareVertexPositionBuffer); - this.gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, - this.squareVertexPositionBuffer.itemSize, - this.gl.FLOAT, - false, - 0, + this.gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, + this.squareVertexPositionBuffer.itemSize, + this.gl.FLOAT, + false, + 0, 0); this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.textureCoordBuffer); this.gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, this.textureCoordBuffer.itemSize, this.gl.FLOAT, false, 0, 0); - this.gl.activeTexture(this.gl.TEXTURE0); - this.gl.bindTexture(this.gl.TEXTURE_2D, image.texture); + this.gl.activeTexture(this.gl.TEXTURE0); + this.gl.bindTexture(this.gl.TEXTURE_2D, image.texture); this.gl.uniform1i(shaderProgram.samplerUniform, 0); // Clut texture @@ -410,10 +557,14 @@ GLPainter.prototype.init_shaders = function() { var fragmentShader16 = this.compile_shader(fragment_shader_16, this.gl.FRAGMENT_SHADER); var fragmentShaderRGB8 = this.compile_shader(fragment_shader_rgb_8, this.gl.FRAGMENT_SHADER); var vertexShader = this.compile_shader(vertex_shader, this.gl.VERTEX_SHADER); + var fragmentShader8MC1 = this.compile_shader(fragment_shader_8_mc1, this.gl.FRAGMENT_SHADER); + var fragmentShader16MC1 = this.compile_shader(fragment_shader_16_mc1, this.gl.FRAGMENT_SHADER); this.shaderPrograms[FRAG_SHADER_8] = this.create_shader_program(fragmentShader8, vertexShader); this.shaderPrograms[FRAG_SHADER_16] = this.create_shader_program(fragmentShader16, vertexShader); this.shaderPrograms[FRAG_SHADER_RGB_8] = this.create_shader_program(fragmentShaderRGB8, vertexShader); + this.shaderPrograms[FRAG_SHADER_16_MC1] = this.create_shader_program(fragmentShader16MC1, vertexShader); + this.shaderPrograms[FRAG_SHADER_8_MC1] = this.create_shader_program(fragmentShader8MC1, vertexShader); } GLPainter.prototype.create_shader_program = function(fragshader, vertshader) { @@ -428,8 +579,8 @@ GLPainter.prototype.create_shader_program = function(fragshader, vertshader) { shaderProgram.vertexPositionAttribute = this.gl.getAttribLocation(shaderProgram, "aVertexPosition"); this.gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); - shaderProgram.textureCoordAttribute = this.gl.getAttribLocation(shaderProgram, "aTextureCoord"); - this.gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute); + shaderProgram.textureCoordAttribute = this.gl.getAttribLocation(shaderProgram, "aTextureCoord"); + this.gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute); shaderProgram.pMatrixUniform = this.gl.getUniformLocation(shaderProgram, "uPMatrix"); shaderProgram.mvMatrixUniform = this.gl.getUniformLocation(shaderProgram, "uMVMatrix"); @@ -441,6 +592,9 @@ GLPainter.prototype.create_shader_program = function(fragshader, vertshader) { shaderProgram.riUniform = this.gl.getUniformLocation(shaderProgram, "uRI"); shaderProgram.rsUniform = this.gl.getUniformLocation(shaderProgram, "uRS"); shaderProgram.alphaUniform = this.gl.getUniformLocation(shaderProgram, "uAlpha"); + shaderProgram.brUniform = this.gl.getUniformLocation(shaderProgram, "uBrightness"); + shaderProgram.cUniform = this.gl.getUniformLocation(shaderProgram, "uContrast"); + shaderProgram.krUniform = this.gl.getUniformLocation(shaderProgram, "uKernel[0]"); return shaderProgram; } @@ -459,6 +613,10 @@ GLPainter.prototype.set_window_uniforms = function(shaderProgram, image) { this.gl.uniform1f(shaderProgram.rsUniform, image.rs); this.gl.uniform1f(shaderProgram.riUniform, image.ri); this.gl.uniform1f(shaderProgram.alphaUniform, image.alpha); + this.gl.uniform1f(shaderProgram.brUniform, this.br); + this.gl.uniform1f(shaderProgram.cUniform, this.c); + this.gl.uniform1fv(shaderProgram.krUniform, KERNELS[this.kernel]); + } GLPainter.prototype.init_buffers = function() { @@ -473,18 +631,18 @@ GLPainter.prototype.init_buffers = function() { this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(vertices), this.gl.STATIC_DRAW); this.squareVertexPositionBuffer.itemSize = 3; this.squareVertexPositionBuffer.numItems = 4; - + // Texture coords - this.textureCoordBuffer = this.gl.createBuffer(); - this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.textureCoordBuffer); - - var textureCoordinates = [ - 0.0, 0.0, - 1.0, 0.0, - 1.0, 1.0, + this.textureCoordBuffer = this.gl.createBuffer(); + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.textureCoordBuffer); + + var textureCoordinates = [ + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, 0.0, 1.0 - ]; - this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), + ]; + this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), this.gl.STATIC_DRAW); this.textureCoordBuffer.itemSize = 2; this.textureCoordBuffer.numItems = 4; @@ -492,7 +650,7 @@ GLPainter.prototype.init_buffers = function() { this.vertexIndexBuffer = this.gl.createBuffer(); this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vertexIndexBuffer); var vertexIndices = [ - 0, 1, 2, 0, 2, 3 + 0, 1, 2, 0, 2, 3 ]; this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(vertexIndices), this.gl.STATIC_DRAW); this.vertexIndexBuffer.itemSize = 1; diff --git a/js/presentation.js b/js/presentation.js index 019826a..6142466 100644 --- a/js/presentation.js +++ b/js/presentation.js @@ -10,7 +10,6 @@ * You should have received a copy of the GNU General Public License along with jsdicom. If not, see http://www.gnu.org/licenses/. */ // Maybe use some cool js-templating, like mustasche? - function fill_series_selection(series, selected_uid, painter_factory) { var series_list = $("#series-selection"); series_list.empty(); @@ -29,8 +28,8 @@ function fill_series_selection(series, selected_uid, painter_factory) { if(uid == selected_uid) { item.addClass('series-selected'); } - //draw_thumbnail_to_canvas(series[uid].files[0], - // thumb_canvas.getContext('2d'), + //draw_thumbnail_to_canvas(series[uid].files[0], + // thumb_canvas.getContext('2d'), // size); item.click((function(u) { return function() { @@ -44,7 +43,8 @@ function fill_series_selection(series, selected_uid, painter_factory) { painter.init(thumb_canvas.id); painter.set_cluts(ClutManager.r('Plain'), ClutManager.g('Plain'), ClutManager.b('Plain')); painter.set_file(series[uid].files[0]); - painter.set_windowing(40, 200); + //painter.set_windowing(40, 200); + painter.set_windowing(2047, 4096); painter.draw_image(); } } @@ -74,14 +74,16 @@ function fill_metadata_table(file) { function draw_thumbnail_to_canvas(file, ctx, size) { var imageData = ctx.createImageData(size, size); // use ww/wl from file - var wl = 500; - var ww = 1000; - if(file.get_element(0x00281050) !== 0) { - wl = file.get_element(0x00281050).get_value(); - wl = (wl.constructor == Array) ? wl[0] : wl; - ww = file.get_element(0x00281051).get_value(); - ww = (ww.constructor == Array) ? ww[0] : ww; - } + //var wl = 500; + //var ww = 1000; + //if(file.get_element(0x00281050) !== 0) { + // wl = file.get_element(0x00281050).get_value(); + // wl = (wl.constructor == Array) ? wl[0] : wl; + // ww = file.get_element(0x00281051).get_value(); + // ww = (ww.constructor == Array) ? ww[0] : ww; + //} + var wl = 2047; + var ww = 4096; var step = file.columns / size; for(var row=0;row 1.0) intensity = 1.0; \ + if (intensity < 0.0) intensity = 0.0; \ + gl_FragColor = vec4(intensity, intensity, intensity, uAlpha);\ +}"; + +var fragment_shader_8_mc1 = "\ +\ +varying highp vec2 vTextureCoord;\ +uniform sampler2D uSampler;\ +uniform highp float uWW;\ +uniform highp float uWL;\ +uniform highp float uRS;\ +uniform highp float uRI;\ +uniform highp float uAlpha;\ uniform sampler2D uClutSampler;\ \ void main(void) { \ @@ -26,7 +77,7 @@ void main(void) { \ highp float lower_bound = (uWW * -0.5) + uWL; \ highp float upper_bound = (uWW * 0.5) + uWL; \ intensity = (intensity - lower_bound)/(upper_bound - lower_bound);\ -\ + intensity = 1.0 - intensity; \ gl_FragColor = vec4(intensity, intensity, intensity, uAlpha);\ }"; @@ -40,16 +91,97 @@ uniform highp float uWL;\ uniform highp float uRS;\ uniform highp float uRI;\ uniform highp float uAlpha;\ +uniform highp float uBrightness;\ +uniform highp float uContrast;\ +uniform highp float uKernel[9];\ \ void main(void) { \ - highp vec4 texcolor = texture2D(uSampler, vTextureCoord); \ - highp float intensity = texcolor.r*256.0 + texcolor.a*65536.0;\ - highp float rescaleIntercept = uRI;\ - highp float rescaleSlope = uRS;\ - intensity = intensity * rescaleSlope + rescaleIntercept;\ - highp float lower_bound = (uWW * -0.5) + uWL; \ - highp float upper_bound = (uWW * 0.5) + uWL; \ - intensity = (intensity - lower_bound)/(upper_bound - lower_bound);\ + highp float values[9];\ + highp vec2 onePixel = vec2(1.0, 1.0) / 512.0;\ + for(int i=0;i<3;++i) {\ + for(int j=0;j<3;++j) {\ + highp vec4 texcolor = texture2D(uSampler, vTextureCoord + onePixel * vec2(i-1, j-1));\ + highp float intensity = texcolor.r*256.0 + texcolor.a*65536.0;\ + highp float rescaleIntercept = uRI;\ + highp float rescaleSlope = uRS;\ + intensity = intensity * rescaleSlope + rescaleIntercept;\ + highp float lower_bound = (uWW * -0.5) + uWL; \ + highp float upper_bound = (uWW * 0.5) + uWL; \ + intensity = (intensity - lower_bound)/(upper_bound - lower_bound);\ + values[i+3*j] = intensity;\ + }\ + }\ + highp float intensity_sum = \ + values[0]*uKernel[0] +\ + values[1]*uKernel[1] +\ + values[2]*uKernel[2] +\ + values[3]*uKernel[3] +\ + values[4]*uKernel[4] +\ + values[5]*uKernel[5] +\ + values[6]*uKernel[6] +\ + values[7]*uKernel[7] +\ + values[8]*uKernel[8];\ + highp float uKernel_weight =\ + uKernel[0] + uKernel[1] + uKernel[2] + uKernel[3] + uKernel[4] + uKernel[5] +\ + uKernel[6] + uKernel[7] + uKernel[8] ;\ + highp float intensity = intensity_sum / uKernel_weight;\ + intensity = intensity + (uBrightness / 255.0); \ + intensity = (intensity - 0.5) * (uContrast / 1000.0) + 0.5; \ + if (intensity > 1.0) intensity = 1.0; \ + if (intensity < 0.0) intensity = 0.0; \ + highp vec4 clutcolor = texture2D(uClutSampler, vec2(intensity, intensity)); \ + gl_FragColor = vec4(clutcolor.r, clutcolor.g, clutcolor.b, uAlpha);\ +}"; + +var fragment_shader_16_mc1 = "\ +\ +varying highp vec2 vTextureCoord;\ +uniform sampler2D uSampler;\ +uniform sampler2D uClutSampler;\ +uniform highp float uWW;\ +uniform highp float uWL;\ +uniform highp float uRS;\ +uniform highp float uRI;\ +uniform highp float uAlpha;\ +uniform highp float uBrightness;\ +uniform highp float uContrast;\ +uniform highp float uKernel[9];\ +\ +void main(void) { \ + highp float values[9];\ + highp vec2 onePixel = vec2(1.0, 1.0) / 512.0;\ + for(int i=0;i<3;++i) {\ + for(int j=0;j<3;++j) {\ + highp vec4 texcolor = texture2D(uSampler, vTextureCoord + onePixel * vec2(i-1, j-1));\ + highp float intensity = texcolor.r*256.0 + texcolor.a*65536.0;\ + highp float rescaleIntercept = uRI;\ + highp float rescaleSlope = uRS;\ + intensity = intensity * rescaleSlope + rescaleIntercept;\ + highp float lower_bound = (uWW * -0.5) + uWL; \ + highp float upper_bound = (uWW * 0.5) + uWL; \ + intensity = (intensity - lower_bound)/(upper_bound - lower_bound);\ + values[i+3*j] = intensity;\ + }\ + }\ + highp float intensity_sum = \ + values[0]*uKernel[0] +\ + values[1]*uKernel[1] +\ + values[2]*uKernel[2] +\ + values[3]*uKernel[3] +\ + values[4]*uKernel[4] +\ + values[5]*uKernel[5] +\ + values[6]*uKernel[6] +\ + values[7]*uKernel[7] +\ + values[8]*uKernel[8];\ + highp float uKernel_weight =\ + uKernel[0] + uKernel[1] + uKernel[2] + uKernel[3] + uKernel[4] + uKernel[5] +\ + uKernel[6] + uKernel[7] + uKernel[8] ;\ + highp float intensity = intensity_sum / uKernel_weight;\ + intensity = intensity + (uBrightness / 255.0); \ + intensity = (intensity - 0.5) * (uContrast / 1000.0) + 0.5; \ + if (intensity > 1.0) intensity = 1.0; \ + if (intensity < 0.0) intensity = 0.0; \ + intensity = 1.0 - intensity; \ highp vec4 clutcolor = texture2D(uClutSampler, vec2(intensity, intensity)); \ gl_FragColor = vec4(clutcolor.r, clutcolor.g, clutcolor.b, uAlpha);\ }"; @@ -79,4 +211,3 @@ void main(void) {\ gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\ vTextureCoord = aTextureCoord;\ }"; - diff --git a/js/tools.js b/js/tools.js index e987164..273a88b 100644 --- a/js/tools.js +++ b/js/tools.js @@ -17,6 +17,9 @@ // draw(canvas) // set_file(file) +// @XXX: Mesarument of a line +// @TODO: sync to scale and pan not yet implemented +// -> so correct measuring only on scale = 1 and a valid PixelSpacing Tag. function MeasureTool(app) { this.in_motion = false; this.app = app; @@ -25,54 +28,77 @@ function MeasureTool(app) { this.startY; this.currX; this.currY; + this.canvas; - this.click = function(canvas_pos, image_pos) { - x = canvas_pos[0]; y = canvas_pos[1]; - if(this.in_motion) { - this.in_motion = false; - // Add line drawing obj to file - if(this.file.measurelines === undefined) - this.file.measurelines = []; - this.file.measurelines.push([this.startX, this.startY, this.currX, this.currY]); - } else { - this.startX = x; - this.startY = y; - this.in_motion = true; - } + this.deactivate = function() + { + + } + + this.click = function(canvas_pos, image_pos) + { + x = canvas_pos[0]; y = canvas_pos[1]; + if(this.canvas === undefined) + { + this.canvas = this.app.macanvas; + } + if(this.in_motion) + { + this.in_motion = false; + } + else + { + this.app.mlength = 0; + this.app.angle = 0; + this.startX = x; + this.startY = y; + this.in_motion = true; + } } - this.mousemove = function(canvas_pos, image_pos) { - x = canvas_pos[0]; y = canvas_pos[1]; - if(this.in_motion) { - this.currX = x; - this.currY = y; - app.draw_image(); - } + this.mousemove = function(canvas_pos, image_pos) + { + x = canvas_pos[0]; y = canvas_pos[1]; + if(this.in_motion) + { + this.canvas.width = this.canvas.width; + this.currX = x; + this.currY = y; + this.draw(); + lx = this.currX - this.startX; + ly = this.currY - this.startY; + this.app.mlength = this.measure_length(lx, ly); + this.app.mline = [this.startX, this.startY, this.currX, this.currY]; + } } - this.postdraw = function(canvas) { - // Draw current line - if (this.in_motion) { - canvas.beginPath(); - canvas.moveTo(this.startX, this.startY); - canvas.lineTo(this.currX, this.currY); - canvas.strokeStyle = '#f44'; // red - canvas.lineWidth = 4; - canvas.stroke(); - canvas.closePath() - } - lines = this.file.measurelines; - for(idx in lines) { - canvas.beginPath(); - canvas.moveTo(lines[idx][0], lines[idx][1]); - canvas.lineTo(lines[idx][2], lines[idx][3]); - canvas.strokeStyle = '#f44'; // red - canvas.lineWidth = 4; - canvas.stroke(); - canvas.closePath() - } - + this.draw = function() + { + // Draw line + if (this.in_motion === true) + { + ctx = this.canvas.getContext('2d'); + ctx.beginPath(); + ctx.moveTo(this.startX, this.startY); + ctx.lineTo(this.currX, this.currY); + ctx.strokeStyle = 'red'; // red + ctx.lineWidth = 1; + ctx.stroke(); + ctx.closePath(); + } } + this.postdraw = function() {} + + this.measure_length = function(a, b) + { + return Math.round + ( + Math.sqrt + ( + (a * a * this.app.pixel_spacing[0].trim()) + + (b * b * this.app.pixel_spacing[1].trim()))* this.app.get_scale() + ); + } this.set_file = function(file) { this.file = file; @@ -85,6 +111,9 @@ function WindowLevelTool(app) { this.app = app; this.last_mouse_pos_x = 0; this.last_mouse_pos_y = 0; + $('#wl_slider').show(); + + this.deactivate = function(){ $('#wl_slider').hide(); } this.scroll = function(detail) { this.app.set_slice_idx(this.app.get_slice_idx() + detail); @@ -126,7 +155,9 @@ function ZoomPanTool(app) { this.app = app; this.last_mouse_pos_x = 0; this.last_mouse_pos_y = 0; + $('#z').show(); + this.deactivate = function(){ $('#z').hide(); } this.scroll = function(detail) { this.app.set_scale(this.app.get_scale() + detail/100.0); } @@ -169,7 +200,274 @@ function ZoomPanTool(app) { return this; } +// @XXX: AngleTool calculates the angle between two connected lines +// Usage: click three times on the canvas in order to connect two lines +function AngleTool(app) { + this.in_motion = false; + this.app = app; + this.file; + this.canvas; + this.startX; + this.startY; + this.startX2; + this.startY2; + this.currX; + this.currY; + this.lines; + + this.click = function(canvas_pos, image_pos) { + x = canvas_pos[0]; y = canvas_pos[1]; + if(this.canvas === undefined) + { + this.canvas = this.app.macanvas; + } + if(this.in_motion) + { + // Add line drawing obj to file + if(this.lines === undefined) + { + this.lines = []; + } + if (this.lines.length == 0) { + this.lines.push([this.startX, this.startY, this.currX, this.currY]); + } + else + { + l = this.lines[this.lines.length-1]; + this.lines.push([l[2], l[3], this.currX, this.currY]); + } + if (this.lines.length > 1) + { + this.app.angle = this.degreeAngle + ( + this.lines[0][0], this.lines[0][1], + this.lines[0][2], this.lines[0][3], + this.lines[1][2], this.lines[1][3] + ); + this.endingArrow + ( + this.lines[0][2], this.lines[0][3], + this.lines[1][2], this.lines[1][3] + ); + this.lines = []; + this.in_motion = false; + } + } + else + { + if (this.lines === undefined || this.lines.length == 0) + { + this.startX = x; + this.startY = y; + this.app.angle = 0; + this.app.mlength = 0; + } + else + { + this.startX2 = x; + this.startY2 = y; + } + this.in_motion = true; + } + } + + this.mousemove = function(canvas_pos, image_pos) + { + x = canvas_pos[0]; y = canvas_pos[1]; + if(this.in_motion) + { + this.canvas.width = this.canvas.width; + this.currX = x; + this.currY = y; + if (this.lines === undefined || this.lines.length == 0) + { + this.draw([this.startX, this.startY, this.currX, this.currY]); + } + else + { + this.draw(this.lines[0]); + this.draw([this.lines[0][2], this.lines[0][3], this.currX, this.currY]); + } + } + } + + this.draw = function(l) + { + // Draw line + if (this.in_motion === true) + { + ctx = this.canvas.getContext('2d'); + ctx.beginPath(); + ctx.moveTo(l[0], l[1]); + ctx.lineTo(l[2], l[3]); + ctx.strokeStyle = 'red'; // red + ctx.lineWidth = 1; + ctx.stroke(); + ctx.closePath(); + } + } + + this.postdraw = function(canvas){} + + this.degreeAngle = function(x1, y1, x2, y2, x3, y3) + { + var theta1 = Math.atan2((y1 - y2), (x1 - x2)); + var theta2 = Math.atan2((y3 - y2), (x3 - x2)); + return Math.abs((((theta2 - theta1) * 180 / Math.PI).toFixed(2))); + } + + this.endingArrow = function(x, y, xx, yy, canvas) { + var endRadians = Math.atan((yy - y) / (xx - x)); + endRadians += ((xx > x) ? 90 : -90) * Math.PI / 180; + ctx = this.canvas.getContext('2d'); + ctx.save(); + ctx.fillStyle = 'red'; // red + ctx.beginPath(); + ctx.translate(xx, yy); + ctx.rotate(endRadians); + ctx.moveTo(0, 0); + ctx.lineTo(8, 20); + ctx.lineTo(-8, 20); + ctx.closePath(); + ctx.fill(); + ctx.restore(); + } + + this.set_file = function(file) { + this.file = file; + } + return this; +} + +function BrightnessContrastTool(app) { + this.is_mouse_down = false; + this.app = app; + this.last_mouse_pos_x = 0; + this.last_mouse_pos_y = 0; + $('#bc_slider').show(); + + this.deactivate = function(){ $('#bc_slider').hide(); } + + this.scroll = function(detail) { + + } + this.mousedown = function(canvas_pos, image_pos) { + this.is_mouse_down = true; + } + + this.mouseup = function(canvas_pos, image_pos) { + this.is_mouse_down = false; + } + + this.mousemove = function(canvas_pos, image_pos) { + x = canvas_pos[0]; y = canvas_pos[1]; + if(this.is_mouse_down) { + + } + this.last_mouse_pos_x = x; + this.last_mouse_pos_y = y; + } + + this.postdraw = function(canvas) { + } + + this.click = function(canvas_pos, image_pos) { + } + + this.set_file = function(file) { + } + return this; +} + +// @XXX: 3x3 convulution Kernel Filter for a gaussian blur +// Tool is not used - turning filter on and off is handled inside the app +function BlurTool(app) { + this.is_mouse_down = false; + this.app = app; + this.blured = false; + + + this.deactivate = function() + { + + } + + this.scroll = function(detail) { + + } + + this.mousedown = function(canvas_pos, image_pos) { + this.is_mouse_down = true; + } + + this.mouseup = function(canvas_pos, image_pos) { + this.is_mouse_down = false; + } + + this.mousemove = function(canvas_pos, image_pos) { + + } + + this.postdraw = function(canvas) { + } + + this.click = function(canvas_pos, image_pos) { + + } + + this.set_file = function(file) { + } + return this; +} + +// @XXX: 3x3 convulution Kernel Filter for sharpening +// Tool is not used - turning filter on and off is handled inside the app +function SharpenTool(app) { + this.is_mouse_down = false; + this.app = app; + this.sharpen = false; + + + this.deactivate = function() + { + + } + + this.scroll = function(detail) { + + } + + this.mousedown = function(canvas_pos, image_pos) { + this.is_mouse_down = true; + } + + this.mouseup = function(canvas_pos, image_pos) { + this.is_mouse_down = false; + } + + this.mousemove = function(canvas_pos, image_pos) { + + } + + this.postdraw = function(canvas) { + } + + this.click = function(canvas_pos, image_pos) { + + } + + this.set_file = function(file) { + } + return this; +} + +// @XXX: new tools added tools = { - 'Windowing': WindowLevelTool, + 'Window Level': WindowLevelTool, + 'Brigthness/Contrast': BrightnessContrastTool, + 'Blur': BlurTool, + 'Sharpen': SharpenTool, 'Zoom/Pan': ZoomPanTool, + 'Measure': MeasureTool, + 'Angle': AngleTool, } diff --git a/main.css b/main.css index 83cf2f9..f2a3f4d 100644 --- a/main.css +++ b/main.css @@ -73,7 +73,7 @@ body { border-radius: 0px 0px 0px 0px; } -.tool-button { +.tool-button { float:left; background: -moz-linear-gradient(top, #ccc 40%, #eee 60%); border: 1px solid #aaa; @@ -88,7 +88,7 @@ body { margin-top: 2px; } -.tool-button:hover { +.tool-button:hover { background: #fff; cursor: pointer; @@ -98,19 +98,13 @@ body { background: #fff; } -.slider-holder { - margin-bottom: 10px; - padding-right: 24px; - padding-left: 10px; -} - td { padding:0; margin:0; } #viewer-bar { - height: 25px; - margin-bottom: 10px; + width: 100%; + padding-bottom: 10px; } #viewer-bar >select { @@ -200,7 +194,7 @@ tr.even { bottom: 10px; left: 10px; right: 10px; - top: 70px; + top: 115px; } .box h2 { @@ -219,3 +213,35 @@ tr.even { position: relative; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.7); } + +.slider-holder{ + margin-top: 30px; + padding: 0px 5px; +} + +.slider-holder table{ + width: 80%; +} + +.slider-holder table td.slider{ + width: 93%; +} + +table td.label{ + width: 50px; +} +div#filter_slider{ + padding: 5px 5px 10px 5px; +} +div#filter_slider table td.slider{ + width: 350px; + padding: 0px 5px 0px 15px; +} + +div#filter_slider table td, div.slider-holder table td{ + padding: 0px 0px 0px 15px; +} + +div#z, div#wl_slider, div#bc_slider{ + display: none; +} From eefe912a4c3219a0ab8bfc539af3d2623d5e1758 Mon Sep 17 00:00:00 2001 From: Kai Philipp Date: Fri, 20 Dec 2013 12:29:35 +0100 Subject: [PATCH 2/2] if-clause bugfix --- js/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/app.js b/js/app.js index d6f527b..3f8119b 100644 --- a/js/app.js +++ b/js/app.js @@ -178,7 +178,7 @@ DcmApp.prototype.load_arraybuffer = function(abuf, index, file_count) { this.pixel_spacing = ["1","1"]; this.unit = "px"; } - // @XXX: prettoLoader hides + // @XXX: prettyLoader hides $.prettyLoader.hide(); } @@ -361,7 +361,7 @@ DcmApp.prototype.activate_tool = function(tool_identifier) { this.set_kernel("normal"); } } - if (tool_identifier == "Blur") + else if (tool_identifier == "Blur") { if (this.blured == false) {