BioGTK  6.7.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.
 
Task< bool > PopulateSelectedZarrStatisticsAsync ()
 
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 3732 of file ImageView.cs.

3733 {
3734 Raw,
3735 Filtered,
3736 RGBImage,
3737 Emission,
3738 }

Constructor & Destructor Documentation

◆ ImageView()

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

Definition at line 605 of file ImageView.cs.

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

206 {
207 Images.Add(im);
208 selectedIndex = Images.Count - 1;
209 if (im.Resolutions[0].SizeX < 1920 && im.Resolutions[0].SizeY < 1080)
210 {
211 if (View != null)
212 {
213 View.WidthRequest = im.Resolutions[0].SizeX;
214 View.HeightRequest = im.Resolutions[0].SizeY;
215 }
216 else
217 {
218 View.WidthRequest = im.Resolutions[0].SizeX;
219 View.HeightRequest = im.Resolutions[0].SizeY;
220 }
221 }
222
223 Initialize();
224 InitPreview();
225 UpdateImages(true);
226 UpdateGUI();
227 App.roiManager?.UpdateAnnotationList();
228 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, im?.file ?? string.Empty);
229 }
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 1176 of file ImageView.cs.

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

◆ CopySelection()

void BioGTK.ImageView.CopySelection ( )

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

Definition at line 3692 of file ImageView.cs.

3693 {
3694 copys.Clear();
3695 string s = "";
3696 List<ROI> rois = new List<ROI>();
3697 rois.AddRange(SelectedImage.AnnotationsR);
3698 rois.AddRange(SelectedImage.AnnotationsG);
3699 rois.AddRange(SelectedImage.AnnotationsB);
3700 foreach (ROI item in rois)
3701 {
3702 if (item.Selected)
3703 {
3704 copys.Add(item);
3705 s += BioImage.ROIToString(item);
3706 }
3707 }
3708 Clipboard clipboard = Clipboard.Get(Gdk.Selection.Clipboard);
3709 clipboard.Text = s;
3710 }

◆ 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 585 of file ImageView.cs.

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

◆ 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 3191 of file ImageView.cs.

3192 {
3193 return new Cairo.Color((double)color.R / 255, (double)color.G / 255, (double)color.B / 255);
3194 }

◆ GetCoordinate()

ZCT BioGTK.ImageView.GetCoordinate ( )

It returns the coordinate of the selected image

Returns
The Coordinate property of the SelectedImage object.

Definition at line 136 of file ImageView.cs.

137 {
138 if (SelectedImage == null)
139 return new ZCT();
140 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, SelectedImage.Coordinate.Z, SelectedImage.Coordinate.C, SelectedImage.Coordinate.T);
141 return SelectedImage.Coordinate;
142 }

◆ GetScale()

double BioGTK.ImageView.GetScale ( )

Definition at line 4225 of file ImageView.cs.

4226 {
4227 return ToViewSizeW(ROI.selectBoxSize / Scale.Width);
4228 }

◆ GetSelectedROIs()

List< ROI > BioGTK.ImageView.GetSelectedROIs ( )

Definition at line 4275 of file ImageView.cs.

4276 {
4277 List<ROI> roi = new List<ROI>();
4278 List<ROI> rois = new List<ROI>();
4279 rois.AddRange(SelectedImage.AnnotationsR);
4280 rois.AddRange(SelectedImage.AnnotationsG);
4281 rois.AddRange(SelectedImage.AnnotationsB);
4282 foreach (ROI r in rois)
4283 {
4284 if (r.Selected)
4285 {
4286 roi.Add(r);
4287 }
4288 }
4289 return roi;
4290 }

◆ GoToImage() [1/2]

void BioGTK.ImageView.GoToImage ( )

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

Definition at line 4941 of file ImageView.cs.

4942 {
4943 GoToImage(SelectedIndex);
4944 }

◆ GoToImage() [2/2]

void BioGTK.ImageView.GoToImage ( int i)

Definition at line 5091 of file ImageView.cs.

5092 {
5093 if (i < 0 || Images.Count <= i)
5094 return;
5095 if (_isApplyingGoToImage)
5096 {
5097 _pendingGoToImageIndex = i;
5098 return;
5099 }
5100
5101 // Ensure viewport is valid before doing any math
5102 int vpW = View.AllocatedWidth;
5103 int vpH = View.AllocatedHeight;
5104
5105 if (vpW < 10 || vpH < 10)
5106 {
5107 void OnAllocated(object sender, SizeAllocatedArgs args)
5108 {
5109 if (args.Allocation.Width < 10 || args.Allocation.Height < 10)
5110 return;
5111
5112 View.SizeAllocated -= OnAllocated;
5113 GoToImage(i);
5114 }
5115
5116 View.SizeAllocated += OnAllocated;
5117 return;
5118 }
5119
5120 bool imageChanged = selectedIndex != i;
5121 _isApplyingGoToImage = true;
5122 _suppressViewUpdates = true;
5123 try
5124 {
5125 if (imageChanged)
5126 {
5127 selectedIndex = i;
5128 Initialize();
5129 InitPreview();
5130 UpdateGUI();
5131 }
5132
5133 BioImage currentImage = Images[i];
5134 if (currentImage == null)
5135 return;
5136
5137 if (currentImage.isPyramidal)
5138 {
5139 TryGetPyramidalViewerBounds(currentImage, out double imageMinX, out double imageMinY, out double imageMaxX, out double imageMaxY);
5140
5141 double imageWorldW = imageMaxX - imageMinX;
5142 double imageWorldH = imageMaxY - imageMinY;
5143 if (imageWorldW <= 0) imageWorldW = 1;
5144 if (imageWorldH <= 0) imageWorldH = 1;
5145
5146 double targetRes = Math.Max(imageWorldW / vpW, imageWorldH / vpH);
5147 if (targetRes <= 0) targetRes = 1;
5148
5149 Resolution = targetRes;
5150 UpdateScrollBars();
5151
5152 double viewWorldW = vpW * Resolution;
5153 double viewWorldH = vpH * Resolution;
5154 double originX = imageMinX - ((viewWorldW - imageWorldW) / 2.0);
5155 double originY = imageMinY - ((viewWorldH - imageWorldH) / 2.0);
5156 PyramidalOrigin = new PointD(originX, originY);
5157 }
5158 else
5159 {
5160 double imageWorldW = Math.Max(currentImage.Volume.Width, currentImage.SizeX * currentImage.PhysicalSizeX);
5161 double imageWorldH = Math.Max(currentImage.Volume.Height, currentImage.SizeY * currentImage.PhysicalSizeY);
5162 if (imageWorldW <= 0) imageWorldW = 1;
5163 if (imageWorldH <= 0) imageWorldH = 1;
5164
5165 double wx = vpW / (PxWmicron * imageWorldW);
5166 double wy = vpH / (PxHmicron * imageWorldH);
5167
5168 float fitScale = (float)Math.Min(wx, wy);
5169 if (fitScale <= 0) fitScale = 1;
5170
5171 Scale = new SizeF(fitScale, fitScale);
5172
5173 double viewWorldW = vpW / (PxWmicron * fitScale);
5174 double viewWorldH = vpH / (PxHmicron * fitScale);
5175 double originX = -currentImage.Volume.Location.X + ((viewWorldW - imageWorldW) / 2.0);
5176 double originY = -currentImage.Volume.Location.Y + ((viewWorldH - imageWorldH) / 2.0);
5177 Origin = new PointD(originX, originY);
5178 }
5179 }
5180 finally
5181 {
5182 _suppressViewUpdates = false;
5183 _isApplyingGoToImage = false;
5184 }
5185
5186 ForceNavigationRefresh();
5187 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, i);
5188
5189 if (_pendingGoToImageIndex.HasValue)
5190 {
5191 int pendingIndex = _pendingGoToImageIndex.Value;
5192 _pendingGoToImageIndex = null;
5193 if (pendingIndex != i)
5194 GoToImage(pendingIndex);
5195 }
5196 }

