BioGTK  6.5.0
A .NET library & program for annotating, editing various microscopy imaging formats using Bioformats supported images. Including whole slide, pyramidal, and series.
Loading...
Searching...
No Matches
BioGTK.ImageView Class Reference
Inheritance diagram for BioGTK.ImageView:

Public Types

enum  ViewMode { Raw , Filtered , RGBImage , Emission }
 

Public Member Functions

void SetCoordinate (int z, int c, int t)
 
ZCT GetCoordinate ()
 
void AddImage (BioImage im)
 
void SetZarrLabelOverlays (BioImage image, List< ROI > overlays, string? keyOverride=null)
 
void RefreshZarrLabelOverlays (string? sourceOverride=null)
 
void RefreshZarrLabelOverlays (BioImage image, string? sourceOverride=null)
 
List< ROI > GetZarrLabelOverlaysForImage (BioImage image)
 
void RequestImmediateRender ()
 
void RequestDeferredRender ()
 
void SetTitle (string s)
 
void UpdateImages (bool force=false)
 It updates the images.
 
void UpdateImage ()
 It updates the image.
 
void RefreshPyramidalTiles ()
 Clears cached pyramidal tiles so channel/threshold changes take effect immediately on the tile renderer.
 
void UpdateGUI ()
 It updates the GUI to reflect the current state of the image.
 
void CopySelection ()
 It takes the selected ROIs and copies them to the clipboard.
 
void PasteSelection ()
 
void OnMouseWheel (object sender, ScrollEventArgs e)
 
void ZoomAtPoint (double mouseX, double mouseY, bool zoomIn)
 
void UpdateStatus ()
 It updates the status of the user.
 
void UpdateView (bool updateImages=true)
 It updates the view.
 
double GetScale ()
 
List< ROI > GetSelectedROIs ()
 
void ZoomAtPoint (float mouseX, float mouseY, bool zoomIn)
 
PointD ImageToViewSpace (double x, double y)
 
PointF ToViewSpace (PointF p)
 
PointD ToViewSpace (PointD p)
 
PointD ToViewSpace (double x, double y)
 
double ToViewSizeH (double d)
 
double ToViewW (double d)
 
double ToViewH (double d)
 
PointD ToScreenSpace (double x, double y)
 
PointD ToScreenSpace (PointD p)
 
PointF ToScreenSpace (PointF p)
 
PointF[] ToScreenSpace (PointF[] p)
 
PointF ToScreenSpace (Point3D p)
 
float ToScreenScaleW (double x)
 
float ToScreenScaleH (double y)
 
PointF ToScreenScale (PointD p)
 
RectangleD ToScreenRect (double x, double y, double w, double h)
 
RectangleD ToScreenSpace (RectangleD p)
 
RectangleD ToScreenSpace (RectangleF p)
 
RectangleD[] ToScreenSpace (RectangleD[] p)
 
PointD[] ToScreenSpace (PointD[] p)
 
double ToScreenW (double x)
 
float ToScreenH (double y)
 
void GoToImage ()
 This function is used to go to the image at the specified index.
 
void GoToImage (int i)
 
void ReinitializeWellField ()
 Open slide file.
 
void RebuildSchemaForWell (BioImage b)
 

Static Public Member Functions

static ImageView Create (BioImage bm)
 
static SKImage BitmapToSKImage (Bitmap bmp)
 
static Cairo.Color FromColor (Color color)
 

Public Attributes

List< BioImage > Images = new List<BioImage>()
 
Gtk.Box mainBox
 
Menu contextMenu
 
SlideGLArea glArea
 
SlideRenderer slideRenderer
 
SKSlideRenderer sKSlideRenderer
 
GLWindow window
 
bool showRROIs = true
 
bool showGROIs = true
 
bool showBROIs = true
 
ROI selectedROI = new ROI()
 

Static Public Attributes

static bool MacOS = false
 
static int waitz = 1000
 
static int waitc = 1000
 
static int waitt = 1000
 
static int startz = 0
 
static int startc = 0
 
static int startt = 0
 
static int endz = 0
 
static int endc = 0
 
static int endt = 0
 
static Gdk.Key keyDown = Gdk.Key.Key_3270_Test
 
static bool x1State
 
static bool x2State
 
static bool mouseLeftState
 
static ModifierType Modifiers
 

Protected Member Functions

 ImageView (Builder builder, IntPtr handle, BioImage im)
 
void SetupHandlers ()
 Sets up the handlers.
 
override void OnDestroyed ()
 

Properties

double PxWmicron [get, set]
 
double PxHmicron [get, set]
 
bool AllowNavigation [get, set]
 
bool ShowMasks = true [get, set]
 
bool ShowOverview = true [get, set]
 
static AForge.Bitmap SelectedBuffer [get]
 
int SelectedIndex [get, set]
 
static List< ROI > selectedAnnotations [get]
 
int? MacroResolution [get]
 
int? LabelResolution [get]
 
bool OpenSlide [get, set]
 
static BioImage SelectedImage [get, set]
 
ViewMode Mode [get, set]
 
Channel RChannel [get]
 
Channel GChannel [get]
 
Channel BChannel [get]
 
PointD Origin [get, set]
 
PointD TopRightOrigin [get]
 
PointD PyramidalOriginTransformed [get, set]
 
PointD PyramidalOrigin [get, set]
 
double Resolution [get, set]
 
int Level [get, set]
 
SizeF Scale [get, set]
 
bool ShowROIs = true [get]
 
PointD MouseDownInt [get, set]
 
PointD MouseMoveInt [get, set]
 
PointD MouseUpInt [get, set]
 
PointD MouseDown [get, set]
 
PointD MouseUp [get, set]
 
PointD MouseMove [get, set]
 
static ROI SelectedAnnotation [get]
 
double ImageViewWidth [get]
 
double ImageViewHeight [get]
 
Widget View [get, set]
 

Detailed Description

Definition at line 25 of file ImageView.cs.

Member Enumeration Documentation

◆ ViewMode

enum BioGTK.ImageView.ViewMode

Definition at line 3665 of file ImageView.cs.

3666 {
3667 Raw,
3668 Filtered,
3669 RGBImage,
3670 Emission,
3671 }

Constructor & Destructor Documentation

◆ ImageView()

BioGTK.ImageView.ImageView ( Builder builder,
IntPtr handle,
BioImage im )
protected

Definition at line 600 of file ImageView.cs.

600 : base(handle)
601 {
602 _builder = builder;
603 App.viewer = this;
604 builder.Autoconnect(this);
605 var gameWindowSettings = new GameWindowSettings()
606 {
607 UpdateFrequency = 60,
608 };
609 NativeWindowSettings nativeSettings;
610
611 if (OperatingSystem.IsMacOS())
612 {
613 MacOS = true;
614 // Create the renderer bridge
615 View = new SKDrawingArea();
616 sKSlideRenderer = new SKSlideRenderer(sk);
617 }
618 else if (OperatingSystem.IsLinux())
619 {
620 nativeSettings = new NativeWindowSettings()
621 {
622 ClientSize = new Vector2i(600, 400),
623 Location = new Vector2i(0, 0),
624 Title = "OpenGL Context",
625 StartVisible = false, // Window starts hidden
626 API = ContextAPI.OpenGL,
627 Profile = ContextProfile.Core,
628 APIVersion = new Version(3, 3)
629 };
630 //tileCopy = new TileCopyGL(gameWindowSettings, nativeSettings);
631 Environment.SetEnvironmentVariable("GDK_BACKEND", "x11");
632 Environment.SetEnvironmentVariable("GTK_BACKEND", "x11");
633 if (im.isPyramidal)
634 {
635 window = new GLWindow(gameWindowSettings, nativeSettings);
636 View = new SlideGLArea();
637 ((SlideGLArea)View).OnSkiaRender += RenderSkia;
638 slideRenderer = new SlideRenderer((SlideGLArea)View);
639 }
640 else
641 {
642 View = new SlideArea();
643 ((SlideArea)View).OnSkiaRender += RenderSkia;
644 }
645 GLFWProvider.SetErrorCallback((error, description) =>
646 {
647 });
648
649 }
650 else if (OperatingSystem.IsWindows())
651 {
652 nativeSettings = new NativeWindowSettings()
653 {
654 ClientSize = new Vector2i(600, 400),
655 Location = new Vector2i(0, 0),
656 Title = "OpenGL Context",
657 StartVisible = false, // Window starts hidden
658 API = ContextAPI.OpenGL,
659 Profile = ContextProfile.Core,
660 APIVersion = new Version(3, 3)
661 };
662 if (im.isPyramidal)
663 {
664 window = new GLWindow(gameWindowSettings, nativeSettings);
665 View = new SlideGLArea();
666 ((SlideGLArea)View).OnSkiaRender += RenderSkia;
667 slideRenderer = new SlideRenderer((SlideGLArea)View);
668 }
669 else
670 {
671 View = new SlideArea();
672 ((SlideArea)View).OnSkiaRender += RenderSkia;
673 }
674 GLFWProvider.SetErrorCallback((error, description) =>
675 {
676 });
677 }
678
679 if (MacOS)
680 {
681 // View is the sole rendering surface on macOS for both pyramidal and non-pyramidal.
682 // Always attach it to the grid so the widget appears in the window layout.
683 View.Expand = true;
684 grid.Attach(View, 0, 0, 1, 1);
685
686 if (im.isPyramidal)
687 {
688 // Set the source based on image type
689 if (im.OpenSlideBase != null)
690 {
691 sKSlideRenderer.SetSource(im.OpenSlideBase);
692 }
693 else if (im.SlideBase != null)
694 {
695 sKSlideRenderer.SetSource(im.SlideBase);
696 }
697 }
698 }
699 else
700 {
701 // Set the source based on image type
702 if (slideRenderer != null && im.OpenSlideBase != null)
703 {
704 slideRenderer.SetSource(im.OpenSlideBase);
705 }
706 else if (slideRenderer != null && im.SlideBase != null)
707 {
708 slideRenderer.SetSource(im.SlideBase);
709 }
710 if (im.isPyramidal)
711 {
712 View.Expand = true;
713 grid.Attach(View,0,0,1,1);
714 }
715 else
716 {
717 View.Name = "View";
718 View.WidthRequest = 600;
719 View.HeightRequest = 400;
720 grid.Attach(View, 0, 0, 1, 1);
721 }
722 }
723
724 if (!MacOS)
725 {
726 if (im.isPyramidal)
727 {
728 View.WidthRequest = 600;
729 View.HeightRequest = 400;
730 View.Show();
731 }
732 else
733 View.ShowAll();
734 }
735 else
736 {
737 View.WidthRequest = 600;
738 View.HeightRequest = 400;
739 View.Show();
740 }
741 roi.Submenu = roiMenu;
742 UpdateRoiMenuState();
743 roi.ShowAll();
744 AddImage(im);
745 ShowMasks = true;
746 pxWmicron = SelectedImage.PhysicalSizeX;
747 pxHmicron = SelectedImage.PhysicalSizeY;
749 EnsureInitialPyramidalRender();
750 //pictureBox.WidthRequest = im.SizeX;
751 //pictureBox.HeightRequest = im.SizeY;
752 Function.InitializeContextMenu();
753 this.Scale = new SizeF(1, 1);
754 // Set the text column to display for comboboxs.
755 var rendererr = new CellRendererText();
756 rBox.PackStart(rendererr, false);
757 rBox.AddAttribute(rendererr, "text", 0);
758 var rendererg = new CellRendererText();
759 gBox.PackStart(rendererg, false);
760 gBox.AddAttribute(rendererg, "text", 0);
761 var rendererb = new CellRendererText();
762 bBox.PackStart(rendererb, false);
763 bBox.AddAttribute(rendererb, "text", 0);
764 UpdateScrollBars();
765
766 Gtk.Application.Invoke((s, e) =>
767 {
768 if (SelectedImage != null)
769 GoToImage(SelectedIndex);
770 });
771
772 //App.ApplyStyles(this);
773 }
void SetupHandlers()
Sets up the handlers.
void GoToImage()
This function is used to go to the image at the specified index.
void AddImage(BioImage im)
Definition ImageView.cs:200
void SetSource(OpenSlideGTK.OpenSlideBase openSlideSource)
Set OpenSlide source and initialize pipeline.

