.qformFix<-function(image,origin){
hdr<-dumpNifti(image)
mat<-diag(4)
d<-dim(image)[1:3]
if(any(is.na(dim(image)[1:3]))){stop("qformFix does not support Images with less than 3 dimensions")}
diag(mat)[1:3]<-abs(pixdim(image)[1:3])*c(-1,1,1)
if(hdr$magic==""){
trans<- -((origin-1)*abs(pixdim(image)[1:3]))
mat[1:3,4]<-trans*c(-1,1,1)
invisible(qform(image)<-structure(.Data = mat,code=2))
invisible(sform(image)<-structure(.Data = mat,code=2))
}
}
viewNew<-function(data=NULL){
###################################
######### ARG CHECK ###############
###################################
if(is.null(data)){
file<-selectR()
if(length(file)==0){stop("You must select a file")}
func<-readNii(file)
} else if(is.character(data)){
file<-data
if(length(file)==0){stop("You must select a file")}
func<-readNii(file)
}else if(!is.array(data)){
stop("This is not an array with 3 or more dimensions")
}else{
func<-data
}
cl<-class(func)
if(cl!="niftiImage" && cl!="nifti" && cl!="array"){
stop(paste("class: ",cl," is not supported.\n niftiImage, arrays, characters and nifti(experimental) classes are supported.\n A NULL argument for data is also supported "))
}
#olay<-readNifti(file)
Meta<-RNifti::dumpNifti(func)
func<-RNifti::updateNifti(zeroNa(func),template = Meta)
if(Meta$magic==""&& class(data)=="character"){
o<-getAnalyzeOrigin(data)
.qformFix(func,origin=o)
}
# make all image 4d as it is then easier to handle truly 4d images without writing new code
d<-dim(func)
if(length(d)==3){
dim(func)<-c(dim(func),1)
#dim(olay)<-c(dim(olay),1)
}
d<-dim(func)
xf<-RNifti::xform(func)
##################################
######## ASPECT RATIO ############
##################################
# function designed to approximate a real number with a rational number
ratApprox<-function(asp,maxRat = 10){
zooms<-round(asp*1:maxRat)
subsamps<-1:maxRat
subsamp<-which.min(abs(zooms/subsamps-asp))
zoom<-zooms[subsamp]
return(c(zoom,subsamp))
}
# pixel dimensions needed to get aspect ratio right
pix<-abs(RNifti::pixdim(func)[1:3])
# vector containing the aspect ratios for each image
asp<-c(pix[1]/pix[3],pix[2]/pix[3],pix[1]/pix[2])
# code that determines how the aspect ratio is handled
code<-paste(as.character(as.numeric(asp>=1)),collapse="")
zoom<-1
subsamp<-1
rat1<-sort(ratApprox(asp[1]),decreasing = TRUE)
rat2<-sort(ratApprox(asp[2]),decreasing = TRUE)
rat3<-sort(ratApprox(asp[3]),decreasing = TRUE)
##################################
######## ASPECT RATIO: LEFT ######
##################################
if(code == "001"||code=="101"){
zoom2<-paste(zoom*rat3[1],zoom*rat2[1])
subsamp2<-paste(subsamp*rat3[2],-subsamp*rat2[2])
wy<-round(d[1]*zoom/subsamp*asp[3])
hy<-round(d[3]*zoom/subsamp/asp[2])
}else{
if(asp[1]>1){
zoom2<-paste(zoom*rat1[1],zoom)
subsamp2<-paste(subsamp*rat1[2],-subsamp)
wy<-round(d[1]*zoom/subsamp*asp[1])
hy<-round(d[3]*zoom/subsamp)
}else{
zoom2<-paste(zoom,zoom*rat1[1])
subsamp2<-paste(subsamp,-subsamp*rat1[2])
wy<-round(d[1]*zoom/subsamp)
hy<-round(d[3]*zoom/subsamp/asp[1])
}
}
##################################
##### ASPECT RATIO: BOTTOM #######
##################################
if(code == "111"||code == "110"){
zoom3<-paste(zoom*rat1[1],zoom*rat2[1])
subsamp3<-paste(subsamp*rat1[2],-subsamp*rat2[2])
wz<-round(d[1]*zoom/subsamp*asp[1])# equals wx:correct
hz<-round(d[2]*zoom/subsamp*asp[2])# equals wx:correct
}else{
if(asp[3]>1){
zoom3<-paste(zoom*rat3[1],zoom)
subsamp3<-paste(subsamp*rat3[2],-subsamp)
wz<-round(d[1]*zoom/subsamp*asp[3])# equals wx:correct
hz<-round(d[2]*zoom/subsamp)# equals wx:correct
}else{
zoom3<-paste(zoom,zoom*rat3[1])
subsamp3<-paste(subsamp,-subsamp*rat3[2])
wz<-round(d[1]*zoom/subsamp)# equals wx:correct
hz<-round(d[2]*zoom/subsamp/asp[3])# equals wx:correct
}
}
##################################
######## ASPECT RATIO: RIGHT #####
##################################
if(code=="000"){
zoom1<-paste(zoom*rat3[1],zoom*rat1[1])
subsamp1<-paste(subsamp*rat3[2],-subsamp*rat1[2])
wx<-round(d[2]*zoom/subsamp/asp[3]) # equals wy:correct
hx<-round(d[3]*zoom/subsamp/asp[1]) # equals wx:correct
}else{
if(code=="010"){
zoom1<-paste(zoom*rat3[1],zoom*rat1[1])
subsamp1<-paste(subsamp*rat3[2],-subsamp*rat1[2])
wx<-round(d[2]*zoom/subsamp/asp[3]) # equals wy:correct
hx<-round(d[3]*zoom/subsamp/asp[1]) # equals wx:c
}else{
if(asp[2]>=1){ # X expands
zoom1<-paste(zoom*rat2[1],zoom)
subsamp1<-paste(subsamp*rat2[2],-subsamp)
wx<-round(d[2]*zoom/subsamp*asp[2]) # equals wy:correct
hx<-round(d[3]*zoom/subsamp) # equals wx:correct
}else{ # y expands
zoom1<-paste(zoom,zoom*rat2[1])
subsamp1<-paste(subsamp,-subsamp*rat2[2])
wx<-round(d[2]*zoom/subsamp) # equals wy:correct
hx<-round(d[3]*zoom/subsamp/asp[2]) # equals wx:correct
}
}
}
##################################
#### EXPANSION FACTOR ############
##################################
imHeight<-hy+hz
screenHeight<-as.numeric(strsplit(tclvalue(tkwm.maxsize("."))," ")[[1]])[2]
desHeight<-round(screenHeight/2)
zoom<-pmax(floor(desHeight/imHeight),1)
zoom3<-paste(as.numeric(strsplit(zoom3," ")[[1]])*zoom,collapse = " ")
zoom2<-paste(as.numeric(strsplit(zoom2," ")[[1]])*zoom,collapse = " ")
zoom1<-paste(as.numeric(strsplit(zoom1," ")[[1]])*zoom,collapse = " ")
hx<-hx*zoom
wx<-wx*zoom
hy<-hy*zoom
wy<-wy*zoom
hz<-hz*zoom
wz<-wz*zoom
##################################
########## FRAMES ################
##################################
# 3 image windows and a utilities window in a master window
top <- tktoplevel()
tktitle(top)<-"Display"
master<-tkframe(parent=top)
img<-tkframe(parent = master)
f1<-tkframe(parent = img)
f2<-tkframe(parent = img)
f3<-tkframe(parent = img)
f4<-tkframe(parent = img)
f5<-tkframe(parent = master,borderwidth=5,relief="groove")
myfont <- tkfont.create(family="Arial",size=9)
##################################
####### GLOBAL VARIABLES #########
##################################
# initial coordinate is middle of image
xyz<-round(c(d[1]/2,d[2]/2,d[3]/2))
# image expands to 256 pixels or if naturally larger stays as is
#empty vectors to hold crosshair poistion and length
xyzL<-xyz
xyzLineLength<-c()
# time variable initialised to 1
t<-1
# by default crosshairs are on
crosshairsOn<-TRUE
# tcl varaibles to hold voxel coordinates and time
X<-tclVar(xyz[1])
Y<-tclVar(xyz[2])
Z<-tclVar(xyz[3])
time<-tclVar(t)
#get range to initialise max and min widget
r<-range(func,na.rm = TRUE)
#or<-oRANGE #commented out support for overlay
#tcl varaibles to hold max,min and intensity
high<-tclVar(r[2])
low<-tclVar(r[1])
#ohigh<-tclVar(or[2]) #commented out support for overlay
#olow<-tclVar(or[1]) #commented out support for overlay
intens<-tclVar(as.character(round(func[xyz[1],xyz[2],xyz[3],1],digits = 4)))
#ointens<-tclVar(as.character(round(olay[xyz[1],xyz[2],xyz[3],1],digits = 4))) #commented out support for overlay
# varaibles to describe which window is being clicked upon
click1<-FALSE
click2<-FALSE
click3<-FALSE
# set initial world coordinates and hold them in tcl variables
worldInit<-round(RNifti::voxelToWorld(xyz,func))
Xw<-tclVar(worldInit[1])
Yw<-tclVar(worldInit[2])
Zw<-tclVar(worldInit[3])
# initialise image matrices to black
im3<-matrix(data = "#ffffff",nrow = d[1],ncol = d[2])
im2<-matrix(data = "#ffffff",nrow = d[1],ncol = d[3])
im1<-matrix(data = "#ffffff",nrow = d[2],ncol = d[3])
# concatenate along columns.. the ugly hack begins
# effectively the vector elements are rows of pixels
ccim3<-.concat1(im3,margin = 2)
ccim2<-.concat1(im2,margin = 2)
ccim1<-.concat1(im1,margin = 2)
# collapse the object into one string separated by curly braces
p3<-paste(get("ccim3"),collapse = " } {",sep="")
cmdz<-paste("{",p3," }",sep = "")
# repeat for the Y image
p2<-paste(get("ccim2"),collapse = " } {",sep="")
cmdy<-paste("{",p2," }",sep = "")
# repeat for the Z image
p1<-paste(get("ccim1"),collapse = " } {",sep="")
cmdx<-paste("{",p1," }",sep = "")
#set the colour palette to greyscale
palette<-grey(0:255/255)
tmovie<-tclVar(FALSE)
after_ID <-""
someFlag<-TRUE
##################################
####### FUNCTIONS ################
##################################
# prepares images to be displayed if clicked
onLeftClick1<-function(x,y){
coord<-as.numeric(c(x,y))
height<-as.character(tkwinfo("reqheight",f1))
width<-as.character(tkwinfo("reqwidth",f1))
xyz[2]<<-round(coord[1]/as.numeric(width)*d[2])
xyz[3]<<-d[3]-round(coord[2]/as.numeric(height)*d[3])
xyzL[2]<<-xyzLineLength[2]-coord[1]+2
xyzL[3]<<-coord[2]-2
xyzL[xyzL<1]<<-1
xyzL[xyzL>xyzLineLength]<<-d[xyzL>xyzLineLength]
click1<<-TRUE
reslicer(c(xyz[1],xyz[2],xyz[3]),zoom,subsamp)
click1<<-FALSE
}
onLeftClick2<-function(x,y){
coord <- as.numeric(c(x,y))
height <- as.character(tkwinfo("reqheight",f2))
width <- as.character(tkwinfo("reqwidth",f2))
xyz[1] <<- round(coord[1] / as.numeric(width) * d[1])
xyz[3] <<- d[3] - round(coord[2] / as.numeric(height) * d[3])
xyzL[1] <<- coord[1] - 2
xyzL[3] <<- coord[2] - 2
xyzL[xyzL<1]<<-1
xyzL[xyzL>xyzLineLength]<<-d[xyzL>xyzLineLength]
click2<<-TRUE
reslicer(xyz,zoom,subsamp)
click2<<-FALSE
}
onLeftClick3<-function(x,y){
coord<-as.numeric(c(x,y))
height<-as.character(tkwinfo("reqheight",f3))
width<-as.character(tkwinfo("reqwidth",f3))
xyz[1]<<-round(coord[1]/as.numeric(width)*d[1])
xyz[2]<<-d[2]-round(coord[2]/as.numeric(height)*d[2])
xyzL[1]<<-coord[1]-2
xyzL[2]<<-coord[2]-2
xyzL[xyzL<1]<<-1
xyzL[xyzL>xyzLineLength]<<-d[xyzL>xyzLineLength]
click3<<-TRUE
reslicer(c(xyz[1],xyz[2],xyz[3]),zoom,subsamp)
click3<<-FALSE
}
onLeftClick4<-function(x,y){
coord<-as.numeric(c(x,y))
cw<-as.numeric(tkwinfo("reqwidth",canvas))
x<-0:(d[4]-1)
xfac<-cw/max(x)
xnew<-x*xfac
tclvalue(time)<<-which.min(abs(xnew-coord[1]))
reslicer(c(xyz[1],xyz[2],xyz[3]),zoom,subsamp)
}
# turns crosshairs on and off
crossHairs<-function(){
crosshairsOn<<-!crosshairsOn
reslicer(coNew = xyz,zoom = zoom,subsamp = subsamp)
gc()
}
# displays image in response to coordinate being manually changed
onSpin<-function(){
xyz[1]<<-as.numeric(tclvalue(X))
xyz[2]<<-as.numeric(tclvalue(Y))
xyz[3]<<-as.numeric(tclvalue(Z))
def<-round(d[1:3]/2)
xyz[is.na(xyz)]<<-def[is.na(xyz)]
xyzL<<-round((c(0,d[2],d[3])-xyz)/d[1:3]*xyzLineLength*c(-1,1,1))
reslicer(coNew = xyz,zoom = zoom,subsamp = subsamp)
}
# redisplays image with max and min changed
maxminChange<-function(){
ma<-as.numeric(tclvalue(high))
mi<-as.numeric(tclvalue(low))
if(is.na(ma)){tclvalue(high)<<-r[2];ma<-r[2]}
if(is.na(mi)){tclvalue(low)<<-r[1];mi<-r[1]}
reslicer(coNew = xyz,zoom = zoom,subsamp = subsamp)
}
# adds the spinbox widget which can be mysteriously absent...
tkspinbox <- function(parent, ...) {
tkwidget(parent, "tk::spinbox", ...)
}
# animation functions for time variable
repeat_call<-function(ms = 200 , f) {
after_ID <<- tcl( "after" , ms,function(){
if(someFlag){
f()
after_ID<<-repeat_call(ms,f)
}else{
tcl("after" , "cancel" , after_ID)
}
})
}
movieT<-function(){
if(tclvalue(tmovie)==1){
someFlag<<-TRUE
repeat_call(1,function() {tkinvoke(coT,"buttonup")})
}else{someFlag<<-FALSE}
}
##################################
######## INITIAL #################
##################################
xlabel<-sample(0:9,size = 10,replace = TRUE)
ylabel<-sample(0:9,size = 10,replace = TRUE)
zlabel<-sample(0:9,size = 10,replace = TRUE)
hmmx<-paste("h",paste(xlabel,collapse = ""),sep = "")
hmmy<-paste("h",paste(ylabel,collapse = ""),sep = "")
hmmz<-paste("h",paste(zlabel,collapse = ""),sep = "")
shx<-paste("sh",paste(xlabel,collapse = ""),sep = "")
shy<-paste("sh",paste(ylabel,collapse = ""),sep = "")
shz<-paste("sh",paste(zlabel,collapse = ""),sep = "")
rhx<-paste("rh",paste(xlabel,collapse = ""),sep = "")
rhy<-paste("rh",paste(ylabel,collapse = ""),sep = "")
rhz<-paste("rh",paste(zlabel,collapse = ""),sep = "")
.Tcl(paste("image create photo",hmmx))
.Tcl(paste("image create photo",hmmy))
.Tcl(paste("image create photo",hmmz))
.Tcl(paste("image create photo",shx))
.Tcl(paste("image create photo",shy))
.Tcl(paste("image create photo",shz))
xImageCallback<-.Tcl(paste("image create photo",rhx))
yImageCallback<-.Tcl(paste("image create photo",rhy))
zImageCallback<-.Tcl(paste("image create photo",rhz))
# attach the final images to a tk widget so they can be displayed
lx <- tklabel(f1, image = rhx)
ly <- tklabel(f2, image = rhy)
lz <- tklabel(f3, image = rhz)
# create the arguements that will be passed to tclk
tclArgZ<-.Tcl.args.objv(hmmz,"put",cmdz)
tclArgY<-.Tcl.args.objv(hmmy,"put",cmdy)
tclArgX<-.Tcl.args.objv(hmmx,"put",cmdx)
# put the actual data in the image using the arguments above
zPutCallback<-.Tcl.objv(tclArgZ)
yPutCallback<-.Tcl.objv(tclArgY)
xPutCallback<-.Tcl.objv(tclArgX)
# The workhorse function that displays new images
reslicer<-function(coNew,zoom,subsamp){
# perform bounds checks on coordinates
xyz[xyz<1]<<-1
xyzL[xyzL<1]<-1
xyz[xyz<1]<<-1
xyzL[xyzL<1]<-1
xyz[xyz>d[1:3]]<<-(d[1:3])[xyz>d[1:3]]
t<<-as.numeric(tclvalue(time))
t[is.na(t)]<<-1
t[t>d[4]]<-d[4]
t[t<1]<-1
tclvalue(time)<<-t
#convert to world coordinates and update variable
world<-round(xf%*%c(xyz,1))
tclvalue(Xw)<<-world[1]
tclvalue(Yw)<<-world[2]
tclvalue(Zw)<<-world[3]
xyz<<-round(xyz)
tclvalue(X)<<-xyz[1]
tclvalue(Y)<<-xyz[2]
tclvalue(Z)<<-xyz[3]
# get max and min and check if non numeric.. correct if necessary
ma<-as.numeric(tclvalue(high))
mi<-as.numeric(tclvalue(low))
if(is.na(ma)){tclvalue(high)<<-r[2];ma<-r[2]}
if(is.na(mi)){tclvalue(low)<<-r[1];mi<-r[1]}
# set height and width of images
.Tcl(paste( rhz, "configure -width",wz,"-height",hz))#1/2
.Tcl(paste( rhy, "configure -width",wy,"-height",hy))#1/2
.Tcl(paste( rhx, "configure -width",wx,"-height",hx))#1/2
# create a local copy of image
locFunc<-get("func")
# get the intensity at crosshair location
tclvalue(intens)<<-round(locFunc[xyz[1],xyz[2],xyz[3],t],digits = 3)
if(!click3){
# in place modification of im3
.hextest(input = locFunc[,,xyz[3],t],palette = palette,currentmax = ma,currentmin = mi,out = im3)
# in place modification of ugly concatenated string
.concat2(get("im3"),margin = 2,y=get("ccim3"))
# creat the tcl command in string form
p3<<-paste(get("ccim3"),collapse = " } {",sep="")
cmdz<<-paste("{",p3," }",sep = "")
# update tcl argument structure in place with string command
.tclObject( tclArgZ[[3]],update = cmdz)
# pass the ugly cmd string to tcltk (computational bottleneck)
zPutCallback<<-.Tcl.objv(tclArgZ)
# zoom by the factor zoom 3
.Tcl(paste(shz,"copy",hmmz, "-zoom",zoom3))
}
if(!click2){
# same as previous but for different image
.hextest(input = locFunc[,xyz[2],,t],palette = palette,currentmax = ma,currentmin = mi,out = im2)
.concat2(get("im2"),margin = 2,y=get("ccim2"))
p2<<-paste(get("ccim2"),collapse = " } {",sep="")
cmdy<<-paste("{",p2," }",sep = "")
.tclObject( tclArgY[[3]],update = cmdy)
yPutCallback<<-.Tcl.objv(tclArgY)
.Tcl(paste(shy,"copy", hmmy,"-zoom",zoom2))
}
if(!click1){
# same as previous but for different image
.hextest(input = locFunc[xyz[1],,,t],palette = palette,currentmax = ma,currentmin = mi,out = im1)
.concat2(get("im1"),margin = 2,y=get("ccim1"))
p1<<-paste(get("ccim1"),collapse = " } {",sep="")
cmdx<<-paste("{",p1," }",sep = "")
.tclObject( tclArgX[[3]],update = cmdx)
xPutCallback<<-.Tcl.objv(tclArgX)
.Tcl(paste(shx,"copy", hmmx,"-zoom",zoom1))
}
.Tcl(paste(rhz,"copy", shz, "-subsample",subsamp3))
.Tcl(paste(rhy,"copy", shy, "-subsample",subsamp2))
.Tcl(paste(rhx,"copy", shx, "-subsample",subsamp1))
# places green line at coordinate
if(crosshairsOn){
cmd<-paste(rhx,"put #00FF00 -to",xyzLineLength[2]-xyzL[2],0,xyzLineLength[2]-xyzL[2]+1,xyzLineLength[3])
.Tcl(cmd)
cmd<-paste(rhx, "put #00FF00 -to",0,xyzL[3],xyzLineLength[2],xyzL[3]+1)
.Tcl(cmd)
cmd<-paste(rhz,"put #00FF00 -to",0,xyzL[2],xyzLineLength[1],xyzL[2]-1)
.Tcl(cmd)
cmd<-paste(rhz,"put #00FF00 -to",xyzL[1],0,xyzL[1]+1,xyzLineLength[2])
.Tcl(cmd)
cmd<-paste(rhy,"put #00FF00 -to",0,xyzL[3],xyzLineLength[2],xyzL[3]+1)
.Tcl(cmd)
cmd<-paste(rhy,"put #00FF00 -to",xyzL[1],0,xyzL[1]+1,xyzLineLength[3])
.Tcl(cmd)}
# update green line lengths and size of bottom frame(potential for resizing)
xyzLineLength[1]<<-as.numeric(tkwinfo("reqwidth",f3))
xyzLineLength[2]<<-as.numeric(tkwinfo("reqheight",f3))
xyzLineLength[3]<<-as.numeric(tkwinfo("reqheight",f1))
tkconfigure(f5,height=100,width=as.numeric(tkwinfo("width",img)))
if(d[4]>1){
x<-0:(d[4]-1)
y<-func[xyz[1],xyz[2],xyz[3],]
ch<-as.numeric(tkwinfo("reqheight",canvas))
cw<-as.numeric(tkwinfo("reqwidth",canvas))
xfac<-cw/max(x)
xnew<-x*xfac
if(sum(y)!=0){
yfac<-ch*.8/diff(range(y))
ynew<-ch-((y-min(y))*yfac+ch*.1)
py<-ch-((y[t]-min(y))*yfac+ch*.1)
}else{
ynew<-rep(ch/2,length(y))
py<-ch/2
}
s<-round(c(rbind(xnew,ynew)))
.Tcl(paste(canvas$ID,"delete all"))
.Tcl(paste(canvas$ID,"create line" ,paste(s,collapse=" "), '-fill grey -tags "myline"'))
px<-(t-1)*xfac
.Tcl(paste(canvas$ID,"create oval" ,
paste(px-3,py-3,px+3,py+3,
collapse=" "), '-outline #00ff00 -tags "mypoint"'))
}
}
##################################
######## WIDGETS #################
##################################
# spinbox widget for voxel coordinates
coX<-tkspinbox(f5,textvariable=X,from=1,to=d[1],command=onSpin,increment=1,repeatdelay=10)
coY<-tkspinbox(f5,textvariable=Y,from=1,to=d[2],command=onSpin,increment=1,repeatdelay=10)
coZ<-tkspinbox(f5,textvariable=Z,from=1,to=d[3],command=onSpin,increment=1,repeatdelay=10)
# add a time spinbox if there is more than 1 image
if(dim(func)[4]>1){
coT<-tkspinbox(f5,textvariable=time,from=1,to=d[4],command=onSpin,increment=1,repeatdelay=10,wrap=TRUE)
}
# read only widget to hold world coordinates
coXw<-tkentry(f5,textvariable=Xw,state="readonly",readonlybackground="white")
coYw<-tkentry(f5,textvariable=Yw,state="readonly",readonlybackground="white")
coZw<-tkentry(f5,textvariable=Zw,state="readonly",readonlybackground="white")
# labels for the voxel coordinates
coXLab<-tklabel(parent = f5,text="X",font=myfont)
coYLab<-tklabel(parent = f5,text="Y",font=myfont)
coZLab<-tklabel(parent = f5,text="Z",font=myfont)
if(dim(func)[4]>1){
coTLab<-tklabel(parent = f5,text="T",font=myfont)
}
# voxel and world labels
voxLab<-tklabel(parent=f5,text="Voxel",font=myfont)
worldLab<-tklabel(parent=f5,text="World",font=myfont)
# max/min/intensity widgets and labels
MAX<-tkentry(f5,textvariable=high)
MIN<-tkentry(f5,textvariable=low)
intensity<-tkentry(f5,textvariable=intens,state="readonly",readonlybackground="white")
maxLab<-tklabel(parent = f5,text="Max",font=myfont)
minLab<-tklabel(parent = f5,text="Min",font=myfont)
intensLab<-tklabel(parent=f5,text="Intensity",font=myfont)
baseLab<-tklabel(parent=f5,text="Base ",font=myfont)
# movie button
tmovieBut<-tkcheckbutton(f5,variable=tmovie, command=movieT,text="Movie",font=myfont)
##################################
######### GEOMETRY ###############
##################################
tkgrid(master)
tkgrid(img)
tkgrid(f2,f1)
tkgrid(f3,f4)
tkgrid(lx)
tkgrid(ly)
tkgrid(lz)
canvas <- tkcanvas(f4, relief="raised",background="black",
width=as.numeric(.Tcl(paste("image width" ,rhy))),
height=as.numeric(.Tcl(paste("image width" ,rhz))))
tkgrid(canvas)
reslicer(coNew = xyz,zoom = zoom,subsamp = subsamp)
crossHairs()
crossHairs()
if(d[4]>1){
tkconfigure(canvas,
height=as.numeric(.Tcl(paste("image width" ,rhz))),
width=as.numeric(.Tcl(paste("image width" ,rhy)))
)
}
tkgrid(f5)
boxWidth<-round(as.numeric(tkwinfo("reqwidth",f5))/10)
boxHeight<-round(as.numeric(tkwinfo("reqheight",f5))/6)
tkplace(coXLab,relx=0,rely=1/6)
tkplace(coYLab,relx=0,rely=2/6)
tkplace(coZLab,relx=0,rely=3/6)
if(dim(func)[4]>1){
tkplace(coTLab,relx=0,rely=4/6)
tkplace(tmovieBut,"in"=coT,x=boxWidth)
}
tkplace(coX,"in"=coXLab,x=as.numeric(tkwinfo("reqwidth",coXLab)),width=boxWidth,height=boxHeight)
tkplace(coY,"in"=coYLab,x=as.numeric(tkwinfo("reqwidth",coXLab)),width=boxWidth,height=boxHeight)
tkplace(coZ,"in"=coZLab,x=as.numeric(tkwinfo("reqwidth",coXLab)),width=boxWidth,height=boxHeight)
Sys.sleep(.1)
tkplace(coXw,"in"=coXLab,x=as.numeric(tkwinfo("width",coX))*1.3,width=boxWidth,height=boxHeight)
tkplace(coYw,"in"=coYLab,x=as.numeric(tkwinfo("width",coX))*1.3,width=boxWidth,height=boxHeight)
tkplace(coZw,"in"=coZLab,x=as.numeric(tkwinfo("width",coX))*1.3,width=boxWidth,height=boxHeight)
if(dim(func)[4]>1){tkplace(coT,"in"=coTLab,x=as.numeric(tkwinfo("reqwidth",coXLab)),width=boxWidth,height=boxHeight)}
tkplace(voxLab,"in"=coX,x=0,y=-as.numeric(tkwinfo("reqheight",coX))*.5,anchor="w",height=boxHeight)
tkplace(worldLab,"in"=coXw,x=0,y=-as.numeric(tkwinfo("reqheight",coXw))*.5,anchor="w",height=boxHeight)
height<-tkwinfo("reqheight",master)
width<-tkwinfo("reqwidth",master)
tkplace(intensity,"in"=coXLab,x=as.numeric(width)-2*boxWidth-11,width=boxWidth,height=boxHeight)
tkplace(MAX,"in"=coYLab,x=as.numeric(width)-2*boxWidth-11,width=boxWidth,height=boxHeight)
tkplace(MIN,"in"=coZLab,x=as.numeric(width)-2*boxWidth-11,width=boxWidth,height=boxHeight)
tkplace(intensLab,'in'=intensity,x=-1,rely=.5,anchor="e",height=boxHeight)
tkplace(maxLab,'in'=MAX,x=-1,rely=.5,anchor="e",height=boxHeight)
tkplace(minLab,'in'=MIN,x=-1,rely=.5,anchor="e",height=boxHeight)
tkplace(baseLab,"in"=intensity,x=-4,y=-as.numeric(tkwinfo("reqheight",intensity))*.5,anchor="w",height=boxHeight)
###################################
########## BINDINGS ###############
###################################
tkbind(lx, "<Button-1>",onLeftClick1)
tkbind(lx, "<B1-Motion>",onLeftClick1)
tkbind(ly, "<Button-1>",onLeftClick2)
tkbind(ly, "<B1-Motion>",onLeftClick2)
tkbind(lz, "<Button-1>",onLeftClick3)
tkbind(lz, "<B1-Motion>",onLeftClick3)
tkbind(top, "<Button-3>",crossHairs)
tkbind(canvas, "<Button-1>",onLeftClick4)
tkbind(canvas, "<B1-Motion>",onLeftClick4)
tkbind(coX, "<Return>",onSpin)
tkbind(coY, "<Return>",onSpin)
tkbind(coZ, "<Return>",onSpin)
if(dim(func)[4]>1){tkbind(coT, "<Return>",onSpin)}
tkbind(MAX, "<Return>",maxminChange)
tkbind(MIN, "<Return>",maxminChange)
##################################
########## CONFIGURES ############
##################################
# get crosshair to appear
tkconfigure(img,cursor="crosshair")
# set a fixed width/height in pixels
geom<-paste(width,height,sep="x")
tkwm.geometry(top,geom)
#do not make window resizable
tkwm.resizable(top,FALSE,FALSE)
if(Meta$magic==""){
tkmessageBox(parent=top,message = "Warning: This image appears to be an Analyze image.\nThis format is only partially supported. Orientation\n may be incorrect.",
icon = "warning", type = "ok")
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.