◆ 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 4622 of file ImageView.cs.

4623 {
4624 if (SelectedImage == null)
4625 return ToViewSpace(x, y);
4626 if (SelectedImage.isPyramidal)
4627 {
4628 // PyramidalOrigin is already in world coordinates. Convert the
4629 // screen-space mouse offset back into the same world space that
4630 // ToViewSpace() consumes.
4631 return new PointD(PyramidalOrigin.X + (x * Resolution),
4632 PyramidalOrigin.Y + (y * Resolution));
4633 }
4634 else
4635 return ToViewSpace(x, y);
4636 }
PointF ToViewSpace(PointF p)

◆ OnDestroyed()

override void BioGTK.ImageView.OnDestroyed ( )
protected

Definition at line 4565 of file ImageView.cs.

4566 {
4567 base.OnDestroyed();
4568 }

◆ OnMouseWheel()

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

Definition at line 3916 of file ImageView.cs.

3917 {
3918 double mouseX = e?.Event?.X ?? PyramidalOrigin.X;
3919 double mouseY = e?.Event?.Y ?? PyramidalOrigin.Y;
3920 if (e.Event.Direction == ScrollDirection.Up)
3921 ZoomAtPoint(mouseX, mouseY, false);
3922 else if (e.Event.Direction == ScrollDirection.Down)
3923 ZoomAtPoint(mouseX, mouseY, true);
3924 }

◆ 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 3713 of file ImageView.cs.

3714 {
3715 Clipboard clipboard = Clipboard.Get(Gdk.Selection.Clipboard);
3716 string text = clipboard.WaitForText();
3717 string[] sts = text.Split(BioImage.NewLine);
3718 foreach (string line in sts)
3719 {
3720 if (line.Length > 8)
3721 {
3722 ROI an = BioImage.StringToROI(line);
3723 //We set the coordinates of the ROI's we are pasting
3724 an.coord = GetCoordinate();
3725 SelectedImage.Annotations.Add(an);
3726 }
3727 }
3728 UpdateView();
3729 }
void UpdateView(bool updateImages=true)
It updates the view.

◆ PopulateSelectedZarrStatisticsAsync()

Task< bool > BioGTK.ImageView.PopulateSelectedZarrStatisticsAsync ( )

Definition at line 1803 of file ImageView.cs.

1804 {
1805 var image = SelectedImage;
1806 if (image?.IsZarrSource != true || slideRenderer == null)
1807 return Task.FromResult(false);
1808
1809 return slideRenderer.PopulateZarrStatisticsAsync(image, image.Coordinate);
1810 }

◆ RebuildSchemaForWell()

void BioGTK.ImageView.RebuildSchemaForWell ( BioImage b)

Definition at line 5354 of file ImageView.cs.

5355 {
5356 if (b.ZarrWellLevels == null || b.ZarrWellLevels.Count == 0)
5357 {
5358 return;
5359 }
5360 int fi = Math.Clamp(b.Level, 0, b.ZarrWellLevels.Count - 1);
5361 var fieldLevels = b.ZarrWellLevels[fi];
5362 if (fieldLevels == null || fieldLevels.Count == 0)
5363 {
5364 // Requested field not yet loaded — fall back to first non-null field
5365 // so the schema matches what TryReadRegionAsync will actually serve.
5366 fieldLevels = b.ZarrWellLevels.FirstOrDefault(l => l != null && l.Count > 0);
5367 if (fieldLevels == null)
5368 {
5369 return;
5370 }
5371 }
5372
5373 int w0 = 1, h0 = 1;
5374 GetFieldDims(fieldLevels[0], out w0, out h0);
5375
5376 var newSchema = new BruTile.TileSchema
5377 {
5378 YAxis = BruTile.YAxis.OSM,
5379 Format = "jpg",
5380 Extent = new BruTile.Extent(0, -h0, w0, 0),
5381 OriginX = 0,
5382 OriginY = 0,
5383 };
5384
5385 for (int lev = 0; lev < fieldLevels.Count; lev++)
5386 {
5387 GetFieldDims(fieldLevels[lev], out int wL, out int hL);
5388 double downsample = w0 > 0 ? (double)w0 / Math.Max(1, wL) : Math.Pow(2, lev);
5389 newSchema.Resolutions[lev] = new BruTile.Resolution(lev, downsample, 256, 256);
5390 }
5391
5392 var slideBase = SelectedImage?.OpenSlideBase;
5393 if (slideBase == null)
5394 {
5395 return;
5396 }
5397 //OpenSlideBase op = new OpenSlideBase(SelectedImage.Filename);
5398 slideBase.Schema = newSchema;
5399 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, b?.file ?? string.Empty, b?.Level ?? 0);
5400 }

◆ RefreshPyramidalTiles()

void BioGTK.ImageView.RefreshPyramidalTiles ( )

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

Definition at line 1786 of file ImageView.cs.

1787 {
1788 if (SelectedImage?.isPyramidal != true)
1789 return;
1790
1791 // Threshold/channel edits invalidate pixels but do not require socket
1792 // aborts. Let older Zarr reads drain and discard them by render version.
1793 slideRenderer?.InvalidateRenderState(cancelActiveFetches: false);
1794 sKSlideRenderer?.InvalidateRenderState();
1795 SelectedImage.InvalidateTileCache();
1796 slideRenderer?.ClearCache(resetLevel: false, cancelActiveFetches: false);
1797 sKSlideRenderer?.ClearCache();
1798 SelectedImage.ZarrDisplayMax = 0;
1799 _overviewSource = null;
1800 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, SelectedImage?.file ?? string.Empty);
1801 }
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(bool cancelActiveFetches=true)
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 249 of file ImageView.cs.

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

