package visHuman.onePointZero; /* * Visible Human Project Java Program * by: Yuh-Jye Chang * */ import java.applet.*; import java.awt.*; import java.net.*; import ImageProcessing.*; import visHuman.*; public class VisibleHuman extends Applet implements Runnable, Setting { VHDialog errorDialog; ImageCanvas NPAClogo, OLDAlogo, VHlogo; URL Fatch; int sliceNo[] = { 860, 350, 600}; Button3D tagBtn[], load, left, right, about, guide; ImageSelector select[]; int gender = -1; String LOAD = "Load Image"; Button3D npac, olda, vishuman; String imgdirMale = "."; String imgdirFemale = "."; String imgdir = "."; String prefix = null; int sliceOfs = 1000; int sliceConst = 1; double scale = 1.0; URL dataBase; int dontCrop = 15; int maxp = 2; int step = 50; int wFrame = 580; int hFrame = 420; int offset = 24; int no = 0; boolean canStop = false; int current = -1; int resolution = -1; int image = -1; String separator; ImageFrame frameList = null; boolean selected = false; Label3D slice; String npacURL = "http://www.npac.syr.edu"; String visHumanURL = "http://www.nlm.nih.gov/research/visible/visible_human.html"; String oldaURL = "http://www.dhpc.adelaide.edu.au/olda"; String guideURL; String aboutURL; int wrap; String tagName[] = {"Axial", "Sagittal", "Coronal", "Male", "Female", "Low", "Medium", "High", "MRI", "Photo", "CT"}; Image nullImage; public void init() { int i; int defaultRes = 1; int defaultView = 2; int defaultGender = 0; int defaultImage = 0; String arg; /* Get Current Screen Resolution */ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); tagBtn = new Button3D[11]; select = new ImageSelector[3]; /* Initialize Arguments pass from HTML */ arg = getParameter("wframe"); if (arg != null) wFrame = Integer.valueOf(arg).intValue(); arg = getParameter("hframe"); if (arg != null) hFrame = Integer.valueOf(arg).intValue(); arg = getParameter("slicex"); if (arg != null) sliceNo[0] = Integer.valueOf(arg).intValue(); arg = getParameter("slicey"); if (arg != null) sliceNo[1] = Integer.valueOf(arg).intValue(); arg = getParameter("slicez"); if (arg != null) sliceNo[2] = Integer.valueOf(arg).intValue(); arg = getParameter("scale"); if (arg != null) scale = Double.valueOf(arg).doubleValue(); arg = getParameter("maxp"); if (arg != null) maxp = Integer.valueOf(arg).intValue(); arg = getParameter("step"); if (arg != null) step = Integer.valueOf(arg).intValue(); arg = getParameter("defaultRes"); if (arg != null) defaultRes = Integer.valueOf(arg).intValue(); arg = getParameter("defaultView"); if (arg != null) defaultView = Integer.valueOf(arg).intValue(); arg = getParameter("defaultImage"); if (arg != null) defaultImage = Integer.valueOf(arg).intValue(); arg = getParameter("defaultGender"); if (arg != null) defaultGender = Integer.valueOf(arg).intValue(); arg = getParameter("imgdirMale"); if (arg != null) imgdirMale = arg; arg = getParameter("imgdirFemale"); if (arg != null) imgdirFemale = arg; arg = getParameter("dataBase"); /* if (arg != null) { try { dataBase = new URL(arg); } catch (Exception e) { dataBase = getCodeBase(); } } else { dataBase = getCodeBase(); } */ dataBase = getCodeBase(); separator = "/"; /* Set Main Applet to Border Layout */ setLayout(new BorderLayout()); /* Setup Components */ NPAClogo = new ImageCanvas(); NPAClogo.setPreferredSize(59, 59); NPAClogo.mode = 1; OLDAlogo = new ImageCanvas(); OLDAlogo.setPreferredSize(59, 59); OLDAlogo.mode = 1; VHlogo = new ImageCanvas(); VHlogo.setPreferredSize(100, 59); VHlogo.mode = 1; select[0] = new ImageSelector(Scrollbar.HORIZONTAL, sliceNo[0], 0, 1728); select[0].setValue(sliceNo[0], false); select[0].setPreferredSize(100, 59); select[0].mode = 1; select[1] = new ImageSelector(Scrollbar.HORIZONTAL, sliceNo[1], 0, 1000); select[1].setValue(sliceNo[1], false); select[1].setPreferredSize(59, 317); select[1].mode = 1; select[2] = new ImageSelector(Scrollbar.VERTICAL, sliceNo[2], 0, 1878); select[2].setValue(sliceNo[2], false); select[2].setPreferredSize(100, 317); select[2].mode = 1; npac = new Button3D("NPAC"); olda = new Button3D("OLDA"); vishuman = new Button3D("Visible Human"); vishuman.setRatio(1); Panel logos[] = new Panel[3]; logos[0] = new Panel(); logos[0].setLayout(new BorderLayout()); logos[0].add("South", npac); logos[0].add("Center", NPAClogo); logos[1] = new Panel(); logos[1].setLayout(new BorderLayout()); logos[1].add("South", olda); logos[1].add("Center", OLDAlogo); logos[2] = new Panel(); logos[2].setLayout(new BorderLayout()); logos[2].add("South", vishuman); logos[2].add("Center", VHlogo); Panel view[] = new Panel[3]; for (i=0; i<3; i++) { view[i] = new Panel(); view[i].setLayout(new BorderLayout()); view[i].add("South", tagBtn[i] = new Button3D(Button3D.CHECKBTN, tagName[i])); view[i].add("Center", select[i]); tagBtn[i].setRatio(2); } Panel board1 = new Panel(); Panel board2 = new Panel(); Panel3D board3 = new Panel3D(); Panel3D board4 = new Panel3D(); board1.add(logos[0]); board1.add(view[0]); board3.add(logos[2]); board3.add(logos[1]); board2.add(view[1]); board2.add(view[2]); board4.setLayout(new BorderLayout()); board4.add("North", board1); board4.add("South", board2); Panel3D maleFemale = new Panel3D(); for (i=3; i<5; i++) { maleFemale.add(tagBtn[i] = new Button3D(Button3D.CHECKBTN, tagName[i])); } tagBtn[3].setRatio(3); Panel resolutions = new Panel(); Panel res = new Panel(); for (i=5; i<8; i++) { res.add(tagBtn[i] = new Button3D(Button3D.CHECKBTN, tagName[i])); } resolutions.setLayout(new BorderLayout()); resolutions.add("South", res); Panel3D imageSelect = new Panel3D(); for (i=8; i<11; i++) { imageSelect.add(tagBtn[i] = new Button3D(Button3D.CHECKBTN, tagName[i])); } tagBtn[10].setRatio(2); Panel3D adjust = new Panel3D(); adjust.setLayout(new FlowLayout(FlowLayout.CENTER, d2, depth)); adjust.add(left = new Button3D(Button3D.LEFT)); adjust.add(right = new Button3D(Button3D.RIGHT)); left.setBase(tagBtn[0].getBase()-8); right.setBase(tagBtn[0].getBase()-8); Panel3D controls = new Panel3D(); controls.add(new Label("Slice:")); controls.add(slice = new Label3D(String.valueOf(sliceNo[2]))); controls.add(adjust); load = new Button3D(LOAD); Panel3D Info = new Panel3D(); Info.add(guide = new Button3D("User Guide")); Info.add(about = new Button3D("About")); guide.setRatio(4); slice.setActive(false); Panel3D p2 = new Panel3D(); p2.setLayout(new BorderLayout()); p2.add("North", new Label("Image Resolution:", Label.CENTER)); p2.add("South", resolutions); Panel p1 = new Panel(); GridBagConstraints cons = new GridBagConstraints(); GridBagLayout gridbag = new GridBagLayout(); cons.gridx = GridBagConstraints.RELATIVE; cons.gridy = GridBagConstraints.RELATIVE; cons.fill = GridBagConstraints.BOTH; cons.ipadx = 0; cons.ipady = 0; cons.insets = new Insets(0,0,0,0); cons.anchor = GridBagConstraints.EAST; cons.gridheight = 1; cons.gridwidth = GridBagConstraints.REMAINDER; p1.setLayout(gridbag); gridbag.setConstraints(maleFemale, cons); p1.add(maleFemale); gridbag.setConstraints(imageSelect, cons); p1.add(imageSelect); cons.gridheight = 2; gridbag.setConstraints(p2, cons); p1.add(p2); cons.gridheight = 1; gridbag.setConstraints(controls, cons); p1.add(controls); Panel3D Load = new Panel3D(); Load.add(load); gridbag.setConstraints(Load, cons); p1.add(Load); gridbag.setConstraints(Info, cons); p1.add(Info); Panel panel = new Panel(); panel.setLayout(new BorderLayout()); TitleLogo title = new TitleLogo(dataBase, this); panel.add("South", p1); panel.add("Center", title); panel.add("North", board3); add("East", panel); add("West", board4); setCurrent(defaultView); setResolution(defaultRes+5); image = defaultImage + 8; setGender(defaultGender + 3); sliceNo[0] = sliceNo[1] = sliceNo[2] = -1; /* Caculate offsets for Pupup ImageFrame */ int wrapx = (screenSize.width-offset*4-wFrame)/offset; wrap = (screenSize.height-offset*4-hFrame)/offset; if ( wrap > wrapx ) wrap = wrapx; if ( wrap < 1 ) wrap = 1; guideURL = dataBase + "UserGuide/index.html"; aboutURL = dataBase + "version2.html"; errorDialog = new VHDialog("MRI-CT Error", 230, 150, new Font("Dialog", Font.PLAIN, 14), 3, 19); errorDialog.setMessage("Sorry but there are"); errorDialog.addMessage("no MRI or CT images"); errorDialog.addMessage("currently avaiable."); } public void start() { /* Setup Image into Image Object */ NPAClogo.updateImage(getImage(dataBase, "NPAClogo.gif")); OLDAlogo.updateImage(getImage(dataBase, "OLDAlogo.gif")); VHlogo.updateImage(getImage(dataBase, "VHlogo.gif")); nullImage = null; updatePreview(); } private void updatePreview() { /* Update Image only when slice number is changed */ if ( sliceNo[0] != select[0].getValue()/18 ) { sliceNo[0] = select[0].getValue()/18; select[1].updateImage(getImage(dataBase, imgdir+"JPEGX-18" + separator + prefix + "X"+(sliceNo[0]+sliceOfs + sliceConst)+"-18.jpg")); } if ( sliceNo[1] != select[1].getValue()/18 ) { sliceNo[1] = select[1].getValue()/18; select[2].updateImage(getImage(dataBase, imgdir + "JPEGY-18" + separator + prefix + "Y"+(sliceNo[1]+sliceOfs + sliceConst)+"-18.jpg")); } if ( sliceNo[2] != select[2].getValue()/6 ) { int labelV = select[2].getValue(); if (gender == 4) { if (labelV < 148) { labelV = 0; } else { labelV = (labelV - 148)/6 + sliceConst; } sliceNo[2] = labelV; } else { sliceNo[2] = labelV/6; } select[0].updateImage(getImage(dataBase, imgdir + "JPEG-18" + separator+ prefix+(sliceNo[2]+sliceOfs)+"-18.jpg")); } } public void stop() { /* Destroy all the Popup ImageFrame Windows */ while ( frameList != null ) frameList.dispose(); } private void setCurrent(int _current) { /* Select the current Viewport */ if ( current == _current ) return; int i, j, k; current = _current; k = (current+1)%3; showStatus("Select "+tagName[k]+" View"); for (i=0; i<3; i++) { tagBtn[i].setActive(i!=k); select[i].setMode((i==k) ? -1 : 1); select[i].setColor((i==current) ? Color.cyan : Color.red); } left.setType((current == 2)? Button3D.UP : Button3D.LEFT); right.setType((current == 2)? Button3D.DOWN : Button3D.RIGHT); updateLabel(); } public void updateLabel() { int labelV = select[current].getValue(); if (gender == 4 && current == 2) { if (labelV < 148) { labelV = 0; } else { labelV = labelV + sliceConst - 148; } slice.setText(String.valueOf(labelV)); } else { slice.setText(String.valueOf(select[current].getValue() + sliceConst)); } } private void setResolution(int _resolution) { /* Select the current Resolution */ if ( resolution == _resolution ) return; resolution = _resolution; showStatus("Set resolution to "+tagName[resolution]); for (int i=5; i<8; i++) tagBtn[i].setActive(i!=resolution); } public void run() { /* Fatch the URL and Show Document */ showStatus(Fatch.toString()); getAppletContext().showDocument(Fatch); } private void showHTML(String addr) { /* Show URL addr's HTML document */ try { Fatch = new URL(dataBase, addr); new Delay(100, -1, this); } catch (MalformedURLException e){}; } public boolean keyDown(Event ev, int key) { if ( key < 0 ) (new Thread(this)).start(); return true; } public boolean action(Event ev, Object arg) { if (arg instanceof ImageSelector || arg == tagBtn[0] || arg == tagBtn[1] || arg == tagBtn[2]) { select[0].clearBand(); select[1].clearBand(); select[2].clearBand(); select[0].repaint(); select[1].repaint(); select[2].repaint(); } if ( arg == load ) { /* Load a Image from Data Set */ if ( canStop ) { canStop = false; load.setText(LOAD); if ( frameList != null ) frameList.dispose(); return true; } int x = offset*((no%wrap)+2); int slice = select[current].getValue(); int yScale = 1; double kScale = 1.0; if (gender == 4 && current == 2) { if (slice < 148) { slice = -1; } else { slice = slice - 148; } } String path = imgdir+"JPEG"; updatePreview(); switch ( resolution ) { case 5 : path += "-L"; break; case 6 : path += "-M"; break; } RubberBand theBand; switch ( current ) { case 0 : // Sagittal Image path += "X" + separator + prefix + "X"+(slice+sliceOfs); if ( resolution == 7 ) { yScale = 3; kScale = scale; } theBand = select[1].getBand(); break; case 1 : // Coronal Image path += "Y" + separator + prefix + "Y"+(slice+sliceOfs); if ( resolution == 7 ) { yScale = 3; kScale = scale; } theBand = select[2].getBand(); break; default : // Axial Image path += separator + prefix+(slice+sliceOfs); theBand = select[0].getBand(); break; } switch ( resolution ) { case 5 : path += "-L"; break; case 6 : path += "-M"; break; } path += ".jpg"; canStop = true; if (slice > 0) { int view = current + 1; if (view > 2) { view = 0; } int realWidth = select[view].getImageWidth(); int realHeight = select[view].getImageHeight(); try { URL source = new URL(dataBase, path); CropParams params = new CropParams(theBand, current, gender, realWidth, realHeight, source, resolution, slice); new ImageFrame(this, "2D Viewer No."+(++no)+" "+ tagBtn[(current+1)%3].getText()+" "+ tagBtn[resolution].getText()+" "+"Slice#"+slice, path, source, x, x, wFrame, hFrame, kScale, 1, yScale, maxp, step, params.X, params.Y, params.width, params.height); } catch (Exception error) { System.out.println("Error accessing file at " + dataBase + path); } if ( canStop ) load.setText("Stop"); else canStop = false; } return true; } else if (arg == left) { /* Decrease current slice number by 1 */ if ( ev.id != Event.MOUSE_UP ) { int v = select[current].getValue()-1; int labelV = v; if (gender == 4 && current == 2) { if (v < 148) { labelV = 0; } else { labelV = v + sliceConst - 148; } if ( select[current].setValue(v, true) ) { slice.setText(String.valueOf(labelV)); } } else { if ( select[current].setValue(v, true) ) { slice.setText(String.valueOf(labelV + sliceConst)); } } updatePreview(); } else { updatePreview(); } return true; } else if (arg == right) { /* Increase current slice number by 1 */ if ( ev.id != Event.MOUSE_UP ) { int v = select[current].getValue()+1; int labelV = v; if (gender == 4 && current == 2) { if (v < 148) { labelV = 0; } else { labelV = v + sliceConst - 148; } if ( select[current].setValue(v, true) ) { slice.setText(String.valueOf(labelV)); } } else { if ( select[current].setValue(v, true) ) { slice.setText(String.valueOf(labelV + sliceConst)); } } updatePreview(); } else { updatePreview(); } return true; } else if (arg == select[0]) { /* Select Cutting Line or View on Axial Image */ switch ( ev.id ) { case Event.MOUSE_DOWN : setCurrent(0); break; case Event.MOUSE_UP : updatePreview(); break; case Event.MOUSE_DRAG : break; default: setCurrent(2); } slice.setText(String.valueOf(select[current].getValue())); return true; } else if (arg == select[1]) { /* Select Cutting Line or View on Sagittal Image */ switch ( ev.id ) { case Event.MOUSE_DOWN : setCurrent(1); break; case Event.MOUSE_UP : updatePreview(); break; case Event.MOUSE_DRAG : break; default: setCurrent(0); } slice.setText(String.valueOf(select[current].getValue())); return true; } else if (arg == select[2]) { /* Select Cutting Line or View on Coronal Image */ switch ( ev.id ) { case Event.MOUSE_DOWN : setCurrent(2); updateLabel(); break; case Event.MOUSE_UP : updatePreview(); updateLabel(); break; case Event.MOUSE_DRAG : updateLabel(); break; default: setCurrent(1); slice.setText(String.valueOf(select[current].getValue() + sliceConst)); } return true; } else if (arg == tagBtn[0]) { /* Select View on Axial Image */ setCurrent(2); return true; } else if (arg == tagBtn[1]) { /* Select View on Sagittal Image */ setCurrent(0); return true; } else if (arg == tagBtn[2]) { /* Select View on Coronal Image */ setCurrent(1); return true; } else if (arg == tagBtn[3]) { /* Select Male images */ setGender(3); return true; } else if (arg == tagBtn[4]) { /* Select Female images */ setGender(4); return true; } else if (arg == tagBtn[5]) { /* Select Low Resolution */ setResolution(5); return true; } else if (arg == tagBtn[6]) { /* Select Medium Resolution */ setResolution(6); return true; } else if (arg == tagBtn[7]) { /* Select High Resolution */ setResolution(7); return true; } else if (arg == tagBtn[8]) { setImage(8); updatePreview(); return true; } else if (arg == tagBtn[9]) { setImage(9); updatePreview(); return true; } else if (arg == tagBtn[10]) { setImage(10); updatePreview(); return true; } else if ((arg == NPAClogo) || (arg == npac)) { /* Select NPAC logo or Button */ if ( (ev.id == Event.MOUSE_DOWN) || (arg == npac) ) showHTML("http://www.npac.syr.edu"); return true; } else if ((arg == OLDAlogo) || (arg == olda)) { /* Select OLDA logo or Button */ if ( (ev.id == Event.MOUSE_DOWN) || (arg == olda) ) showHTML(oldaURL); return true; } else if ((arg == VHlogo) || (arg == vishuman)) { /* Select Visible Human logo or Button */ if ( (ev.id == Event.MOUSE_DOWN) || (arg == vishuman) ) showHTML(visHumanURL); return true; } else if (arg == guide) { /* Select Guide Button */ showHTML(guideURL); return true; } else if (arg == about) { /* Select About Button */ showHTML(aboutURL); return true; } else if (arg instanceof String) { /* Download the Image into Browser */ showHTML((String)arg); return true; } else if ((frameList != null) && (arg == frameList)) { /* Popup ImageFrame is Ready Notify */ if ( canStop ) { canStop = false; if ( load.getText() != LOAD ) load.setText(LOAD); } return true; } return false; } private void setGender(int Gender) { /* Select the current gender */ if ( gender == Gender ) { return; } if (nullImage != null) { select[0].updateImage(nullImage); select[1].updateImage(nullImage); select[2].updateImage(nullImage); } gender = Gender; for (int i=3; i<5; i++) { tagBtn[i].setActive(i!=gender); } if (gender == 3) { imgdir = imgdirMale; prefix = "a_vm"; offset = 1; } else { imgdir = imgdirFemale; prefix = "avf"; offset = 148; } sliceNo[0] = sliceNo[1] = sliceNo[2] = -1; setImage(image); updateLabel(); showStatus("Set gender to " +tagName[Gender]); } private void setImage(int whichSet) { /* used to set the directory where the images are to come from */ select[0].clearBand(); select[1].clearBand(); select[2].clearBand(); select[0].repaint(); select[1].repaint(); select[2].repaint(); if (whichSet == 9) { image = whichSet; showStatus("View " +tagName[image] + " images"); if (gender == 3) { imgdir = imgdirMale; prefix = "a_vm"; } else { imgdir = imgdirFemale; prefix = "avf"; } imgdir += "Image" + separator; sliceNo[0] = -1; sliceNo[1] = -1; sliceNo[2] = -1; } else { System.out.println("MRI and CT images not yet available"); showStatus("MRI and CT images not yet available"); errorDialog.show(); } for (int i=8; i<11; i++) { tagBtn[i].setActive(i!=image); } updatePreview(); } }