8
8
9
9
using ImageCore, ImageBase, StatsBase
10
10
using ImageCore. MappedArrays
11
- using MultiChannelColors
12
11
using RoundingIntegers
13
12
using Gtk4, GtkObservables, Graphics, Cairo
14
13
using Gtk4: Align_START, Align_END, Align_FILL
15
14
using GtkObservables. Observables
16
15
using AxisArrays: AxisArrays, Axis, AxisArray, axisnames, axisvalues, axisdim
17
- using ImageMetadata
18
16
using Compat # for @constprop :none
19
17
20
18
export AnnotationText, AnnotationPoint, AnnotationPoints,
559
557
default_clim (img) = nothing
560
558
default_clim (img:: AbstractArray{C} ) where {C<: GrayLike } = _default_clim (img, eltype (C))
561
559
default_clim (img:: AbstractArray{C} ) where {C<: AbstractRGB } = _default_clim (img, eltype (C))
562
- default_clim (img:: AbstractArray{C} ) where {C<: AbstractMultiChannelColor } = _default_clim (img, eltype (C))
563
560
_default_clim (img, :: Type{Bool} ) = nothing
564
561
_default_clim (img, :: Type{T} ) where {T} = _deflt_clim (img)
565
562
function _deflt_clim (img:: AbstractMatrix )
@@ -573,12 +570,6 @@ function _deflt_clim(img::AbstractMatrix{T}) where {T<:AbstractRGB}
573
570
Observable (CLim (minval, maxval))
574
571
end
575
572
576
- function _deflt_clim (img:: AbstractMatrix{C} ) where {C<: AbstractMultiChannelColor }
577
- minval = zero (C)
578
- maxval = oneunit (C)
579
- Observable (CLim (minval, maxval))
580
- end
581
-
582
573
saferound (x:: Integer ) = convert (RInteger, x)
583
574
saferound (x) = x
584
575
615
606
616
607
channel_clim (f, clim:: CLim{C} ) where {C<: Colorant } = CLim (f (clim. min), f (clim. max))
617
608
channel_clims (clim:: CLim{T} ) where {T<: AbstractRGB } = map (f-> channel_clim (f, clim), (red, green, blue))
618
- channel_clims (clim:: CLim{C} ) where {C<: AbstractMultiChannelColor } = map (f-> channel_clim (f, clim), ntuple (i -> (c -> Tuple (c)[i]), length (C)))
619
609
620
610
function mapped_channel_clims (clim:: Observable{CLim{T}} ) where {T<: AbstractRGB }
621
611
inits = channel_clims (clim[])
@@ -637,18 +627,6 @@ function histsignals(enabled::Observable{Bool}, img::Observable, clim::Observabl
637
627
return histsigs
638
628
end
639
629
640
- function mapped_channel_clims (clim:: Observable{CLim{C}} ) where {C<: AbstractMultiChannelColor }
641
- inits = channel_clims (clim[])
642
- return [map! (x -> channel_clim (c -> Tuple (c)[i], x), Observable (inits[1 ]), clim) for i = 1 : length (C)]
643
- end
644
-
645
- function histsignals (enabled:: Observable{Bool} , img:: Observable , clim:: Observable{CLim{C}} ) where {C<: AbstractMultiChannelColor }
646
- chanarrays = [map (x-> mappedarray (c -> Tuple (c)[i], x), img) for i = 1 : length (C)]
647
- cls = mapped_channel_clims (clim) # note currently this gets called twice, also in contrast gui creation (a bit inefficient/awkward)
648
- histsigs = [histsignals (enabled, chanarrays[i], cls[i])[1 ] for i = 1 : length (C)]
649
- return histsigs
650
- end
651
-
652
630
function scalechannels (:: Type{Tout} , cmin:: AbstractRGB{T} , cmax:: AbstractRGB{T} ) where {T,Tout}
653
631
r = scaleminmax (T, red (cmin), red (cmax))
654
632
g = scaleminmax (T, green (cmin), green (cmax))
@@ -671,15 +649,6 @@ function safeminmax(cmin::T, cmax::T) where {T<:AbstractRGB}
671
649
return T (rmin, gmin, bmin), T (rmax, gmax, bmax)
672
650
end
673
651
674
- function scalechannels (:: Type{Tout} , cmin:: AbstractMultiChannelColor{T} , cmax:: AbstractMultiChannelColor{T} ) where {T,Tout}
675
- return x-> Tout (ntuple (i -> nanz (scaleminmax (T, Tuple (cmin)[i], Tuple (cmax)[i])(Tuple (x)[i])), length (cmin)))
676
- end
677
-
678
- function safeminmax (cmin:: C , cmax:: C ) where {C<: AbstractMultiChannelColor }
679
- minmaxpairs = ntuple (i -> safeminmax (Tuple (cmin)[i], Tuple (cmax)[i]), length (C))
680
- return C (first .(minmaxpairs)), C (last .(minmaxpairs))
681
- end
682
-
683
652
function prep_contrast (@nospecialize (img:: Observable ), clim:: Observable{CLim{T}} ) where {T}
684
653
# Set up the signals to calculate the histogram of intensity
685
654
enabled = Observable (false ) # skip hist calculation if the contrast gui isn't open
695
664
696
665
outtype (:: Type{T} ) where T<: GrayLike = Gray{N0f8}
697
666
outtype (:: Type{C} ) where C<: Color = RGB{N0f8}
698
- outtype (:: Type{C} ) where C<: AbstractMultiChannelColor = C
699
667
outtype (:: Type{C} ) where C<: TransparentColor = RGBA{N0f8}
700
668
701
669
function prep_contrast (canvas, @nospecialize (img:: Observable ), clim:: Observable{CLim{T}} ) where T
@@ -833,7 +801,6 @@ isgray(img) = false
833
801
834
802
_mappedarray (f, img) = mappedarray (f, img)
835
803
_mappedarray (f, img:: AxisArray ) = AxisArray (mappedarray (f, img. data), AxisArrays. axes (img))
836
- _mappedarray (f, img:: ImageMeta ) = shareproperties (img, _mappedarray (f, data (img)))
837
804
838
805
wrap_signal (x) = Observable (x)
839
806
wrap_signal (x:: Observable ) = x
@@ -849,6 +816,10 @@ include("contrast_gui.jl")
849
816
include (" annotations.jl" )
850
817
851
818
function __init__ ()
819
+ if ! Gtk4. initialized[]
820
+ error (" Gtk4 not initialized" )
821
+ return
822
+ end
852
823
# by default, GtkFrame and GtkAspectFrame use rounded corners
853
824
# the way to override this is via custom CSS
854
825
css= """
@@ -863,6 +834,10 @@ using PrecompileTools
863
834
for T in (N0f8, N0f16, Float32)
864
835
for C in (Gray, RGB)
865
836
img = rand (C{T}, 2 , 2 )
837
+ if ! Gtk4. initialized[]
838
+ @warn (" ImageView precompile skipped: Gtk4 could not be initialized (are you on a headless system?)" )
839
+ return
840
+ end
866
841
imshow (img)
867
842
clim = ImageView. default_clim (img)
868
843
imgsig = Observable (img)
0 commit comments