◆ RefreshZarrLabelOverlays() [2/2]

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

Definition at line 244 of file ImageView.cs.

245 {
246 RefreshZarrLabelOverlays(SelectedImage, sourceOverride);
247 }

◆ 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 5279 of file ImageView.cs.

5280 {
5281 if (SelectedImage?.Type != BioImage.ImageType.well) return;
5282 if (_slideBase == null) return;
5283
5284 _slideBase.RebuildSchemaForWell(SelectedImage);
5285 NormalizeOsmSchemaOrigin(_slideBase, SelectedImage);
5286
5287 if (MacOS) sKSlideRenderer?.SetSource(_slideBase);
5288 else slideRenderer?.SetSource(_slideBase);
5289
5290 // GoToImage resets the viewport to fit the new field and triggers a render.
5291 GoToImage(selectedIndex);
5292 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, SelectedImage?.file ?? string.Empty, SelectedImage.WellIndex);
5293 }

◆ RequestDeferredRender()

void BioGTK.ImageView.RequestDeferredRender ( )

Definition at line 1392 of file ImageView.cs.

1393 {
1394 if (_viewerCleanupDone)
1395 return;
1396 if (System.Threading.Interlocked.Exchange(ref _deferredRenderQueued, 1) == 1)
1397 return;
1398
1399 GLib.Timeout.Add(16, () =>
1400 {
1401 if (_viewerCleanupDone)
1402 {
1403 System.Threading.Interlocked.Exchange(ref _deferredRenderQueued, 0);
1404 return false;
1405 }
1406
1407 try
1408 {
1409 ExecuteDeferredRender();
1410 }
1411 finally
1412 {
1413 System.Threading.Interlocked.Exchange(ref _deferredRenderQueued, 0);
1414 }
1415 return false;
1416 });
1417 }

◆ RequestImmediateRender()

void BioGTK.ImageView.RequestImmediateRender ( )

Definition at line 1254 of file ImageView.cs.

1255 {
1256 UpdateView(true);
1257 }

◆ 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 (coordinateChanged)
70 App.channelsTool?.RefreshStatisticsForCoordinate(SelectedImage, SelectedImage.Coordinate);
71 if (SelectedImage.isPyramidal && coordinateChanged)
72 {
73 PreparePyramidalCoordinateRender();
74 ForceNavigationRefresh();
75 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, z, c, t);
76 return;
77 }
78
80 if (SelectedImage?.isPyramidal != true && View != null)
81 {
82 RequestViewportRefresh();
83 }
84 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, z, c, t);
85 }

◆ SetTitle()

void BioGTK.ImageView.SetTitle ( string s)

Definition at line 1586 of file ImageView.cs.

1587 {
1588 this.Title = s;
1589 }

◆ SetupHandlers()

void BioGTK.ImageView.SetupHandlers ( )
protected

Sets up the handlers.

Definition at line 2307 of file ImageView.cs.

2308 {
2309 View.Realized += View_Realized;
2310 this.Shown += ImageView_Shown;
2311 zBar.ValueChanged += ValueChangedZ;
2312 cBar.ValueChanged += ValueChangedC;
2313 tBar.ValueChanged += ValueChangedT;
2314 zBar.ScrollEvent += ZBar_ScrollEvent;
2315 cBar.ScrollEvent += CBar_ScrollEvent;
2316 tBar.ScrollEvent += TBar_ScrollEvent;
2317 zBar.AddEvents((int)EventMask.ScrollMask);
2318 cBar.AddEvents((int)EventMask.ScrollMask);
2319 tBar.AddEvents((int)EventMask.ScrollMask);
2320 this.ScrollEvent += ImageView_WindowScrollEvent;
2321 this.AddEvents((int)EventMask.ScrollMask);
2322 if (MacOS)
2323 {
2324 View.MotionNotifyEvent += ImageView_MotionNotifyEvent;
2325 View.ButtonPressEvent += ImageView_ButtonPressEvent;
2326 View.ButtonReleaseEvent += ImageView_ButtonReleaseEvent;
2327 View.ScrollEvent += ImageView_ScrollEvent;
2328 // OnMouseWheel is intentionally NOT registered here: ImageView_ScrollEvent already
2329 // handles zoom-to-cursor via SetResolution. Registering both causes double-zoom jumps.
2330 ((SKDrawingArea)View).PaintSurface += Sk_PaintSurface;
2331 View.SizeAllocated += PictureBox_SizeAllocated;
2332 View.SetSizeRequest(600, 400);
2333 View.AddEvents((int)(EventMask.ButtonPressMask
2334 | EventMask.ButtonReleaseMask
2335 | EventMask.KeyPressMask
2336 | EventMask.PointerMotionMask
2337 | EventMask.ScrollMask));
2338 }
2339 else
2340 {
2341 View.MotionNotifyEvent += ImageView_MotionNotifyEvent;
2342 View.ButtonPressEvent += ImageView_ButtonPressEvent;
2343 View.ButtonReleaseEvent += ImageView_ButtonReleaseEvent;
2344 View.ScrollEvent += ImageView_ScrollEvent;
2345 // OnMouseWheel removed: ImageView_ScrollEvent handles zoom-to-cursor via SetResolution.
2346 if (glArea != null)
2347 glArea.Render += GlArea_Render;
2348 View.SizeAllocated += PictureBox_SizeAllocated;
2349 View.AddEvents((int)(EventMask.ButtonPressMask
2350 | EventMask.ButtonReleaseMask
2351 | EventMask.KeyPressMask
2352 | EventMask.PointerMotionMask
2353 | EventMask.ScrollMask));
2354 }
2355 vScroll.ValueChanged += VScroll_ValueChanged;
2356 hScroll.ValueChanged += HScroll_ValueChanged;
2357 this.KeyPressEvent += ImageView_KeyPressEvent;
2358 this.DestroyEvent += ImageView_DestroyEvent;
2359 this.DeleteEvent += ImageView_DeleteEvent;
2360 this.FocusInEvent += ImageView_FocusInEvent;
2361 rBox.Changed += RBox_Changed;
2362 gBox.Changed += GBox_Changed;
2363 bBox.Changed += BBox_Changed;
2364 //Context Menu
2365 goToImageMenu.ButtonPressEvent += GoToImageMenu_ButtonPressEvent;
2366 goToOriginMenu.ButtonPressEvent += GoToOriginMenu_ButtonPressEvent;
2367 overView.ButtonPressEvent += OverView_ButtonPressEvent;
2368
2369 roiShow.ButtonPressEvent += RoiShow_ButtonPressEvent;
2370 roiHide.ButtonPressEvent += RoiHide_ButtonPressEvent;
2371 roiDelete.ButtonPressEvent += RoiDelete_ButtonPressEvent;
2372 roiID.ButtonPressEvent += RoiID_ButtonPressEvent;
2373 copy.ButtonPressEvent += Copy_ButtonPressEvent;
2374 paste.ButtonPressEvent += Paste_ButtonPressEvent;
2375 draw.ButtonPressEvent += Draw_ButtonPressEvent;
2376 fill.ButtonPressEvent += Fill_ButtonPressEvent;
2377
2378 play.ButtonPressEvent += Play_ButtonPressEvent;
2379 stop.ButtonPressEvent += Stop_ButtonPressEvent;
2380 playSpeed.ButtonPressEvent += PlaySpeed_ButtonPressEvent;
2381 setValueRange.ButtonPressEvent += SetValueRange_ButtonPressEvent;
2382 loop.ButtonPressEvent += Loop_ButtonPressEvent;
2383
2384 zBar.ButtonPressEvent += ZBar_ButtonPressEvent;
2385 tBar.ButtonPressEvent += TBar_ButtonPressEvent;
2386 cBar.ButtonPressEvent += CBar_ButtonPressEvent;
2387
2388 }

