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
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 0000000..d42f72c
Binary files /dev/null and b/jquery/images/prettyLoader/ajax-loader.gif differ
diff --git a/jquery/images/prettyLoader/prettyLoader.gif b/jquery/images/prettyLoader/prettyLoader.gif
new file mode 100755
index 0000000..daeb7f6
Binary files /dev/null and b/jquery/images/prettyLoader/prettyLoader.gif differ
diff --git a/jquery/images/prettyLoader/prettyLoader.png b/jquery/images/prettyLoader/prettyLoader.png
new file mode 100755
index 0000000..dba8615
Binary files /dev/null and b/jquery/images/prettyLoader/prettyLoader.png differ
diff --git a/jquery/js/jquery.prettyLoader.js b/jquery/js/jquery.prettyLoader.js
new file mode 100755
index 0000000..ede1ecd
--- /dev/null
+++ b/jquery/js/jquery.prettyLoader.js
@@ -0,0 +1,11 @@
+/* ------------------------------------------------------------------------
+ * Class: prettyLoader
+ * Use: A unified solution for AJAX loader
+ * Author: Stephane Caron (http://www.no-margin-for-errors.com)
+ * Version: 1.0.1
+ * ------------------------------------------------------------------------- */
+
+(function($){$.prettyLoader={version:'1.0.1'};$.prettyLoader=function(settings){settings=jQuery.extend({animation_speed:'fast',bind_to_ajax:true,delay:false,loader:'./images/prettyLoader/ajax-loader.gif',offset_top:13,offset_left:10},settings);scrollPos=_getScroll();imgLoader=new Image();imgLoader.onerror=function(){alert('Preloader image cannot be loaded. Make sure the path is correct in the settings and that the image is reachable.');};imgLoader.src=settings.loader;if(settings.bind_to_ajax)
+jQuery(document).ajaxStart(function(){$.prettyLoader.show()}).ajaxStop(function(){$.prettyLoader.hide()});$.prettyLoader.positionLoader=function(e){e=e?e:window.event;cur_x=(e.clientX)?e.clientX:cur_x;cur_y=(e.clientY)?e.clientY:cur_y;left_pos=cur_x+settings.offset_left+scrollPos['scrollLeft'];top_pos=cur_y+settings.offset_top+scrollPos['scrollTop'];$('.prettyLoader').css({'top':top_pos,'left':left_pos});}
+$.prettyLoader.show=function(delay){if($('.prettyLoader').size()>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..3f8119b 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");
+ }
+ }
+ else 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;
+}