Member Function Documentation

◆ AddImage()

void BioGTK.ImageView.AddImage ( BioImage im)

It adds an image to the list of images, and then updates the GUI and the images

Parameters
BioImagea class that contains the image data and metadata

Definition at line 200 of file ImageView.cs.

201 {
202 Images.Add(im);
203 selectedIndex = Images.Count - 1;
204 if (im.Resolutions[0].SizeX < 1920 && im.Resolutions[0].SizeY < 1080)
205 {
206 if (View != null)
207 {
208 View.WidthRequest = im.Resolutions[0].SizeX;
209 View.HeightRequest = im.Resolutions[0].SizeY;
210 }
211 else
212 {
213 View.WidthRequest = im.Resolutions[0].SizeX;
214 View.HeightRequest = im.Resolutions[0].SizeY;
215 }
216 }
217
218 Initialize();
219 InitPreview();
220 UpdateImages(true);
221 UpdateGUI();
222 App.roiManager?.UpdateAnnotationList();
223 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, im?.file ?? string.Empty);
224 }
void UpdateGUI()
It updates the GUI to reflect the current state of the image.
void UpdateImages(bool force=false)
It updates the images.
Definition Zarr.cs:20

◆ BitmapToSKImage()

static SKImage BioGTK.ImageView.BitmapToSKImage ( Bitmap bmp)
static

Definition at line 1170 of file ImageView.cs.

1171 {
1172 var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
1173
1174 var data = bmp.LockBits(
1175 rect,
1176 ImageLockMode.ReadOnly,
1177 AForge.PixelFormat.Format32bppArgb); // This is BGRA in memory
1178
1179 try
1180 {
1181 var info = new SKImageInfo(
1182 bmp.Width,
1183 bmp.Height,
1184 SKColorType.Bgra8888,
1185 SKAlphaType.Premul);
1186
1187 var pixmap = new SKPixmap(info, data.Scan0, data.Stride);
1188
1189 return SKImage.FromPixels(pixmap);
1190 }
1191 finally
1192 {
1193 bmp.UnlockBits(data);
1194 }
1195 }

◆ CopySelection()

void BioGTK.ImageView.CopySelection ( )

It takes the selected ROIs and copies them to the clipboard.

Definition at line 3625 of file ImageView.cs.

3626 {
3627 copys.Clear();
3628 string s = "";
3629 List<ROI> rois = new List<ROI>();
3630 rois.AddRange(SelectedImage.AnnotationsR);
3631 rois.AddRange(SelectedImage.AnnotationsG);
3632 rois.AddRange(SelectedImage.AnnotationsB);
3633 foreach (ROI item in rois)
3634 {
3635 if (item.Selected)
3636 {
3637 copys.Add(item);
3638 s += BioImage.ROIToString(item);
3639 }
3640 }
3641 Clipboard clipboard = Clipboard.Get(Gdk.Selection.Clipboard);
3642 clipboard.Text = s;
3643 }

◆ Create()

static ImageView BioGTK.ImageView.Create ( BioImage bm)
static

The function creates an ImageView object using a BioImage object and returns it.

Parameters
BioImageThe BioImage parameter is an object that represents an image in a biological context. It likely contains information about the image file, such as the filename, and possibly additional metadata related to the image.
Returns
The method is returning an instance of the ImageView class.

Definition at line 580 of file ImageView.cs.

581 {
582 string gladePath = System.IO.Path.Combine(
583 System.IO.Path.GetDirectoryName(Environment.ProcessPath)!,
584 "Glade",
585 "ImageView.glade");
586 if (App.tools == null)
587 App.tools = Tools.Create();
588 Builder builder = new Builder();
589 builder.AddFromFile(gladePath);
590
591 var imageViewObj = builder.GetObject("imageView");
592 ImageView v = new ImageView(builder, imageViewObj.Handle, bm);
593 v.Title = bm.Filename;
594
595 return v;
596 }

◆ FromColor()

static Cairo.Color BioGTK.ImageView.FromColor ( Color color)
static

It takes a System.Drawing.Color and returns a Cairo.Color

Parameters
ColorThe color to convert
Returns
A Cairo.Color object.

Definition at line 3125 of file ImageView.cs.

3126 {
3127 return new Cairo.Color((double)color.R / 255, (double)color.G / 255, (double)color.B / 255);
3128 }

◆ GetCoordinate()

ZCT BioGTK.ImageView.GetCoordinate ( )

It returns the coordinate of the selected image

Returns
The Coordinate property of the SelectedImage object.

Definition at line 131 of file ImageView.cs.

132 {
133 if (SelectedImage == null)
134 return new ZCT();
135 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, SelectedImage.Coordinate.Z, SelectedImage.Coordinate.C, SelectedImage.Coordinate.T);
136 return SelectedImage.Coordinate;
137 }

◆ GetScale()

double BioGTK.ImageView.GetScale ( )

Definition at line 4026 of file ImageView.cs.

4027 {
4028 return ToViewSizeW(ROI.selectBoxSize / Scale.Width);
4029 }

◆ GetSelectedROIs()

List< ROI > BioGTK.ImageView.GetSelectedROIs ( )

Definition at line 4076 of file ImageView.cs.

4077 {
4078 List<ROI> roi = new List<ROI>();
4079 List<ROI> rois = new List<ROI>();
4080 rois.AddRange(SelectedImage.AnnotationsR);
4081 rois.AddRange(SelectedImage.AnnotationsG);
4082 rois.AddRange(SelectedImage.AnnotationsB);
4083 foreach (ROI r in rois)
4084 {
4085 if (r.Selected)
4086 {
4087 roi.Add(r);
4088 }
4089 }
4090 return roi;
4091 }

◆ GoToImage() [1/2]

void BioGTK.ImageView.GoToImage ( )

This function is used to go to the image at the specified index.

Definition at line 4798 of file ImageView.cs.

4799 {
4800 GoToImage(SelectedIndex);
4801 }

◆ GoToImage() [2/2]

void BioGTK.ImageView.GoToImage ( int i)

Definition at line 4946 of file ImageView.cs.

4947 {
4948 if (i < 0 || Images.Count <= i)
4949 return;
4950 if (_isApplyingGoToImage)
4951 {
4952 _pendingGoToImageIndex = i;
4953 return;
4954 }
4955
4956 // Ensure viewport is valid before doing any math
4957 int vpW = View.AllocatedWidth;
4958 int vpH = View.AllocatedHeight;
4959
4960 if (vpW < 10 || vpH < 10)
4961 {
4962 void OnAllocated(object sender, SizeAllocatedArgs args)
4963 {
4964 if (args.Allocation.Width < 10 || args.Allocation.Height < 10)
4965 return;
4966
4967 View.SizeAllocated -= OnAllocated;
4968 GoToImage(i);
4969 }
4970
4971 View.SizeAllocated += OnAllocated;
4972 return;
4973 }
4974
4975 bool imageChanged = selectedIndex != i;
4976 _isApplyingGoToImage = true;
4977 _suppressViewUpdates = true;
4978 try
4979 {
4980 if (imageChanged)
4981 {
4982 selectedIndex = i;
4983 Initialize();
4984 InitPreview();
4985 UpdateGUI();
4986 }
4987
4988 BioImage currentImage = Images[i];
4989 if (currentImage == null)
4990 return;
4991
4993
4994 if (currentImage.isPyramidal)
4995 {
4996 TryGetPyramidalViewerBounds(currentImage, out double imageMinX, out double imageMinY, out double imageMaxX, out double imageMaxY);
4997
4998 double imageWorldW = imageMaxX - imageMinX;
4999 double imageWorldH = imageMaxY - imageMinY;
5000 if (imageWorldW <= 0) imageWorldW = 1;
5001 if (imageWorldH <= 0) imageWorldH = 1;
5002
5003 double targetRes = Math.Max(imageWorldW / vpW, imageWorldH / vpH);
5004 if (targetRes <= 0) targetRes = 1;
5005
5006 Resolution = targetRes;
5007 UpdateScrollBars();
5008
5009 double viewWorldW = vpW * Resolution;
5010 double viewWorldH = vpH * Resolution;
5011 double originX = imageMinX - ((viewWorldW - imageWorldW) / 2.0);
5012 double originY = imageMinY - ((viewWorldH - imageWorldH) / 2.0);
5013 PyramidalOrigin = new PointD(originX, originY);
5014 }
5015 else
5016 {
5017 double imageWorldW = Math.Max(currentImage.Volume.Width, currentImage.SizeX * currentImage.PhysicalSizeX);
5018 double imageWorldH = Math.Max(currentImage.Volume.Height, currentImage.SizeY * currentImage.PhysicalSizeY);
5019 if (imageWorldW <= 0) imageWorldW = 1;
5020 if (imageWorldH <= 0) imageWorldH = 1;
5021
5022 double wx = vpW / (PxWmicron * imageWorldW);
5023 double wy = vpH / (PxHmicron * imageWorldH);
5024
5025 float fitScale = (float)Math.Min(wx, wy);
5026 if (fitScale <= 0) fitScale = 1;
5027
5028 Scale = new SizeF(fitScale, fitScale);
5029
5030 double viewWorldW = vpW / (PxWmicron * fitScale);
5031 double viewWorldH = vpH / (PxHmicron * fitScale);
5032 double originX = -currentImage.Volume.Location.X + ((viewWorldW - imageWorldW) / 2.0);
5033 double originY = -currentImage.Volume.Location.Y + ((viewWorldH - imageWorldH) / 2.0);
5034 Origin = new PointD(originX, originY);
5035 }
5036 }
5037 finally
5038 {
5039 _suppressViewUpdates = false;
5040 _isApplyingGoToImage = false;
5041 }
5042
5043 ForceNavigationRefresh();
5044 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, i);
5045
5046 if (_pendingGoToImageIndex.HasValue)
5047 {
5048 int pendingIndex = _pendingGoToImageIndex.Value;
5049 _pendingGoToImageIndex = null;
5050 if (pendingIndex != i)
5051 GoToImage(pendingIndex);
5052 }
5053 }
void RefreshPyramidalTiles()
Clears cached pyramidal tiles so channel/threshold changes take effect immediately on the tile render...