◆ SetZarrLabelOverlays()

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

Definition at line 231 of file ImageView.cs.

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

◆ 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 4936 of file ImageView.cs.

4937 {
4938 return (float)(y * PxHmicron);
4939 }

◆ 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 4849 of file ImageView.cs.

4850 {
4851 if (SelectedImage == null)
4852 {
4853 double dx = (pxWmicron * (-Origin.X)) * Scale.Width;
4854 double dy = (pxHmicron * (-Origin.Y)) * Scale.Height;
4855 RectangleD rf = new RectangleD((PxWmicron * x * Scale.Width + dx), (PxHmicron * y * Scale.Height + dy), (PxWmicron * w * Scale.Width), (PxHmicron * h * Scale.Height));
4856 return rf;
4857 }
4858 if (SelectedImage.isPyramidal)
4859 {
4860 PointD d = ToViewSpace(x, y);
4861 double dw = ToViewSizeW(w);
4862 double dh = ToViewSizeH(h);
4863 return new RectangleD(d.X, d.Y, dw, dh);
4864 }
4865 else
4866 {
4867 double dx = (pxWmicron * (Origin.X)) * Scale.Width;
4868 double dy = (pxHmicron * (Origin.Y)) * Scale.Height;
4869 RectangleD rf = new RectangleD((PxWmicron * x * Scale.Width + dx), (PxHmicron * y * Scale.Height + dy), (PxWmicron * w * Scale.Width), (PxHmicron * h * Scale.Height));
4870 return rf;
4871 }
4872 }
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 4835 of file ImageView.cs.

4836 {
4837 float x = ToScreenScaleW((float)p.X);
4838 float y = ToScreenScaleH((float)p.Y);
4839 return new PointF(x, y);
4840 }
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 4826 of file ImageView.cs.

4827 {
4828 return (float)(-y * PxHmicron * Scale.Height);
4829 }

◆ 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 4817 of file ImageView.cs.

4818 {
4819 return (float)(-x * PxWmicron * Scale.Width);
4820 }

◆ 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 4764 of file ImageView.cs.

4765 {
4766 RectangleD f = ToScreenRect(x, y, 1, 1);
4767 return new PointD(f.X, f.Y);
4768 }
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 4807 of file ImageView.cs.

4808 {
4809 PointD pd = ToScreenSpace(p.X, p.Y);
4810 return new PointF((float)pd.X, (float)pd.Y);
4811 }
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 4774 of file ImageView.cs.

4775 {
4776 return ToScreenSpace(p.X, p.Y);
4777 }

◆ 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 4912 of file ImageView.cs.

4913 {
4914 PointD[] rs = new PointD[p.Length];
4915 for (int i = 0; i < p.Length; i++)
4916 {
4917 PointD pd = ToScreenSpace(p[i]);
4918 rs[i] = new PointD((float)pd.X, (float)pd.Y);
4919 }
4920 return rs;
4921 }

◆ 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 4783 of file ImageView.cs.

4784 {
4785 PointD pd = ToScreenSpace(p.X, p.Y);
4786 return new PointF((float)pd.X, (float)pd.Y);
4787 }

◆ 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 4793 of file ImageView.cs.

4794 {
4795 PointF[] pf = new PointF[p.Length];
4796 for (int i = 0; i < p.Length; i++)
4797 {
4798 pf[i] = ToScreenSpace(p[i]);
4799 }
4800 return pf;
4801 }

◆ 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 4879 of file ImageView.cs.

4880 {
4881 return ToScreenRect(p.X, p.Y, p.W, p.H);
4882 }

◆ 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 4897 of file ImageView.cs.

4898 {
4899 RectangleD[] rs = new RectangleD[p.Length];
4900 for (int i = 0; i < p.Length; i++)
4901 {
4902 rs[i] = ToScreenSpace(p[i]);
4903 }
4904 return rs;
4905 }

◆ 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 4888 of file ImageView.cs.

4889 {
4890 return ToScreenRect(p.X, p.Y, p.Width, p.Height);
4891 }

◆ 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 4927 of file ImageView.cs.

4928 {
4929 return (float)(x * PxWmicron);
4930 }

◆ 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 4748 of file ImageView.cs.

4749 {
4750 if (SelectedImage != null)
4751 if (SelectedImage.isPyramidal)
4752 {
4753 return d / Resolution;
4754 }
4755 double y = (double)(d / PxHmicron) / scale.Height;
4756 return y;
4757 }

◆ 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 4718 of file ImageView.cs.

4719 {
4720 if (SelectedImage != null)
4721 if (SelectedImage.isPyramidal)
4722 {
4723 return d / Resolution;
4724 }
4725 double y = (double)(d / PxHmicron);
4726 return y;
4727 }

◆ ToViewSpace() [1/3]

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

Definition at line 4675 of file ImageView.cs.

4676 {
4677 if (SelectedImage == null)
4678 {
4679 double dx = (ToViewSizeW(x - (View.AllocatedWidth / 2)) / Scale.Width) - Origin.X;
4680 double dy = (ToViewSizeH(y - (View.AllocatedHeight / 2)) / Scale.Height) - Origin.Y;
4681 return new PointD(dx, dy);
4682 }
4683 if (SelectedImage.isPyramidal)
4684 {
4685 // x, y are world (full-resolution pixel) coordinates.
4686 // Subtract the viewport origin and divide by Resolution to get screen pixels.
4687 return new PointD((x - PyramidalOrigin.X) / Resolution,
4688 (y - PyramidalOrigin.Y) / Resolution);
4689 }
4690 else
4691 {
4692 double dx = (ToViewSizeW(x - (View.AllocatedWidth / 2)) / Scale.Width) - Origin.X;
4693 double dy = (ToViewSizeH(y - (View.AllocatedHeight / 2)) / Scale.Height) - Origin.Y;
4694 return new PointD(dx, dy);
4695 }
4696 }