◆ ImageToViewSpace()

PointD BioGTK.ImageView.ImageToViewSpace ( double x,
double y )

It takes a point in the image space and returns the point in the view space

Parameters
xthe x coordinate of the point in the image
ythe y coordinate of the point in the image
Returns
The point in the image space that corresponds to the point in the view space.

Definition at line 4479 of file ImageView.cs.

4480 {
4481 if (SelectedImage == null)
4482 return ToViewSpace(x, y);
4483 if (SelectedImage.isPyramidal)
4484 {
4485 // PyramidalOrigin is already in world coordinates. Convert the
4486 // screen-space mouse offset back into the same world space that
4487 // ToViewSpace() consumes.
4488 return new PointD(PyramidalOrigin.X + (x * Resolution),
4489 PyramidalOrigin.Y + (y * Resolution));
4490 }
4491 else
4492 return ToViewSpace(x, y);
4493 }
PointF ToViewSpace(PointF p)

◆ OnDestroyed()

override void BioGTK.ImageView.OnDestroyed ( )
protected

Definition at line 4422 of file ImageView.cs.

4423 {
4424 base.OnDestroyed();
4425 }

◆ OnMouseWheel()

void BioGTK.ImageView.OnMouseWheel ( object sender,
ScrollEventArgs e )

Definition at line 3841 of file ImageView.cs.

3842 {
3843 double mouseX = e?.Event?.X ?? PyramidalOrigin.X;
3844 double mouseY = e?.Event?.Y ?? PyramidalOrigin.Y;
3845 if (e.Event.Direction == ScrollDirection.Up)
3846 ZoomAtPoint(mouseX, mouseY, false);
3847 else if (e.Event.Direction == ScrollDirection.Down)
3848 ZoomAtPoint(mouseX, mouseY, true);
3849 }

◆ PasteSelection()

void BioGTK.ImageView.PasteSelection ( )

The function takes the text from the clipboard and splits it into lines. Each line is then converted into an ROI object and added to the list of annotations

Definition at line 3646 of file ImageView.cs.

3647 {
3648 Clipboard clipboard = Clipboard.Get(Gdk.Selection.Clipboard);
3649 string text = clipboard.WaitForText();
3650 string[] sts = text.Split(BioImage.NewLine);
3651 foreach (string line in sts)
3652 {
3653 if (line.Length > 8)
3654 {
3655 ROI an = BioImage.StringToROI(line);
3656 //We set the coordinates of the ROI's we are pasting
3657 an.coord = GetCoordinate();
3658 SelectedImage.Annotations.Add(an);
3659 }
3660 }
3661 UpdateView();
3662 }
void UpdateView(bool updateImages=true)
It updates the view.

◆ RebuildSchemaForWell()

void BioGTK.ImageView.RebuildSchemaForWell ( BioImage b)

Definition at line 5211 of file ImageView.cs.

5212 {
5213 if (b.ZarrWellLevels == null || b.ZarrWellLevels.Count == 0)
5214 {
5215 return;
5216 }
5217 int fi = Math.Clamp(b.Level, 0, b.ZarrWellLevels.Count - 1);
5218 var fieldLevels = b.ZarrWellLevels[fi];
5219 if (fieldLevels == null || fieldLevels.Count == 0)
5220 {
5221 // Requested field not yet loaded — fall back to first non-null field
5222 // so the schema matches what TryReadRegionAsync will actually serve.
5223 fieldLevels = b.ZarrWellLevels.FirstOrDefault(l => l != null && l.Count > 0);
5224 if (fieldLevels == null)
5225 {
5226 return;
5227 }
5228 }
5229
5230 int w0 = 1, h0 = 1;
5231 GetFieldDims(fieldLevels[0], out w0, out h0);
5232
5233 var newSchema = new BruTile.TileSchema
5234 {
5235 YAxis = BruTile.YAxis.OSM,
5236 Format = "jpg",
5237 Extent = new BruTile.Extent(0, -h0, w0, 0),
5238 OriginX = 0,
5239 OriginY = 0,
5240 };
5241
5242 for (int lev = 0; lev < fieldLevels.Count; lev++)
5243 {
5244 GetFieldDims(fieldLevels[lev], out int wL, out int hL);
5245 double downsample = w0 > 0 ? (double)w0 / Math.Max(1, wL) : Math.Pow(2, lev);
5246 newSchema.Resolutions[lev] = new BruTile.Resolution(lev, downsample, 256, 256);
5247 }
5248
5249 var slideBase = SelectedImage?.OpenSlideBase;
5250 if (slideBase == null)
5251 {
5252 return;
5253 }
5254 //OpenSlideBase op = new OpenSlideBase(SelectedImage.Filename);
5255 slideBase.Schema = newSchema;
5256 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, b?.file ?? string.Empty, b?.Level ?? 0);
5257 }

◆ RefreshPyramidalTiles()

void BioGTK.ImageView.RefreshPyramidalTiles ( )

Clears cached pyramidal tiles so channel/threshold changes take effect immediately on the tile renderer.

Definition at line 1778 of file ImageView.cs.

1779 {
1780 if (SelectedImage?.isPyramidal != true)
1781 return;
1782
1783 slideRenderer?.InvalidateRenderState();
1784 sKSlideRenderer?.InvalidateRenderState();
1785 SelectedImage.InvalidateTileCache();
1786 slideRenderer?.ClearCache(resetLevel: false);
1787 sKSlideRenderer?.ClearCache();
1788 SelectedImage.ZarrDisplayMax = 0;
1789 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, SelectedImage?.file ?? string.Empty);
1790 }
void InvalidateRenderState()
Marks any in-flight render as stale so the next viewport update can replace it without the old result...
void ClearCache()
Clear the tile cache.
void InvalidateRenderState()
Marks all in-flight tile work as stale. Call this before changing threshold/range state so old tiles ...

◆ RefreshZarrLabelOverlays() [1/2]

void BioGTK.ImageView.RefreshZarrLabelOverlays ( BioImage image,
string? sourceOverride = null )

Definition at line 244 of file ImageView.cs.

245 {
246 if (image == null)
247 return;
248
249 string source = sourceOverride ?? image.file;
250 if (string.IsNullOrWhiteSpace(source))
251 source = image.Filename;
252
253 if (string.IsNullOrWhiteSpace(source) ||
254 (!source.Contains(".zarr", StringComparison.OrdinalIgnoreCase) && !Directory.Exists(source)))
255 return;
256
257 try
258 {
259 var overlays = BioLib.Zarr.LoadLabelOverlaysAsync(image, source).GetAwaiter().GetResult();
260 if (overlays == null || overlays.Count == 0)
261 {
262 // Some saved Zarrs expose the labels on disk but do not
263 // advertise them through the async label discovery path.
264 // Fall back to a direct labels-folder scan so the masks
265 // still render after reopen.
266 var zarrType = typeof(BioImage).Assembly.GetType("BioLib.Zarr");
267 var method = zarrType?.GetMethod(
268 "LoadLabelsAsROIs",
269 System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
270 if (method != null)
271 {
272 var result = method.Invoke(null, new object[] { image, source }) as List<ROI>;
273 if (result != null && result.Count > 0)
274 overlays = result;
275 }
276 }
277 if ((overlays == null || overlays.Count == 0) && image.Annotations != null)
278 {
279 var existing = image.Annotations.Where(IsZarrLabelRoi).ToList();
280 if (existing.Count > 0)
281 overlays = existing;
282 }
283
284 SetZarrLabelOverlays(image, overlays);
285 SetZarrLabelOverlays(image, overlays, source);
286 SyncZarrLabelAnnotations(image, overlays);
287 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, source);
288 }
289 catch (Exception)
290 {
291 }
292 }

◆ RefreshZarrLabelOverlays() [2/2]

void BioGTK.ImageView.RefreshZarrLabelOverlays ( string? sourceOverride = null)

Definition at line 239 of file ImageView.cs.

240 {
241 RefreshZarrLabelOverlays(SelectedImage, sourceOverride);
242 }

◆ ReinitializeWellField()

void BioGTK.ImageView.ReinitializeWellField ( )

Open slide file.

Parameters
sender
e

Rebuilds the tile schema and renderer source for a well image when the active well field (WellIndex) has been changed from outside (e.g. the PlateTool UI). Call this after setting SelectedImage.WellIndex.

Definition at line 5136 of file ImageView.cs.

5137 {
5138 if (SelectedImage?.Type != BioImage.ImageType.well) return;
5139 if (_slideBase == null) return;
5140
5141 _slideBase.RebuildSchemaForWell(SelectedImage);
5142 NormalizeOsmSchemaOrigin(_slideBase, SelectedImage);
5143
5144 if (MacOS) sKSlideRenderer?.SetSource(_slideBase);
5145 else slideRenderer?.SetSource(_slideBase);
5146
5147 // GoToImage resets the viewport to fit the new field and triggers a render.
5148 GoToImage(selectedIndex);
5149 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, SelectedImage?.file ?? string.Empty, SelectedImage.WellIndex);
5150 }

◆ RequestDeferredRender()

void BioGTK.ImageView.RequestDeferredRender ( )

Definition at line 1385 of file ImageView.cs.

1386 {
1387 if (_viewerCleanupDone)
1388 return;
1389 if (System.Threading.Interlocked.Exchange(ref _deferredRenderQueued, 1) == 1)
1390 return;
1391
1392 GLib.Timeout.Add(16, () =>
1393 {
1394 if (_viewerCleanupDone)
1395 {
1396 System.Threading.Interlocked.Exchange(ref _deferredRenderQueued, 0);
1397 return false;
1398 }
1399
1400 try
1401 {
1402 ExecuteDeferredRender();
1403 }
1404 finally
1405 {
1406 System.Threading.Interlocked.Exchange(ref _deferredRenderQueued, 0);
1407 }
1408 return false;
1409 });
1410 }

◆ RequestImmediateRender()

void BioGTK.ImageView.RequestImmediateRender ( )

Definition at line 1248 of file ImageView.cs.