◆ 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 4652 of file ImageView.cs.

4653 {
4654 return ToViewSpace(p.X, p.Y); ;
4655 }

◆ 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 4642 of file ImageView.cs.

4643 {
4644 PointD d = ToViewSpace(p.X, p.Y);
4645 return new PointF((float)d.X, (float)d.Y);
4646 }

◆ 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 4733 of file ImageView.cs.

4734 {
4735 if (SelectedImage != null)
4736 if (SelectedImage.isPyramidal)
4737 {
4738 return d / Resolution;
4739 }
4740 double x = (double)(d / PxWmicron) / scale.Width;
4741 return x;
4742 }

◆ UpdateGUI()

void BioGTK.ImageView.UpdateGUI ( )

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

Definition at line 3546 of file ImageView.cs.

3547 {
3548 if (SelectedImage == null)
3549 return;
3550 if (_updatingGui)
3551 return;
3552
3553 _updatingGui = true;
3554 try
3555 {
3556 EnsureImageChannels(SelectedImage);
3557 cBar.Adjustment.Lower = 0;
3558 cBar.Adjustment.Upper = Images[selectedIndex].SizeC - 1;
3559 zBar.Adjustment.Lower = 0;
3560 zBar.Adjustment.Upper = Images[selectedIndex].SizeZ - 1;
3561 tBar.Adjustment.Lower = 0;
3562 tBar.Adjustment.Upper = Images[selectedIndex].SizeT - 1;
3563 if (endz == 0 || endz > Images[selectedIndex].SizeZ - 1)
3564 endz = Images[selectedIndex].SizeZ - 1;
3565 if (endc == 0 || endc > Images[selectedIndex].SizeC - 1)
3566 endc = Images[selectedIndex].SizeC - 1;
3567 if (endt == 0 || endt > Images[selectedIndex].SizeT - 1)
3568 endt = Images[selectedIndex].SizeT - 1;
3569 UpdateScrollBars();
3570 var store = new ListStore(typeof(string));
3571 for (int i = 0; i < SelectedImage.Channels.Count; i++)
3572 {
3573 store.AppendValues(GetChannelDisplayLabel(SelectedImage.Channels[i], i));
3574 }
3575 rBox.Model = store;
3576 gBox.Model = store;
3577 bBox.Model = store;
3578 if (SelectedImage.Channels.Count > 0)
3579 {
3580 int lastChannel = SelectedImage.Channels.Count - 1;
3581 rBox.Active = Math.Clamp(SelectedImage.rgbChannels[0], 0, lastChannel);
3582 gBox.Active = Math.Clamp(SelectedImage.rgbChannels[1], 0, lastChannel);
3583 bBox.Active = Math.Clamp(SelectedImage.rgbChannels[2], 0, lastChannel);
3584 }
3585 imagesMenu = new Menu();
3586 for (int i = 0; i < Images.Count; i++)
3587 {
3588 if (Images[i] == null)
3589 {
3590 if (SelectedIndex >= Images.Count)
3591 SelectedIndex--;
3592 Images.RemoveAt(i);
3593 }
3594 MenuItem mi = new MenuItem(Images[i].Filename);
3595 mi.ButtonPressEvent += Mi_ButtonPressEvent;
3596 imagesMenu.Append(mi);
3597 }
3598 goToImageMenu.Submenu = imagesMenu;
3599 goToImageMenu.ShowAll();
3600 }
3601 finally
3602 {
3603 _updatingGui = false;
3604 }
3605 }

◆ UpdateImage()

void BioGTK.ImageView.UpdateImage ( )

It updates the image.

Definition at line 1777 of file ImageView.cs.

1778 {
1779 UpdateImages();
1780 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false);
1781 }

◆ UpdateImages()

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

It updates the images.

Definition at line 1620 of file ImageView.cs.

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

4052 {
4053 if (SelectedImage.Buffers.Count == 0 &&
4054 SelectedImage.Type != BioImage.ImageType.well &&
4055 !SelectedImage.IsZarrSource)
4056 return;
4057 string formattedResolution = FormatResolution(Resolution);
4058 if (SelectedImage.Type == BioImage.ImageType.stack)
4059 statusLabel.Text = (zBar.Value + 1) + "/" + (zBar.Adjustment.Upper + 1) + ", " + (cBar.Value + 1) + "/" + (cBar.Adjustment.Upper + 1) + ", " + (tBar.Value + 1) + "/" + (tBar.Adjustment.Upper + 1) + ", " +
4060 mousePoint + mouseColor + ", " + SelectedImage.Resolutions[0].PixelFormat.ToString() + ", (" + SelectedImage.Volume.Location.X.ToString("N2") + ", " + SelectedImage.Volume.Location.Y.ToString("N2") + ") "
4061 + Origin.X.ToString("N2") + "," + Origin.Y.ToString("N2") + ", Res:" + formattedResolution + " Level:" + Level;
4062 else if (SelectedImage.Type == BioImage.ImageType.pyramidal ||
4063 SelectedImage.Type == BioImage.ImageType.well)
4064 {
4065 string wellStatus = SelectedImage.Type == BioImage.ImageType.well
4066 ? ", WellIndex:" + SelectedImage.WellIndex
4067 : string.Empty;
4068 statusLabel.Text = (zBar.Value + 1) + "/" + (zBar.Adjustment.Upper + 1) + ", " + (cBar.Value + 1) + "/" + (cBar.Adjustment.Upper + 1) + ", " + (tBar.Value + 1) + "/" + (tBar.Adjustment.Upper + 1) + ", " +
4069 mousePoint + mouseColor + ", " + SelectedImage.Resolutions[0].PixelFormat.ToString() + ", (" + SelectedImage.Volume.Location.X.ToString("N2") + ", " + SelectedImage.Volume.Location.Y.ToString("N2") + ") "
4070 + PyramidalOrigin.X.ToString("N2") + "," + PyramidalOrigin.Y.ToString("N2") + " , Level:" + Level + " Res:" + formattedResolution + wellStatus;
4071 }
4072 }

◆ UpdateView()

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

It updates the view.

Definition at line 4086 of file ImageView.cs.

4087 {
4088 refresh = true;
4089 if (SelectedImage?.isPyramidal == true)
4090 {
4091 RequestDeferredRender();
4092 }
4093 else
4094 {
4095 UpdateImages(true);
4096 RequestViewportRefresh();
4097 }
4098 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, updateImages);
4099 }

◆ ZoomAtPoint() [1/2]

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

Definition at line 3925 of file ImageView.cs.