1249 {
1250 UpdateView(true);
1251 }

◆ SetCoordinate()

void BioGTK.ImageView.SetCoordinate ( int z,
int c,
int t )

Definition at line 34 of file ImageView.cs.

35 {
36 if (SelectedImage == null)
37 return;
38 if (_updatingCoordinate)
39 return;
40
41 ZCT previousCoordinate = SelectedImage.Coordinate;
42 _updatingCoordinate = true;
43 try
44 {
45 if (z > SelectedImage.SizeZ - 1 && SelectedImage.Type == BioImage.ImageType.well)
46 zBar.Value = zBar.Adjustment.Upper;
47 else
48 zBar.Value = z;
49 if (c > SelectedImage.SizeC - 1)
50 cBar.Value = cBar.Adjustment.Upper;
51 else
52 cBar.Value = c;
53 if (t > SelectedImage.SizeT - 1)
54 tBar.Value = tBar.Adjustment.Upper;
55 else
56 tBar.Value = t;
57
58 if (SelectedImage.Type == BioImage.ImageType.well)
59 SelectedImage.Coordinate = new ZCT(0, (int)cBar.Value, (int)tBar.Value);
60 else
61 SelectedImage.Coordinate = new ZCT((int)zBar.Value, (int)cBar.Value, (int)tBar.Value);
62 }
63 finally
64 {
65 _updatingCoordinate = false;
66 }
67
68 bool coordinateChanged = SelectedImage.Coordinate != previousCoordinate;
69 if (SelectedImage.isPyramidal && coordinateChanged)
70 {
71 PreparePyramidalCoordinateRender();
72 ForceNavigationRefresh();
73 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, z, c, t);
74 return;
75 }
76
78 if (SelectedImage?.isPyramidal != true && View != null)
79 {
80 RequestViewportRefresh();
81 }
82 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, z, c, t);
83 }

◆ SetTitle()

void BioGTK.ImageView.SetTitle ( string s)

Definition at line 1579 of file ImageView.cs.

1580 {
1581 this.Title = s;
1582 }

◆ SetupHandlers()

void BioGTK.ImageView.SetupHandlers ( )
protected

Sets up the handlers.

Definition at line 2241 of file ImageView.cs.

2242 {
2243 View.Realized += View_Realized;
2244 this.Shown += ImageView_Shown;
2245 zBar.ValueChanged += ValueChangedZ;
2246 cBar.ValueChanged += ValueChangedC;
2247 tBar.ValueChanged += ValueChangedT;
2248 zBar.ScrollEvent += ZBar_ScrollEvent;
2249 cBar.ScrollEvent += CBar_ScrollEvent;
2250 tBar.ScrollEvent += TBar_ScrollEvent;
2251 zBar.AddEvents((int)EventMask.ScrollMask);
2252 cBar.AddEvents((int)EventMask.ScrollMask);
2253 tBar.AddEvents((int)EventMask.ScrollMask);
2254 this.ScrollEvent += ImageView_WindowScrollEvent;
2255 this.AddEvents((int)EventMask.ScrollMask);
2256 if (MacOS)
2257 {
2258 View.MotionNotifyEvent += ImageView_MotionNotifyEvent;
2259 View.ButtonPressEvent += ImageView_ButtonPressEvent;
2260 View.ButtonReleaseEvent += ImageView_ButtonReleaseEvent;
2261 View.ScrollEvent += ImageView_ScrollEvent;
2262 // OnMouseWheel is intentionally NOT registered here: ImageView_ScrollEvent already
2263 // handles zoom-to-cursor via SetResolution. Registering both causes double-zoom jumps.
2264 ((SKDrawingArea)View).PaintSurface += Sk_PaintSurface;
2265 View.SizeAllocated += PictureBox_SizeAllocated;
2266 View.SetSizeRequest(600, 400);
2267 View.AddEvents((int)(EventMask.ButtonPressMask
2268 | EventMask.ButtonReleaseMask
2269 | EventMask.KeyPressMask
2270 | EventMask.PointerMotionMask
2271 | EventMask.ScrollMask));
2272 }
2273 else
2274 {
2275 View.MotionNotifyEvent += ImageView_MotionNotifyEvent;
2276 View.ButtonPressEvent += ImageView_ButtonPressEvent;
2277 View.ButtonReleaseEvent += ImageView_ButtonReleaseEvent;
2278 View.ScrollEvent += ImageView_ScrollEvent;
2279 // OnMouseWheel removed: ImageView_ScrollEvent handles zoom-to-cursor via SetResolution.
2280 if (glArea != null)
2281 glArea.Render += GlArea_Render;
2282 View.SizeAllocated += PictureBox_SizeAllocated;
2283 View.AddEvents((int)(EventMask.ButtonPressMask
2284 | EventMask.ButtonReleaseMask
2285 | EventMask.KeyPressMask
2286 | EventMask.PointerMotionMask
2287 | EventMask.ScrollMask));
2288 }
2289 vScroll.ValueChanged += VScroll_ValueChanged;
2290 hScroll.ValueChanged += HScroll_ValueChanged;
2291 this.KeyPressEvent += ImageView_KeyPressEvent;
2292 this.DestroyEvent += ImageView_DestroyEvent;
2293 this.DeleteEvent += ImageView_DeleteEvent;
2294 this.FocusInEvent += ImageView_FocusInEvent;
2295 rBox.Changed += RBox_Changed;
2296 gBox.Changed += GBox_Changed;
2297 bBox.Changed += BBox_Changed;
2298 //Context Menu
2299 goToImageMenu.ButtonPressEvent += GoToImageMenu_ButtonPressEvent;
2300 goToOriginMenu.ButtonPressEvent += GoToOriginMenu_ButtonPressEvent;
2301 overView.ButtonPressEvent += OverView_ButtonPressEvent;
2302
2303 roiShow.ButtonPressEvent += RoiShow_ButtonPressEvent;
2304 roiHide.ButtonPressEvent += RoiHide_ButtonPressEvent;
2305 roiDelete.ButtonPressEvent += RoiDelete_ButtonPressEvent;
2306 roiID.ButtonPressEvent += RoiID_ButtonPressEvent;
2307 copy.ButtonPressEvent += Copy_ButtonPressEvent;
2308 paste.ButtonPressEvent += Paste_ButtonPressEvent;
2309 draw.ButtonPressEvent += Draw_ButtonPressEvent;
2310 fill.ButtonPressEvent += Fill_ButtonPressEvent;
2311
2312 play.ButtonPressEvent += Play_ButtonPressEvent;
2313 stop.ButtonPressEvent += Stop_ButtonPressEvent;
2314 playSpeed.ButtonPressEvent += PlaySpeed_ButtonPressEvent;
2315 setValueRange.ButtonPressEvent += SetValueRange_ButtonPressEvent;
2316 loop.ButtonPressEvent += Loop_ButtonPressEvent;
2317
2318 zBar.ButtonPressEvent += ZBar_ButtonPressEvent;
2319 tBar.ButtonPressEvent += TBar_ButtonPressEvent;
2320 cBar.ButtonPressEvent += CBar_ButtonPressEvent;
2321
2322 }

◆ SetZarrLabelOverlays()

void BioGTK.ImageView.SetZarrLabelOverlays ( BioImage image,
List< ROI > overlays,
string? keyOverride = null )

Definition at line 226 of file ImageView.cs.

227 {
228 if (image == null)
229 return;
230
231 string key = string.IsNullOrWhiteSpace(keyOverride) ? GetOverlayKey(image) : keyOverride;
232 if (string.IsNullOrWhiteSpace(key))
233 return;
234
235 zarrLabelOverlays[key] = overlays ?? new List<ROI>();
236 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, image?.file ?? string.Empty, overlays?.Count ?? 0, keyOverride ?? string.Empty);
237 }

◆ ToScreenH()

float BioGTK.ImageView.ToScreenH ( double y)

‍Convert a value in microns to a value in pixels

Parameters
ythe y coordinate of the point to be converted
Returns
The return value is a float.

Definition at line 4793 of file ImageView.cs.

4794 {
4795 return (float)(y * PxHmicron);
4796 }

◆ ToScreenRect()

RectangleD BioGTK.ImageView.ToScreenRect ( double x,
double y,
double w,
double h )

It converts a rectangle in microns to a rectangle in pixels

Parameters
xThe x coordinate of the rectangle
y-0.0015
wwidth of the image in microns
hheight of the rectangle
Returns
A RectangleF object.

Definition at line 4706 of file ImageView.cs.

4707 {
4708 if (SelectedImage == null)
4709 {
4710 double dx = (pxWmicron * (-Origin.X)) * Scale.Width;
4711 double dy = (pxHmicron * (-Origin.Y)) * Scale.Height;
4712 RectangleD rf = new RectangleD((PxWmicron * x * Scale.Width + dx), (PxHmicron * y * Scale.Height + dy), (PxWmicron * w * Scale.Width), (PxHmicron * h * Scale.Height));
4713 return rf;
4714 }
4715 if (SelectedImage.isPyramidal)
4716 {
4717 PointD d = ToViewSpace(x, y);
4718 double dw = ToViewSizeW(w);
4719 double dh = ToViewSizeH(h);
4720 return new RectangleD(d.X, d.Y, dw, dh);
4721 }
4722 else
4723 {
4724 double dx = (pxWmicron * (Origin.X)) * Scale.Width;
4725 double dy = (pxHmicron * (Origin.Y)) * Scale.Height;
4726 RectangleD rf = new RectangleD((PxWmicron * x * Scale.Width + dx), (PxHmicron * y * Scale.Height + dy), (PxWmicron * w * Scale.Width), (PxHmicron * h * Scale.Height));
4727 return rf;
4728 }
4729 }
double ToViewSizeH(double d)

◆ ToScreenScale()

PointF BioGTK.ImageView.ToScreenScale ( PointD p)

‍Convert a point in the world coordinate system to a point in the screen coordinate system

Parameters
PointD
Returns
A PointF object.

Definition at line 4692 of file ImageView.cs.

4693 {
4694 float x = ToScreenScaleW((float)p.X);
4695 float y = ToScreenScaleH((float)p.Y);
4696 return new PointF(x, y);
4697 }
float ToScreenScaleW(double x)
float ToScreenScaleH(double y)

◆ ToScreenScaleH()

float BioGTK.ImageView.ToScreenScaleH ( double y)

‍Convert a value in microns to a value in pixels

Parameters
ythe y coordinate of the point to be converted
Returns
The return value is a float.

Definition at line 4683 of file ImageView.cs.

4684 {
4685 return (float)(-y * PxHmicron * Scale.Height);
4686 }

◆ ToScreenScaleW()

float BioGTK.ImageView.ToScreenScaleW ( double x)

ToScreenScaleW() returns the number of pixels that correspond to the given number of microns

Parameters
xthe x coordinate of the point to be converted
Returns
The return value is a float.

Definition at line 4674 of file ImageView.cs.

4675 {
4676 return (float)(-x * PxWmicron * Scale.Width);
4677 }

◆ ToScreenSpace() [1/9]

PointD BioGTK.ImageView.ToScreenSpace ( double x,
double y )

‍It converts a point in world space to a point in screen space

Parameters
xThe x coordinate of the point to convert.
yThe y coordinate of the point to transform.
Returns
A PointD object.

Definition at line 4621 of file ImageView.cs.

4622 {
4623 RectangleD f = ToScreenRect(x, y, 1, 1);
4624 return new PointD(f.X, f.Y);
4625 }
RectangleD ToScreenRect(double x, double y, double w, double h)

◆ ToScreenSpace() [2/9]

PointF BioGTK.ImageView.ToScreenSpace ( Point3D p)

‍It converts a 3D point to a 2D point

Parameters
Point3D
Returns
A PointF object.

Definition at line 4664 of file ImageView.cs.

4665 {
4666 PointD pd = ToScreenSpace(p.X, p.Y);
4667 return new PointF((float)pd.X, (float)pd.Y);
4668 }
PointD ToScreenSpace(double x, double y)

◆ ToScreenSpace() [3/9]

PointD BioGTK.ImageView.ToScreenSpace ( PointD p)

‍Converts a point from world space to screen space

Parameters
PointDA class that contains an X and Y value.
Returns
A PointD object.

Definition at line 4631 of file ImageView.cs.

4632 {
4633 return ToScreenSpace(p.X, p.Y);
4634 }

◆ ToScreenSpace() [4/9]

PointD[] BioGTK.ImageView.ToScreenSpace ( PointD[] p)

‍Convert a list of points from world space to screen space

Parameters
pThe point to convert
Returns
A PointF[] array of points.

Definition at line 4769 of file ImageView.cs.

4770 {
4771 PointD[] rs = new PointD[p.Length];
4772 for (int i = 0; i < p.Length; i++)
4773 {
4774 PointD pd = ToScreenSpace(p[i]);
4775 rs[i] = new PointD((float)pd.X, (float)pd.Y);
4776 }
4777 return rs;
4778 }

◆ ToScreenSpace() [5/9]

PointF BioGTK.ImageView.ToScreenSpace ( PointF p)

Convert a point in the world coordinate system to the screen coordinate system

Parameters
PointFThe point you want to convert to screen space.
Returns
A PointD object.

Definition at line 4640 of file ImageView.cs.

4641 {
4642 PointD pd = ToScreenSpace(p.X, p.Y);
4643 return new PointF((float)pd.X, (float)pd.Y);
4644 }

◆ ToScreenSpace() [6/9]

PointF[] BioGTK.ImageView.ToScreenSpace ( PointF[] p)

‍It takes an array of points and returns an array of points

Parameters
pThe point to convert
Returns
A PointF array.

Definition at line 4650 of file ImageView.cs.

4651 {
4652 PointF[] pf = new PointF[p.Length];
4653 for (int i = 0; i < p.Length; i++)
4654 {
4655 pf[i] = ToScreenSpace(p[i]);
4656 }
4657 return pf;
4658 }

◆ ToScreenSpace() [7/9]

RectangleD BioGTK.ImageView.ToScreenSpace ( RectangleD p)

‍It converts a rectangle from world space to screen space

Parameters
RectangleDThe rectangle to convert.
Returns
A RectangleF object.

Definition at line 4736 of file ImageView.cs.

4737 {
4738 return ToScreenRect(p.X, p.Y, p.W, p.H);
4739 }

◆ ToScreenSpace() [8/9]

RectangleD[] BioGTK.ImageView.ToScreenSpace ( RectangleD[] p)

It takes an array of RectangleD objects and returns an array of RectangleF objects

Parameters
pThe rectangle to convert
Returns
A RectangleF[]

Definition at line 4754 of file ImageView.cs.

4755 {
4756 RectangleD[] rs = new RectangleD[p.Length];
4757 for (int i = 0; i < p.Length; i++)
4758 {
4759 rs[i] = ToScreenSpace(p[i]);
4760 }
4761 return rs;
4762 }

◆ ToScreenSpace() [9/9]

RectangleD BioGTK.ImageView.ToScreenSpace ( RectangleF p)

‍It converts a rectangle from world space to screen space

Parameters
RectangleFThe rectangle to convert.
Returns
A RectangleF object.

Definition at line 4745 of file ImageView.cs.

4746 {
4747 return ToScreenRect(p.X, p.Y, p.Width, p.Height);
4748 }

◆ ToScreenW()

double BioGTK.ImageView.ToScreenW ( double x)

ToScreenW(x) = x * PxWmicron

Parameters
xthe x coordinate of the point to be converted
Returns
The return value is a float.

Definition at line 4784 of file ImageView.cs.

4785 {
4786 return (float)(x * PxWmicron);
4787 }

◆ ToViewH()

double BioGTK.ImageView.ToViewH ( double d)

‍Convert a distance in microns to a distance in pixels

Parameters
dthe distance in microns
Returns
The return value is the y-coordinate of the point in the view.

Definition at line 4605 of file ImageView.cs.

4606 {
4607 if (SelectedImage != null)
4608 if (SelectedImage.isPyramidal)
4609 {
4610 return d / Resolution;
4611 }
4612 double y = (double)(d / PxHmicron) / scale.Height;
4613 return y;
4614 }

◆ ToViewSizeH()

double BioGTK.ImageView.ToViewSizeH ( double d)

‍Convert a value in microns to a value in pixels

Parameters
dthe size in microns
Returns
The return value is the size of the object in pixels.

Definition at line 4575 of file ImageView.cs.

4576 {
4577 if (SelectedImage != null)
4578 if (SelectedImage.isPyramidal)
4579 {
4580 return d / Resolution;
4581 }
4582 double y = (double)(d / PxHmicron);
4583 return y;
4584 }

◆ ToViewSpace() [1/3]

PointD BioGTK.ImageView.ToViewSpace ( double x,
double y )

Definition at line 4532 of file ImageView.cs.

4533 {
4534 if (SelectedImage == null)
4535 {
4536 double dx = (ToViewSizeW(x - (View.AllocatedWidth / 2)) / Scale.Width) - Origin.X;
4537 double dy = (ToViewSizeH(y - (View.AllocatedHeight / 2)) / Scale.Height) - Origin.Y;
4538 return new PointD(dx, dy);
4539 }
4540 if (SelectedImage.isPyramidal)
4541 {
4542 // x, y are world (full-resolution pixel) coordinates.
4543 // Subtract the viewport origin and divide by Resolution to get screen pixels.
4544 return new PointD((x - PyramidalOrigin.X) / Resolution,
4545 (y - PyramidalOrigin.Y) / Resolution);
4546 }
4547 else
4548 {
4549 double dx = (ToViewSizeW(x - (View.AllocatedWidth / 2)) / Scale.Width) - Origin.X;
4550 double dy = (ToViewSizeH(y - (View.AllocatedHeight / 2)) / Scale.Height) - Origin.Y;
4551 return new PointD(dx, dy);
4552 }
4553 }

◆ ToViewSpace() [2/3]

PointD BioGTK.ImageView.ToViewSpace ( PointD p)

‍Converts a point from world space to view space

Parameters
PointDA class that contains an X and Y value.
Returns
A PointD object.

Definition at line 4509 of file ImageView.cs.

4510 {
4511 return ToViewSpace(p.X, p.Y); ;
4512 }

◆ ToViewSpace() [3/3]

PointF BioGTK.ImageView.ToViewSpace ( PointF p)

Convert a point from world space to view space

Parameters
PointFThe point to convert
Returns
A PointD object.

Definition at line 4499 of file ImageView.cs.

4500 {
4501 PointD d = ToViewSpace(p.X, p.Y);
4502 return new PointF((float)d.X, (float)d.Y);
4503 }

◆ ToViewW()

double BioGTK.ImageView.ToViewW ( double d)

Convert a distance in microns to a distance in pixels on the screen

Parameters
dthe distance in microns
Returns
The width of the image in pixels.

Definition at line 4590 of file ImageView.cs.

4591 {
4592 if (SelectedImage != null)
4593 if (SelectedImage.isPyramidal)
4594 {
4595 return d / Resolution;
4596 }
4597 double x = (double)(d / PxWmicron) / scale.Width;
4598 return x;
4599 }

◆ UpdateGUI()

void BioGTK.ImageView.UpdateGUI ( )

It updates the GUI to reflect the current state of the image.

Definition at line 3480 of file ImageView.cs.

3481 {
3482 if (SelectedImage == null)
3483 return;
3484 if (_updatingGui)
3485 return;
3486
3487 _updatingGui = true;
3488 try
3489 {
3490 EnsureImageChannels(SelectedImage);
3491 cBar.Adjustment.Lower = 0;
3492 cBar.Adjustment.Upper = Images[selectedIndex].SizeC - 1;
3493 zBar.Adjustment.Lower = 0;
3494 zBar.Adjustment.Upper = Images[selectedIndex].SizeZ - 1;
3495 tBar.Adjustment.Lower = 0;
3496 tBar.Adjustment.Upper = Images[selectedIndex].SizeT - 1;
3497 if (endz == 0 || endz > Images[selectedIndex].SizeZ - 1)
3498 endz = Images[selectedIndex].SizeZ - 1;
3499 if (endc == 0 || endc > Images[selectedIndex].SizeC - 1)
3500 endc = Images[selectedIndex].SizeC - 1;
3501 if (endt == 0 || endt > Images[selectedIndex].SizeT - 1)
3502 endt = Images[selectedIndex].SizeT - 1;
3503 UpdateScrollBars();
3504 var store = new ListStore(typeof(string));
3505 for (int i = 0; i < SelectedImage.Channels.Count; i++)
3506 {
3507 store.AppendValues(GetChannelDisplayLabel(SelectedImage.Channels[i], i));
3508 }
3509 rBox.Model = store;
3510 gBox.Model = store;
3511 bBox.Model = store;
3512 if (SelectedImage.Channels.Count > 2)
3513 {
3514 rBox.Active = Math.Clamp(SelectedImage.rgbChannels[0], 0, SelectedImage.Channels.Count - 1);
3515 gBox.Active = Math.Clamp(SelectedImage.rgbChannels[1], 0, SelectedImage.Channels.Count - 1);
3516 bBox.Active = Math.Clamp(SelectedImage.rgbChannels[2], 0, SelectedImage.Channels.Count - 1);
3517 }
3518 else if (SelectedImage.Channels.Count == 2)
3519 {
3520 rBox.Active = Math.Clamp(SelectedImage.rgbChannels[0], 0, SelectedImage.Channels.Count - 1);
3521 gBox.Active = Math.Clamp(SelectedImage.rgbChannels[1], 0, SelectedImage.Channels.Count - 1);
3522 }
3523 else if (SelectedImage.Channels.Count == 1)
3524 {
3525 rBox.Active = 0;
3526 gBox.Active = 0;
3527 bBox.Active = 0;
3528 }
3529 imagesMenu = new Menu();
3530 for (int i = 0; i < Images.Count; i++)
3531 {
3532 if (Images[i] == null)
3533 {
3534 if (SelectedIndex >= Images.Count)
3535 SelectedIndex--;
3536 Images.RemoveAt(i);
3537 }
3538 MenuItem mi = new MenuItem(Images[i].Filename);
3539 mi.ButtonPressEvent += Mi_ButtonPressEvent;
3540 imagesMenu.Append(mi);
3541 }
3542 goToImageMenu.Submenu = imagesMenu;
3543 goToImageMenu.ShowAll();
3544 }
3545 finally
3546 {
3547 _updatingGui = false;
3548 }
3549 }