3926 {
3927 if (SelectedImage == null || !SelectedImage.isPyramidal) return;
3928
3929 int currentLevel = Level;
3930 int nextLevel = zoomIn
3931 ? Math.Max(0, currentLevel - 1)
3932 : Math.Min(SelectedImage.Resolutions.Count - 1, currentLevel + 1);
3933
3934 if (nextLevel == currentLevel)
3935 return;
3936
3937 double currentResolution = SelectedImage.GetUnitPerPixel(currentLevel);
3938 double nextResolution = SelectedImage.GetUnitPerPixel(nextLevel);
3939 if (currentResolution <= 0 || nextResolution <= 0)
3940 return;
3941
3942 // Batch the level/origin change so zoom only triggers one viewport
3943 // update instead of two separate renders.
3944 SetResolution(nextResolution, new PointD(mouseX, mouseY));
3945 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, mouseX, mouseY, zoomIn);
3946 }

◆ ZoomAtPoint() [2/2]

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

Definition at line 4291 of file ImageView.cs.

4292 {
4293 if (SelectedImage == null) return;
4294
4295 // 1. Define zoom factor (e.g., 2.0x zoom steps)
4296 float zoomFactor = zoomIn ? 2.0f : 0.5f;
4297
4298 // 2. Get the current level's scale relative to Full Res (Level 0)
4299 // Formula: CurrentLevelWidth / FullResWidth
4300 double currentLevelScale = (double)SelectedImage.Resolutions[SelectedImage.Level].SizeX / SelectedImage.SizeX;
4301
4302 // 3. Find the "World Point" (Full Res Level 0) currently under the mouse
4303 // We add the origin to the mouse offset and then scale up to Level 0
4304 double worldX = (PyramidalOrigin.X + mouseX) / currentLevelScale;
4305 double worldY = (PyramidalOrigin.Y + mouseY) / currentLevelScale;
4306
4307 // 4. Update your Level logic here
4308 // This is where you switch your 'CurrentLevelWidth' to the next level in the pyramid
4309 //UpdateLevel(zoomIn);
4310
4311 // 5. Get the NEW level's scale relative to Full Res
4312 double newLevelScale = (double)SelectedImage.Resolutions[SelectedImage.Level].SizeX / SelectedImage.SizeX;
4313
4314 // 6. Calculate the NEW PyramidalOrigin
4315 // To keep the world point at the same mouse position:
4316 // NewOrigin = (WorldPoint * NewScale) - MouseOffset
4317 float newOriginX = (float)(worldX * newLevelScale - mouseX);
4318 float newOriginY = (float)(worldY * newLevelScale - mouseY);
4319
4320 // 7. Apply and Clamp (to ensure we don't scroll past image edges)
4321 TryGetPyramidalViewerBounds(SelectedImage, out double imageMinX, out double imageMinY, out double imageMaxX, out double imageMaxY);
4322 double viewWorldW = Math.Max(1, View?.AllocatedWidth ?? 1) * Resolution;
4323 double viewWorldH = Math.Max(1, View?.AllocatedHeight ?? 1) * Resolution;
4324 PyramidalOrigin = new PointD(
4325 ClampPyramidalOrigin(newOriginX, imageMinX, imageMaxX, viewWorldW),
4326 ClampPyramidalOrigin(newOriginY, imageMinY, imageMaxY, viewWorldH)
4327 );
4328 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, mouseX, mouseY, zoomIn);
4329 }

Member Data Documentation

◆ contextMenu

Menu BioGTK.ImageView.contextMenu

Definition at line 524 of file ImageView.cs.

◆ endc

int BioGTK.ImageView.endc = 0
static

Definition at line 2557 of file ImageView.cs.

◆ endt

int BioGTK.ImageView.endt = 0
static

Definition at line 2558 of file ImageView.cs.

◆ endz

int BioGTK.ImageView.endz = 0
static

Definition at line 2556 of file ImageView.cs.

◆ glArea

SlideGLArea BioGTK.ImageView.glArea

Definition at line 570 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 3315 of file ImageView.cs.

◆ MacOS

bool BioGTK.ImageView.MacOS = false
static

Definition at line 574 of file ImageView.cs.

◆ mainBox

Gtk.Box BioGTK.ImageView.mainBox

Definition at line 512 of file ImageView.cs.

◆ Modifiers

ModifierType BioGTK.ImageView.Modifiers
static

Definition at line 4232 of file ImageView.cs.

◆ mouseLeftState

bool BioGTK.ImageView.mouseLeftState
static

Definition at line 4231 of file ImageView.cs.

◆ selectedROI

ROI BioGTK.ImageView.selectedROI = new ROI()

Definition at line 4241 of file ImageView.cs.

◆ showBROIs

bool BioGTK.ImageView.showBROIs = true

Definition at line 4214 of file ImageView.cs.

◆ showGROIs

bool BioGTK.ImageView.showGROIs = true

Definition at line 4213 of file ImageView.cs.

◆ showRROIs

bool BioGTK.ImageView.showRROIs = true

Definition at line 4212 of file ImageView.cs.

◆ sKSlideRenderer

SKSlideRenderer BioGTK.ImageView.sKSlideRenderer

Definition at line 572 of file ImageView.cs.

◆ slideRenderer

SlideRenderer BioGTK.ImageView.slideRenderer

Definition at line 571 of file ImageView.cs.

◆ startc

int BioGTK.ImageView.startc = 0
static

Definition at line 2554 of file ImageView.cs.

◆ startt

int BioGTK.ImageView.startt = 0
static

Definition at line 2555 of file ImageView.cs.

◆ startz

int BioGTK.ImageView.startz = 0
static

Definition at line 2553 of file ImageView.cs.

◆ waitc

int BioGTK.ImageView.waitc = 1000
static

Definition at line 2551 of file ImageView.cs.

◆ waitt

int BioGTK.ImageView.waitt = 1000
static

Definition at line 2552 of file ImageView.cs.

◆ waitz

int BioGTK.ImageView.waitz = 1000
static

Definition at line 2550 of file ImageView.cs.

◆ window

GLWindow BioGTK.ImageView.window

Definition at line 573 of file ImageView.cs.

◆ x1State

bool BioGTK.ImageView.x1State
static

Definition at line 4229 of file ImageView.cs.

◆ x2State

bool BioGTK.ImageView.x2State
static

Definition at line 4230 of file ImageView.cs.

Property Documentation

◆ AllowNavigation

bool BioGTK.ImageView.AllowNavigation
getset

Definition at line 435 of file ImageView.cs.

436 {
437 get { return allowNavigation; }
438 set { allowNavigation = value; }
439 }

◆ BChannel

Channel BioGTK.ImageView.BChannel
get

Definition at line 3813 of file ImageView.cs.

3814 {
3815 get
3816 {
3817 return SelectedImage.Channels[SelectedImage.rgbChannels[2]];
3818 }
3819 }

◆ GChannel

Channel BioGTK.ImageView.GChannel
get

Definition at line 3805 of file ImageView.cs.

3806 {
3807 get
3808 {
3809 return SelectedImage.Channels[SelectedImage.rgbChannels[1]];
3810 }
3811 }

◆ ImageViewHeight

double BioGTK.ImageView.ImageViewHeight
get

Definition at line 4608 of file ImageView.cs.

4609 {
4610 get
4611 {
4612 double d = View.AllocatedHeight / Resolution;
4613 return d;
4614 }
4615 }

◆ ImageViewWidth

double BioGTK.ImageView.ImageViewWidth
get

Definition at line 4600 of file ImageView.cs.

4601 {
4602 get
4603 {
4604 double d = View.AllocatedWidth / Resolution;
4605 return d;
4606 }
4607 }

◆ LabelResolution

int? BioGTK.ImageView.LabelResolution
get

Definition at line 1832 of file ImageView.cs.

1832{ get { return SelectedImage.LabelResolution; } }

◆ Level

int BioGTK.ImageView.Level
getset

Definition at line 4006 of file ImageView.cs.

4007 {
4008 get
4009 {
4010 return SelectedImage.LevelFromResolution(SelectedImage.Resolution);
4011 }
4012 set
4013 {
4014 if (value < 0)
4015 return;
4016 if (SelectedImage?.Type == BioImage.ImageType.well)
4017 {
4018 if (l != value)
4019 l = value;
4020 SelectedImage.Level = value;
4021 UpdateScrollBars();
4022 if (View != null)
4023 {
4024 UpdateImages();
4025 View.QueueDraw();
4026 }
4027 return;
4028 }
4029 if (l != value)
4030 UpdateLevel();
4031 l = value;
4032 SelectedImage.Level = l;
4033 UpdateScrollBars();
4034 }
4035 }

◆ MacroResolution

int? BioGTK.ImageView.MacroResolution
get

Definition at line 1831 of file ImageView.cs.

1831{ get { return SelectedImage.MacroResolution; } }

◆ Mode

ViewMode BioGTK.ImageView.Mode
getset

Definition at line 3766 of file ImageView.cs.

3767 {
3768 get
3769 {
3770 return viewMode;
3771 }
3772 set
3773 {
3774 viewMode = value;
3775 if (viewMode == ViewMode.RGBImage)
3776 {
3777 rgbStack.VisibleChild = rgbStack.Children[1];
3778 }
3779 else
3780 if (viewMode == ViewMode.Filtered)
3781 {
3782 rgbStack.VisibleChild = rgbStack.Children[0];
3783 }
3784 else
3785 if (viewMode == ViewMode.Raw)
3786 {
3787 rgbStack.VisibleChild = rgbStack.Children[0];
3788 }
3789 else
3790 {
3791 rgbStack.VisibleChild = rgbStack.Children[0];
3792 }
3793 RefreshDisplayState(invalidatePyramidalTiles: true);
3794 }
3795 }

◆ MouseDown

PointD BioGTK.ImageView.MouseDown
getset

Definition at line 4258 of file ImageView.cs.

4259 {
4260 get { return mouseDown; }
4261 set { mouseDown = value; }
4262 }

◆ MouseDownInt

PointD BioGTK.ImageView.MouseDownInt
getset

Definition at line 4243 of file ImageView.cs.

4244 {
4245 get { return mouseDownInt; }
4246 set { mouseDownInt = value; }
4247 }

◆ MouseMove

PointD BioGTK.ImageView.MouseMove
getset

Definition at line 4268 of file ImageView.cs.

4269 {
4270 get { return mouseMove; }
4271 set { mouseMove = value; }
4272 }

◆ MouseMoveInt

PointD BioGTK.ImageView.MouseMoveInt
getset

Definition at line 4248 of file ImageView.cs.

4249 {
4250 get { return mouseMoveInt; }
4251 set { mouseMoveInt = value; }
4252 }

◆ MouseUp

PointD BioGTK.ImageView.MouseUp
getset

Definition at line 4263 of file ImageView.cs.

4264 {
4265 get { return mouseUp; }
4266 set { mouseUp = value; }
4267 }

◆ MouseUpInt

PointD BioGTK.ImageView.MouseUpInt
getset

Definition at line 4253 of file ImageView.cs.

4254 {
4255 get { return mouseUpInt; }
4256 set { mouseUpInt = value; }
4257 }

◆ OpenSlide

bool BioGTK.ImageView.OpenSlide
getset

Definition at line 3740 of file ImageView.cs.

3741 {
3742 get { return openSlide; }
3743 set { openSlide = value; }
3744 }

◆ Origin

PointD BioGTK.ImageView.Origin
getset

Definition at line 3822 of file ImageView.cs.

3823 {
3824 get { return origin; }
3825 set
3826 {
3827 if (AllowNavigation)
3828 origin = value;
3829 if (View != null)
3830 {
3831 UpdateImages();
3832 if (!MacOS)
3833 glArea?.RequestRedraw();
3834 else
3835 View.QueueDraw();
3836 }
3837 }
3838 }
void RequestRedraw()
Request a redraw of the GLArea.

◆ PxHmicron

double BioGTK.ImageView.PxHmicron
getset

Definition at line 402 of file ImageView.cs.

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

◆ PxWmicron

double BioGTK.ImageView.PxWmicron
getset

Definition at line 369 of file ImageView.cs.

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

◆ PyramidalOrigin

PointD BioGTK.ImageView.PyramidalOrigin
getset

Definition at line 3855 of file ImageView.cs.

3856 {
3857 get
3858 {
3859 return SelectedImage.PyramidalOrigin;
3860 }
3861 set
3862 {
3863 if (!AllowNavigation)
3864 return;
3865 SelectedImage.PyramidalOrigin = value;
3866 if (!MacOS)
3867 {
3868 double viewWorldW = Math.Max(1, View?.AllocatedWidth ?? 1) * Resolution;
3869 double viewWorldH = Math.Max(1, View?.AllocatedHeight ?? 1) * Resolution;
3870 double worldRangeX = Math.Max(0, hScroll.Adjustment.Upper - hScroll.Adjustment.Lower);
3871 double worldRangeY = Math.Max(0, vScroll.Adjustment.Upper - vScroll.Adjustment.Lower);
3872 bool canPanX = SelectedImage?.isPyramidal == true && worldRangeX > viewWorldW;
3873 bool canPanY = SelectedImage?.isPyramidal == true && worldRangeY > viewWorldH;
3874
3875 double maxX = Math.Max(hScroll.Adjustment.Lower, hScroll.Adjustment.Upper - hScroll.Adjustment.PageSize);
3876 double maxY = Math.Max(vScroll.Adjustment.Lower, vScroll.Adjustment.Upper - vScroll.Adjustment.PageSize);
3877 double clampedX = canPanX
3878 ? Math.Clamp(value.X, hScroll.Adjustment.Lower, maxX)
3879 : value.X;
3880 double clampedY = canPanY
3881 ? Math.Clamp(value.Y, vScroll.Adjustment.Lower, maxY)
3882 : value.Y;
3883
3884 _updatingScrollBars = true;
3885 if (canPanX && hScroll.Value != clampedX)
3886 hScroll.Value = clampedX;
3887 if (canPanY && vScroll.Value != clampedY)
3888 vScroll.Value = clampedY;
3889 _updatingScrollBars = false;
3890 }
3891 if (_suppressViewUpdates)
3892 return;
3893
3894 if (SelectedImage?.isPyramidal == true)
3895 {
3896 // Pan and zoom only change which part of the same image is
3897 // visible. In-flight tiles remain valid cache entries, so do
3898 // not cancel their HTTP requests here. Cancellation is still
3899 // used for channel, Z/T, threshold, and source changes where
3900 // an old tile could contain genuinely stale pixel data.
3901 slideRenderer?.InvalidateViewport();
3902 // The Skia renderer does not cancel network I/O when its
3903 // render state changes, so its existing generation invalidation
3904 // is the viewport-safe equivalent.
3905 sKSlideRenderer?.InvalidateRenderState();
3906 UpdateView();
3907 }
3908 else if (View != null)
3909 {
3910 UpdateImages();
3911 View.QueueDraw();
3912 }
3913 }
3914 }
void InvalidateViewport()
Marks screen-space layout work as stale without cancelling tile I/O. Tile pixels are independent of t...

◆ PyramidalOriginTransformed

PointD BioGTK.ImageView.PyramidalOriginTransformed
getset

Definition at line 3848 of file ImageView.cs.

3849 {
3850 get { return new PointD(PyramidalOrigin.X * Resolution, PyramidalOrigin.Y * Resolution); }
3851 set { PyramidalOrigin = new PointD(value.X / Resolution, value.Y / Resolution); }
3852 }

◆ RChannel

Channel BioGTK.ImageView.RChannel
get

Definition at line 3797 of file ImageView.cs.

3798 {
3799 get
3800 {
3801 return SelectedImage.Channels[SelectedImage.rgbChannels[0]];
3802 }
3803 }

◆ Resolution

double BioGTK.ImageView.Resolution
getset

Definition at line 3947 of file ImageView.cs.

3948 {
3949 get
3950 {
3951 if (!SelectedImage.isPyramidal)
3952 return 1;
3953 return SelectedImage.Resolution;
3954 }
3955 set
3956 {
3957 if (SelectedImage.isPyramidal)
3958 SelectedImage.Resolution = value;
3959 if (!_suppressViewUpdates)
3960 {
3961 if (SelectedImage?.isPyramidal == true)
3962 UpdateView();
3963 else if (View != null)
3964 {
3965 try
3966 {
3967 UpdateImages();
3968 }
3969 catch (Exception)
3970 {
3971
3972 }
3973 if (!MacOS)
3974 glArea?.RequestRedraw();
3975 else
3976 View.QueueDraw();
3977 }
3978 }
3979 }
3980 }

◆ Scale

SizeF BioGTK.ImageView.Scale
getset

Definition at line 4039 of file ImageView.cs.

4040 {
4041 get
4042 {
4043 return scale;
4044 }
4045 set
4046 {
4047 scale = value;
4048 }
4049 }

◆ SelectedAnnotation

ROI BioGTK.ImageView.SelectedAnnotation
staticget

Definition at line 4587 of file ImageView.cs.

4588 {
4589 get
4590 {
4591 foreach (var item in SelectedImage.Annotations)
4592 {
4593 if (item.Selected)
4594 return item;
4595 }
4596 return null;
4597 }
4598 }

◆ selectedAnnotations

List<ROI> BioGTK.ImageView.selectedAnnotations
staticget

Definition at line 473 of file ImageView.cs.

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

◆ SelectedBuffer

AForge.Bitmap BioGTK.ImageView.SelectedBuffer
staticget

Definition at line 446 of file ImageView.cs.

447 {
448 get
449 {
450 int ind = SelectedImage.GetFrameIndex(SelectedImage.Coordinate.Z, SelectedImage.Coordinate.C, SelectedImage.Coordinate.T);
451 return SelectedImage.Buffers[ind];
452 }
453 }

◆ SelectedImage

BioImage BioGTK.ImageView.SelectedImage
staticgetset

Definition at line 3745 of file ImageView.cs.

3746 {
3747 get
3748 {
3749 if (App.viewer == null)
3750 return null;
3751 if (App.viewer.Images.Count == 0)
3752 return null;
3753 return App.viewer.Images[App.viewer.SelectedIndex];
3754 }
3755 set
3756 {
3757 if (value == null)
3758 return;
3759 if (App.viewer == null)
3760 App.viewer = ImageView.Create(value);
3761 App.viewer.Images[App.viewer.SelectedIndex] = value;
3762 }
3763 }

◆ SelectedIndex

int BioGTK.ImageView.SelectedIndex
getset

Definition at line 455 of file ImageView.cs.

456 {
457 get
458 {
459 if(selectedIndex >= Images.Count)
460 selectedIndex = Images.Count - 1;
461 return selectedIndex;
462 }
463 set
464 {
465 if (value >= 0 && value < Images.Count)
466 {
467 selectedIndex = value;
468 Images[selectedIndex] = SelectedImage;
469 }
470 }
471 }

◆ ShowMasks

bool BioGTK.ImageView.ShowMasks = true
getset

Definition at line 441 of file ImageView.cs.

441{ get; set; } = true;

◆ ShowOverview

bool BioGTK.ImageView.ShowOverview = true
getset

Definition at line 442 of file ImageView.cs.

442{ get; set; } = true;

◆ ShowROIs

bool BioGTK.ImageView.ShowROIs = true
get

Definition at line 4215 of file ImageView.cs.

4215{ get; private set; } = true;

◆ TopRightOrigin

PointD BioGTK.ImageView.TopRightOrigin
get

Definition at line 3840 of file ImageView.cs.

3841 {
3842 get
3843 {
3844 return new PointD((Origin.X - ((View.AllocatedWidth / 2) * pxWmicron)), (Origin.Y - ((View.AllocatedHeight / 2) * pxHmicron)));
3845 }
3846 }

◆ View

Widget BioGTK.ImageView.View
getset

Definition at line 4656 of file ImageView.cs.

4657 {
4658 get
4659 {
4660 if (currentView != null)
4661 return currentView;
4662 if (MacOS)
4663 return sk;
4664 return glArea;
4665 }
4666 set
4667 {
4668 currentView = value;
4669 if (value is SKDrawingArea drawingArea)
4670 sk = drawingArea;
4671 if (value is SlideGLArea slideGlArea)
4672 glArea = slideGlArea;
4673 }
4674 }

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