◆ UpdateImage()

void BioGTK.ImageView.UpdateImage ( )

It updates the image.

Definition at line 1769 of file ImageView.cs.

1770 {
1771 UpdateImages();
1772 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false);
1773 }

◆ UpdateImages()

void BioGTK.ImageView.UpdateImages ( bool force = false)

It updates the images.

Definition at line 1612 of file ImageView.cs.

1613 {
1614 App.viewer = this;
1615 if (selectedIndex < 0 || selectedIndex >= Images.Count)
1616 return;
1617 BioImage currentImage = Images[selectedIndex];
1618 if (currentImage == null)
1619 return;
1620 EnsureImageChannels(currentImage);
1621 if (zBar.Adjustment.Upper != currentImage.SizeZ - 1 ||
1622 tBar.Adjustment.Upper != currentImage.SizeT - 1)
1623 {
1624 UpdateGUI();
1625 }
1626 if (!MacOS)
1627 {
1628 if (currentImage.isPyramidal && glArea.AllocatedWidth > 1 && glArea.AllocatedHeight > 1)
1629 {
1630 // Use the new renderer - no more ReadPixels!
1631 _ = slideRenderer.UpdateViewAsync(
1632 currentImage.PyramidalOrigin,
1633 glArea.AllocatedWidth,
1634 glArea.AllocatedHeight,
1635 currentImage.Resolution,
1636 currentImage.Coordinate
1637 );
1638 }
1639 else if (!currentImage.isPyramidal)
1640 {
1641 for (int i = 0; i < SKImages.Count; i++)
1642 {
1643 SKImages[i].Dispose();
1644 Bitmaps[i].Dispose();
1645 }
1646 SKImages.Clear();
1647 Bitmaps.Clear();
1648 foreach (BioImage b in Images)
1649 {
1650 ZCT c = b.Coordinate;
1651 AForge.Bitmap bitmap = null;
1652 int index = b.GetFrameIndex(c.Z, c.C, c.T);
1653 if (Mode == ViewMode.Filtered)
1654 {
1655 bitmap = b.GetFiltered(c, b.RChannel.RangeR, b.GChannel.RangeG, b.BChannel.RangeB);
1656 }
1657 else if (Mode == ViewMode.RGBImage)
1658 {
1659 bitmap = b.GetRGBBitmap(c, b.RChannel.RangeR, b.GChannel.RangeG, b.BChannel.RangeB);
1660 }
1661 else if (Mode == ViewMode.Raw)
1662 {
1663 bitmap = b.Buffers[index];
1664 }
1665 else
1666 {
1667 bitmap = b.GetEmission(c, b.RChannel.RangeR, b.GChannel.RangeG, b.BChannel.RangeB);
1668 }
1669 if (bitmap == null)
1670 return;
1671 var bm = bitmap.GetImageRGBA(bitmap.LittleEndian);
1672 SKImage skim = BitmapToSKImage(bm);
1673 SKImages.Add(skim);
1674 Bitmaps.Add(bm);
1675 }
1676 }
1677 }
1678 else
1679 {
1680 if (currentImage.isPyramidal && sk.AllocatedWidth > 1 && sk.AllocatedHeight > 1)
1681 {
1682 // Use the new renderer - no more ReadPixels!
1683 _ = sKSlideRenderer.UpdateViewAsync(
1684 currentImage.PyramidalOrigin,
1685 currentImage.Resolution,
1686 currentImage.Coordinate,
1687 sk.AllocatedWidth,
1688 sk.AllocatedHeight
1689 );
1690 }
1691 else if (!currentImage.isPyramidal)
1692 {
1693 for (int i = 0; i < SKImages.Count; i++)
1694 {
1695 SKImages[i].Dispose();
1696 Bitmaps[i].Dispose();
1697 }
1698 SKImages.Clear();
1699 Bitmaps.Clear();
1700 foreach (BioImage b in Images)
1701 {
1702 ZCT c = b.Coordinate;
1703 AForge.Bitmap bitmap = null;
1704 int index = b.GetFrameIndex(c.Z, c.C, c.T);
1705 if (Mode == ViewMode.Filtered)
1706 {
1707 bitmap = b.GetFiltered(c, b.RChannel.RangeR, b.GChannel.RangeG, b.BChannel.RangeB);
1708 }
1709 else if (Mode == ViewMode.RGBImage)
1710 {
1711 bitmap = b.GetRGBBitmap(c, b.RChannel.RangeR, b.GChannel.RangeG, b.BChannel.RangeB);
1712 }
1713 else if (Mode == ViewMode.Raw)
1714 {
1715 bitmap = b.Buffers[index];
1716 }
1717 else
1718 {
1719 bitmap = b.GetEmission(c, b.RChannel.RangeR, b.GChannel.RangeG, b.BChannel.RangeB);
1720 }
1721 if (bitmap == null)
1722 return;
1723 var bm = bitmap.GetImageRGBA(bitmap.LittleEndian);
1724 SKImage skim = BitmapToSKImage(bm);
1725 SKImages.Add(skim);
1726 Bitmaps.Add(bm);
1727 }
1728 }
1729 }
1730 }/*
async Task UpdateViewAsync(PointD origin, double resolution, ZCT coordinate, int width=600, int height=400)
Update the rendered view asynchronously - main entry point for rendering.

◆ UpdateStatus()

void BioGTK.ImageView.UpdateStatus ( )

It updates the status of the user.

Definition at line 3976 of file ImageView.cs.

3977 {
3978 if (SelectedImage.Buffers.Count == 0 && SelectedImage.Type != BioImage.ImageType.well)
3979 return;
3980 if (SelectedImage.Type == BioImage.ImageType.stack)
3981 statusLabel.Text = (zBar.Value + 1) + "/" + (zBar.Adjustment.Upper + 1) + ", " + (cBar.Value + 1) + "/" + (cBar.Adjustment.Upper + 1) + ", " + (tBar.Value + 1) + "/" + (tBar.Adjustment.Upper + 1) + ", " +
3982 mousePoint + mouseColor + ", " + SelectedImage.Resolutions[0].PixelFormat.ToString() + ", (" + SelectedImage.Volume.Location.X.ToString("N2") + ", " + SelectedImage.Volume.Location.Y.ToString("N2") + ") "
3983 + Origin.X.ToString("N2") + "," + Origin.Y.ToString("N2") + ", Res:" + Resolution + " Level:" + Level;
3984 else if (SelectedImage.Type == BioImage.ImageType.pyramidal ||
3985 SelectedImage.Type == BioImage.ImageType.well)
3986 {
3987 string wellStatus = SelectedImage.Type == BioImage.ImageType.well
3988 ? ", WellIndex:" + SelectedImage.WellIndex
3989 : string.Empty;
3990 statusLabel.Text = (zBar.Value + 1) + "/" + (zBar.Adjustment.Upper + 1) + ", " + (cBar.Value + 1) + "/" + (cBar.Adjustment.Upper + 1) + ", " + (tBar.Value + 1) + "/" + (tBar.Adjustment.Upper + 1) + ", " +
3991 mousePoint + mouseColor + ", " + SelectedImage.Resolutions[0].PixelFormat.ToString() + ", (" + SelectedImage.Volume.Location.X.ToString("N2") + ", " + SelectedImage.Volume.Location.Y.ToString("N2") + ") "
3992 + PyramidalOrigin.X.ToString("N2") + "," + PyramidalOrigin.Y.ToString("N2") + " , Level:" + Level + " Res:" + Resolution + wellStatus;
3993 }
3994 }

◆ UpdateView()

void BioGTK.ImageView.UpdateView ( bool updateImages = true)

It updates the view.

Definition at line 3996 of file ImageView.cs.

3997 {
3998 refresh = true;
3999 if (SelectedImage?.isPyramidal == true)
4000 {
4001 RequestDeferredRender();
4002 }
4003 else
4004 {
4005 UpdateImages(true);
4006 RequestViewportRefresh();
4007 }
4008 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, updateImages);
4009 }

◆ ZoomAtPoint() [1/2]

void BioGTK.ImageView.ZoomAtPoint ( double mouseX,
double mouseY,
bool zoomIn )

Definition at line 3850 of file ImageView.cs.

3851 {
3852 if (SelectedImage == null || !SelectedImage.isPyramidal) return;
3853
3854 int currentLevel = Level;
3855 int nextLevel = zoomIn
3856 ? Math.Max(0, currentLevel - 1)
3857 : Math.Min(SelectedImage.Resolutions.Count - 1, currentLevel + 1);
3858
3859 if (nextLevel == currentLevel)
3860 return;
3861
3862 double currentResolution = SelectedImage.GetUnitPerPixel(currentLevel);
3863 double nextResolution = SelectedImage.GetUnitPerPixel(nextLevel);
3864 if (currentResolution <= 0 || nextResolution <= 0)
3865 return;
3866
3867 // Batch the level/origin change so zoom only triggers one viewport
3868 // update instead of two separate renders.
3869 SetResolution(nextResolution, new PointD(mouseX, mouseY));
3870 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, mouseX, mouseY, zoomIn);
3871 }

◆ ZoomAtPoint() [2/2]

void BioGTK.ImageView.ZoomAtPoint ( float mouseX,
float mouseY,
bool zoomIn )

Definition at line 4092 of file ImageView.cs.

4093 {
4094 if (SelectedImage == null) return;
4095
4096 // 1. Define zoom factor (e.g., 2.0x zoom steps)
4097 float zoomFactor = zoomIn ? 2.0f : 0.5f;
4098
4099 // 2. Get the current level's scale relative to Full Res (Level 0)
4100 // Formula: CurrentLevelWidth / FullResWidth
4101 double currentLevelScale = (double)SelectedImage.Resolutions[SelectedImage.Level].SizeX / SelectedImage.SizeX;
4102
4103 // 3. Find the "World Point" (Full Res Level 0) currently under the mouse
4104 // We add the origin to the mouse offset and then scale up to Level 0
4105 double worldX = (PyramidalOrigin.X + mouseX) / currentLevelScale;
4106 double worldY = (PyramidalOrigin.Y + mouseY) / currentLevelScale;
4107
4108 // 4. Update your Level logic here
4109 // This is where you switch your 'CurrentLevelWidth' to the next level in the pyramid
4110 //UpdateLevel(zoomIn);
4111
4112 // 5. Get the NEW level's scale relative to Full Res
4113 double newLevelScale = (double)SelectedImage.Resolutions[SelectedImage.Level].SizeX / SelectedImage.SizeX;
4114
4115 // 6. Calculate the NEW PyramidalOrigin
4116 // To keep the world point at the same mouse position:
4117 // NewOrigin = (WorldPoint * NewScale) - MouseOffset
4118 float newOriginX = (float)(worldX * newLevelScale - mouseX);
4119 float newOriginY = (float)(worldY * newLevelScale - mouseY);
4120
4121 // 7. Apply and Clamp (to ensure we don't scroll past image edges)
4122 TryGetPyramidalViewerBounds(SelectedImage, out double imageMinX, out double imageMinY, out double imageMaxX, out double imageMaxY);
4123 double viewWorldW = Math.Max(1, View?.AllocatedWidth ?? 1) * Resolution;
4124 double viewWorldH = Math.Max(1, View?.AllocatedHeight ?? 1) * Resolution;
4125 PyramidalOrigin = new PointD(
4126 ClampPyramidalOrigin(newOriginX, imageMinX, imageMaxX, viewWorldW),
4127 ClampPyramidalOrigin(newOriginY, imageMinY, imageMaxY, viewWorldH)
4128 );
4129 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, mouseX, mouseY, zoomIn);
4130 }

Member Data Documentation

◆ contextMenu

Menu BioGTK.ImageView.contextMenu

Definition at line 519 of file ImageView.cs.

◆ endc

int BioGTK.ImageView.endc = 0
static

Definition at line 2491 of file ImageView.cs.

◆ endt

int BioGTK.ImageView.endt = 0
static

Definition at line 2492 of file ImageView.cs.

◆ endz

int BioGTK.ImageView.endz = 0
static

Definition at line 2490 of file ImageView.cs.

◆ glArea

SlideGLArea BioGTK.ImageView.glArea

Definition at line 565 of file ImageView.cs.

◆ Images

List<BioImage> BioGTK.ImageView.Images = new List<BioImage>()

Definition at line 31 of file ImageView.cs.

◆ keyDown

Gdk.Key BioGTK.ImageView.keyDown = Gdk.Key.Key_3270_Test
static

Definition at line 3249 of file ImageView.cs.

◆ MacOS

bool BioGTK.ImageView.MacOS = false
static

Definition at line 569 of file ImageView.cs.

◆ mainBox

Gtk.Box BioGTK.ImageView.mainBox

Definition at line 507 of file ImageView.cs.

◆ Modifiers

ModifierType BioGTK.ImageView.Modifiers
static

Definition at line 4033 of file ImageView.cs.

◆ mouseLeftState

bool BioGTK.ImageView.mouseLeftState
static

Definition at line 4032 of file ImageView.cs.

◆ selectedROI

ROI BioGTK.ImageView.selectedROI = new ROI()

Definition at line 4042 of file ImageView.cs.

◆ showBROIs

bool BioGTK.ImageView.showBROIs = true

Definition at line 4015 of file ImageView.cs.

◆ showGROIs

bool BioGTK.ImageView.showGROIs = true

Definition at line 4014 of file ImageView.cs.

◆ showRROIs

bool BioGTK.ImageView.showRROIs = true

Definition at line 4013 of file ImageView.cs.

◆ sKSlideRenderer

SKSlideRenderer BioGTK.ImageView.sKSlideRenderer

Definition at line 567 of file ImageView.cs.

◆ slideRenderer

SlideRenderer BioGTK.ImageView.slideRenderer

Definition at line 566 of file ImageView.cs.

◆ startc

int BioGTK.ImageView.startc = 0
static

Definition at line 2488 of file ImageView.cs.

◆ startt

int BioGTK.ImageView.startt = 0
static

Definition at line 2489 of file ImageView.cs.

◆ startz

int BioGTK.ImageView.startz = 0
static

Definition at line 2487 of file ImageView.cs.

◆ waitc

int BioGTK.ImageView.waitc = 1000
static

Definition at line 2485 of file ImageView.cs.

◆ waitt

int BioGTK.ImageView.waitt = 1000
static

Definition at line 2486 of file ImageView.cs.

◆ waitz

int BioGTK.ImageView.waitz = 1000
static

Definition at line 2484 of file ImageView.cs.

◆ window

GLWindow BioGTK.ImageView.window

Definition at line 568 of file ImageView.cs.

◆ x1State

bool BioGTK.ImageView.x1State
static

Definition at line 4030 of file ImageView.cs.

◆ x2State

bool BioGTK.ImageView.x2State
static

Definition at line 4031 of file ImageView.cs.

Property Documentation

◆ AllowNavigation

bool BioGTK.ImageView.AllowNavigation
getset

Definition at line 430 of file ImageView.cs.

431 {
432 get { return allowNavigation; }
433 set { allowNavigation = value; }
434 }

◆ BChannel

Channel BioGTK.ImageView.BChannel
get

Definition at line 3746 of file ImageView.cs.

3747 {
3748 get
3749 {
3750 return SelectedImage.Channels[SelectedImage.rgbChannels[2]];
3751 }
3752 }

◆ GChannel

Channel BioGTK.ImageView.GChannel
get

Definition at line 3738 of file ImageView.cs.

3739 {
3740 get
3741 {
3742 return SelectedImage.Channels[SelectedImage.rgbChannels[1]];
3743 }
3744 }

◆ ImageViewHeight

double BioGTK.ImageView.ImageViewHeight
get

Definition at line 4465 of file ImageView.cs.

4466 {
4467 get
4468 {
4469 double d = View.AllocatedHeight / Resolution;
4470 return d;
4471 }
4472 }

◆ ImageViewWidth

double BioGTK.ImageView.ImageViewWidth
get

Definition at line 4457 of file ImageView.cs.

4458 {
4459 get
4460 {
4461 double d = View.AllocatedWidth / Resolution;
4462 return d;
4463 }
4464 }

◆ LabelResolution

int? BioGTK.ImageView.LabelResolution
get

Definition at line 1794 of file ImageView.cs.

1794{ get { return SelectedImage.LabelResolution; } }

◆ Level

int BioGTK.ImageView.Level
getset

Definition at line 3931 of file ImageView.cs.

3932 {
3933 get
3934 {
3935 return SelectedImage.LevelFromResolution(SelectedImage.Resolution);
3936 }
3937 set
3938 {
3939 if (value < 0)
3940 return;
3941 if (SelectedImage?.Type == BioImage.ImageType.well)
3942 {
3943 if (l != value)
3944 l = value;
3945 SelectedImage.Level = value;
3946 UpdateScrollBars();
3947 if (View != null)
3948 {
3949 UpdateImages();
3950 View.QueueDraw();
3951 }
3952 return;
3953 }
3954 if (l != value)
3955 UpdateLevel();
3956 l = value;
3957 SelectedImage.Level = l;
3958 UpdateScrollBars();
3959 }
3960 }

◆ MacroResolution

int? BioGTK.ImageView.MacroResolution
get

Definition at line 1793 of file ImageView.cs.

1793{ get { return SelectedImage.MacroResolution; } }

◆ Mode

ViewMode BioGTK.ImageView.Mode
getset

Definition at line 3699 of file ImageView.cs.

3700 {
3701 get
3702 {
3703 return viewMode;
3704 }
3705 set
3706 {
3707 viewMode = value;
3708 if (viewMode == ViewMode.RGBImage)
3709 {
3710 rgbStack.VisibleChild = rgbStack.Children[1];
3711 }
3712 else
3713 if (viewMode == ViewMode.Filtered)
3714 {
3715 rgbStack.VisibleChild = rgbStack.Children[0];
3716 }
3717 else
3718 if (viewMode == ViewMode.Raw)
3719 {
3720 rgbStack.VisibleChild = rgbStack.Children[0];
3721 }
3722 else
3723 {
3724 rgbStack.VisibleChild = rgbStack.Children[0];
3725 }
3726 RefreshDisplayState(invalidatePyramidalTiles: true);
3727 }
3728 }

◆ MouseDown

PointD BioGTK.ImageView.MouseDown
getset

Definition at line 4059 of file ImageView.cs.

4060 {
4061 get { return mouseDown; }
4062 set { mouseDown = value; }
4063 }

◆ MouseDownInt

PointD BioGTK.ImageView.MouseDownInt
getset

Definition at line 4044 of file ImageView.cs.

4045 {
4046 get { return mouseDownInt; }
4047 set { mouseDownInt = value; }
4048 }

◆ MouseMove

PointD BioGTK.ImageView.MouseMove
getset

Definition at line 4069 of file ImageView.cs.

4070 {
4071 get { return mouseMove; }
4072 set { mouseMove = value; }
4073 }

◆ MouseMoveInt

PointD BioGTK.ImageView.MouseMoveInt
getset

Definition at line 4049 of file ImageView.cs.

4050 {
4051 get { return mouseMoveInt; }
4052 set { mouseMoveInt = value; }
4053 }

◆ MouseUp

PointD BioGTK.ImageView.MouseUp
getset

Definition at line 4064 of file ImageView.cs.

4065 {
4066 get { return mouseUp; }
4067 set { mouseUp = value; }
4068 }

◆ MouseUpInt

PointD BioGTK.ImageView.MouseUpInt
getset

Definition at line 4054 of file ImageView.cs.

4055 {
4056 get { return mouseUpInt; }
4057 set { mouseUpInt = value; }
4058 }

◆ OpenSlide

bool BioGTK.ImageView.OpenSlide
getset

Definition at line 3673 of file ImageView.cs.

3674 {
3675 get { return openSlide; }
3676 set { openSlide = value; }
3677 }

◆ Origin

PointD BioGTK.ImageView.Origin
getset

Definition at line 3755 of file ImageView.cs.

3756 {
3757 get { return origin; }
3758 set
3759 {
3760 if (AllowNavigation)
3761 origin = value;
3762 if (View != null)
3763 {
3764 UpdateImages();
3765 if (!MacOS)
3766 glArea?.RequestRedraw();
3767 else
3768 View.QueueDraw();
3769 }
3770 }
3771 }
void RequestRedraw()
Request a redraw of the GLArea.

◆ PxHmicron

double BioGTK.ImageView.PxHmicron
getset

Definition at line 397 of file ImageView.cs.

398 {
399 get
400 {
401 if (SelectedImage == null)
402 return 1;
403 if (SelectedImage.Type == BioImage.ImageType.pyramidal)
404 if (openSlide)
405 {
406 if (_openSlideBase?.Schema?.Resolutions != null && _openSlideBase.Schema.Resolutions.Count > 0)
407 {
408 int lev = OpenSlideGTK.TileUtil.GetLevel(_openSlideBase.Schema.Resolutions, Resolution);
409 lev = Math.Clamp(lev, 0, _openSlideBase.Schema.Resolutions.Count - 1);
410 return _openSlideBase.Schema.Resolutions[lev].UnitsPerPixel * pxHmicron;
411 }
412 }
413 else
414 {
415 if (_slideBase?.Schema?.Resolutions != null && _slideBase.Schema.Resolutions.Count > 0)
416 {
417 int lev = OpenSlideGTK.TileUtil.GetLevel(_slideBase.Schema.Resolutions, Resolution);
418 lev = Math.Clamp(lev, 0, _slideBase.Schema.Resolutions.Count - 1);
419 return _slideBase.Schema.Resolutions[lev].UnitsPerPixel * pxHmicron;
420 }
421 }
422 return pxHmicron;
423 }
424 set
425 {
426 pxHmicron = value;
427 }
428 }

◆ PxWmicron

double BioGTK.ImageView.PxWmicron
getset

Definition at line 364 of file ImageView.cs.

365 {
366 get
367 {
368 if (SelectedImage == null)
369 return 1;
370 if (SelectedImage.Type == BioImage.ImageType.pyramidal)
371 if (openSlide)
372 {
373 if (_openSlideBase?.Schema?.Resolutions != null && _openSlideBase.Schema.Resolutions.Count > 0)
374 {
375 int lev = OpenSlideGTK.TileUtil.GetLevel(_openSlideBase.Schema.Resolutions, Resolution);
376 lev = Math.Clamp(lev, 0, _openSlideBase.Schema.Resolutions.Count - 1);
377 return _openSlideBase.Schema.Resolutions[lev].UnitsPerPixel * pxWmicron;
378 }
379 }
380 else
381 {
382 if (_slideBase?.Schema?.Resolutions != null && _slideBase.Schema.Resolutions.Count > 0)
383 {
384 int lev = OpenSlideGTK.TileUtil.GetLevel(_slideBase.Schema.Resolutions, Resolution);
385 lev = Math.Clamp(lev, 0, _slideBase.Schema.Resolutions.Count - 1);
386 return _slideBase.Schema.Resolutions[lev].UnitsPerPixel * pxWmicron;
387 }
388 }
389
390 return pxWmicron;
391 }
392 set
393 {
394 pxWmicron = value;
395 }
396 }

◆ PyramidalOrigin

PointD BioGTK.ImageView.PyramidalOrigin
getset

Definition at line 3788 of file ImageView.cs.

3789 {
3790 get
3791 {
3792 return SelectedImage.PyramidalOrigin;
3793 }
3794 set
3795 {
3796 if (!AllowNavigation)
3797 return;
3798 SelectedImage.PyramidalOrigin = value;
3799 if (!MacOS)
3800 {
3801 double viewWorldW = Math.Max(1, View?.AllocatedWidth ?? 1) * Resolution;
3802 double viewWorldH = Math.Max(1, View?.AllocatedHeight ?? 1) * Resolution;
3803 double worldRangeX = Math.Max(0, hScroll.Adjustment.Upper - hScroll.Adjustment.Lower);
3804 double worldRangeY = Math.Max(0, vScroll.Adjustment.Upper - vScroll.Adjustment.Lower);
3805 bool canPanX = SelectedImage?.isPyramidal == true && worldRangeX > viewWorldW;
3806 bool canPanY = SelectedImage?.isPyramidal == true && worldRangeY > viewWorldH;
3807
3808 double maxX = Math.Max(hScroll.Adjustment.Lower, hScroll.Adjustment.Upper - hScroll.Adjustment.PageSize);
3809 double maxY = Math.Max(vScroll.Adjustment.Lower, vScroll.Adjustment.Upper - vScroll.Adjustment.PageSize);
3810 double clampedX = canPanX
3811 ? Math.Clamp(value.X, hScroll.Adjustment.Lower, maxX)
3812 : value.X;
3813 double clampedY = canPanY
3814 ? Math.Clamp(value.Y, vScroll.Adjustment.Lower, maxY)
3815 : value.Y;
3816
3817 _updatingScrollBars = true;
3818 if (canPanX && hScroll.Value != clampedX)
3819 hScroll.Value = clampedX;
3820 if (canPanY && vScroll.Value != clampedY)
3821 vScroll.Value = clampedY;
3822 _updatingScrollBars = false;
3823 }
3824 if (_suppressViewUpdates)
3825 return;
3826
3827 if (SelectedImage?.isPyramidal == true)
3828 {
3829 slideRenderer?.InvalidateRenderState();
3830 sKSlideRenderer?.InvalidateRenderState();
3831 UpdateView();
3832 }
3833 else if (View != null)
3834 {
3835 UpdateImages();
3836 View.QueueDraw();
3837 }
3838 }
3839 }

◆ PyramidalOriginTransformed

PointD BioGTK.ImageView.PyramidalOriginTransformed
getset

Definition at line 3781 of file ImageView.cs.

3782 {
3783 get { return new PointD(PyramidalOrigin.X * Resolution, PyramidalOrigin.Y * Resolution); }
3784 set { PyramidalOrigin = new PointD(value.X / Resolution, value.Y / Resolution); }
3785 }

◆ RChannel

Channel BioGTK.ImageView.RChannel
get

Definition at line 3730 of file ImageView.cs.

3731 {
3732 get
3733 {
3734 return SelectedImage.Channels[SelectedImage.rgbChannels[0]];
3735 }
3736 }

◆ Resolution

double BioGTK.ImageView.Resolution
getset

Definition at line 3872 of file ImageView.cs.

3873 {
3874 get
3875 {
3876 if (!SelectedImage.isPyramidal)
3877 return 1;
3878 return SelectedImage.Resolution;
3879 }
3880 set
3881 {
3882 if (SelectedImage.isPyramidal)
3883 SelectedImage.Resolution = value;
3884 if (!_suppressViewUpdates)
3885 {
3886 if (SelectedImage?.isPyramidal == true)
3887 UpdateView();
3888 else if (View != null)
3889 {
3890 try
3891 {
3892 UpdateImages();
3893 }
3894 catch (Exception)
3895 {
3896
3897 }
3898 if (!MacOS)
3899 glArea?.RequestRedraw();
3900 else
3901 View.QueueDraw();
3902 }
3903 }
3904 }
3905 }

◆ Scale

SizeF BioGTK.ImageView.Scale
getset

Definition at line 3964 of file ImageView.cs.

3965 {
3966 get
3967 {
3968 return scale;
3969 }
3970 set
3971 {
3972 scale = value;
3973 }
3974 }

◆ SelectedAnnotation

ROI BioGTK.ImageView.SelectedAnnotation
staticget

Definition at line 4444 of file ImageView.cs.

4445 {
4446 get
4447 {
4448 foreach (var item in SelectedImage.Annotations)
4449 {
4450 if (item.Selected)
4451 return item;
4452 }
4453 return null;
4454 }
4455 }

◆ selectedAnnotations

List<ROI> BioGTK.ImageView.selectedAnnotations
staticget

Definition at line 468 of file ImageView.cs.

469 {
470 get
471 {
472 List<ROI> rois = new List<ROI>();
473 foreach (var item in SelectedImage.Annotations)
474 {
475 if (item != null && item.Selected)
476 rois.Add(item);
477 }
478 if (App.viewer != null)
479 {
480 foreach (var item in App.viewer.GetZarrLabelOverlaysForImage(SelectedImage))
481 {
482 if (item != null && item.Selected)
483 rois.Add(item);
484 }
485 }
486 return rois;
487 }
488 }

◆ SelectedBuffer

AForge.Bitmap BioGTK.ImageView.SelectedBuffer
staticget

Definition at line 441 of file ImageView.cs.

442 {
443 get
444 {
445 int ind = SelectedImage.GetFrameIndex(SelectedImage.Coordinate.Z, SelectedImage.Coordinate.C, SelectedImage.Coordinate.T);
446 return SelectedImage.Buffers[ind];
447 }
448 }

◆ SelectedImage

BioImage BioGTK.ImageView.SelectedImage
staticgetset

Definition at line 3678 of file ImageView.cs.

3679 {
3680 get
3681 {
3682 if (App.viewer == null)
3683 return null;
3684 if (App.viewer.Images.Count == 0)
3685 return null;
3686 return App.viewer.Images[App.viewer.SelectedIndex];
3687 }
3688 set
3689 {
3690 if (value == null)
3691 return;
3692 if (App.viewer == null)
3693 App.viewer = ImageView.Create(value);
3694 App.viewer.Images[App.viewer.SelectedIndex] = value;
3695 }
3696 }

◆ SelectedIndex

int BioGTK.ImageView.SelectedIndex
getset

Definition at line 450 of file ImageView.cs.

451 {
452 get
453 {
454 if(selectedIndex >= Images.Count)
455 selectedIndex = Images.Count - 1;
456 return selectedIndex;
457 }
458 set
459 {
460 if (value >= 0 && value < Images.Count)
461 {
462 selectedIndex = value;
463 Images[selectedIndex] = SelectedImage;
464 }
465 }
466 }

◆ ShowMasks

bool BioGTK.ImageView.ShowMasks = true
getset

Definition at line 436 of file ImageView.cs.

436{ get; set; } = true;

◆ ShowOverview

bool BioGTK.ImageView.ShowOverview = true
getset

Definition at line 437 of file ImageView.cs.

437{ get; set; } = true;

◆ ShowROIs

bool BioGTK.ImageView.ShowROIs = true
get

Definition at line 4016 of file ImageView.cs.

4016{ get; private set; } = true;

◆ TopRightOrigin

PointD BioGTK.ImageView.TopRightOrigin
get

Definition at line 3773 of file ImageView.cs.

3774 {
3775 get
3776 {
3777 return new PointD((Origin.X - ((View.AllocatedWidth / 2) * pxWmicron)), (Origin.Y - ((View.AllocatedHeight / 2) * pxHmicron)));
3778 }
3779 }

◆ View

Widget BioGTK.ImageView.View
getset

Definition at line 4513 of file ImageView.cs.

4514 {
4515 get
4516 {
4517 if (currentView != null)
4518 return currentView;
4519 if (MacOS)
4520 return sk;
4521 return glArea;
4522 }
4523 set
4524 {
4525 currentView = value;
4526 if (value is SKDrawingArea drawingArea)
4527 sk = drawingArea;
4528 if (value is SlideGLArea slideGlArea)
4529 glArea = slideGlArea;
4530 }
4531 }

The documentation for this class was generated from the following file: