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 RequestImmediateRender ()
 
void RequestDeferredRender ()
 
void SetTitle (string s)
 
void UpdateImages (bool force=false)
 It updates the images.
 
void UpdateImage ()
 It updates the image.
 
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)
 

Static Public Member Functions

static ImageView Create (BioImage bm)
 
static SKImage Convert16bppBitmapToSKImage (Bitmap sourceBitmap)
 
static SKImage BitmapToSKImage (AForge.Bitmap bitm)
 
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]
 
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]
 

Detailed Description

Definition at line 35 of file ImageView.cs.

Member Enumeration Documentation

◆ ViewMode

enum BioGTK.ImageView.ViewMode

Definition at line 2333 of file ImageView.cs.

2334 {
2335 Raw,
2336 Filtered,
2337 RGBImage,
2338 Emission,
2339 }

Constructor & Destructor Documentation

◆ ImageView()

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

Definition at line 282 of file ImageView.cs.

282 : base(handle)
283 {
284 _builder = builder;
285 App.viewer = this;
286 builder.Autoconnect(this);
287 var gameWindowSettings = new GameWindowSettings()
288 {
289 UpdateFrequency = 60,
290 };
291 NativeWindowSettings nativeSettings;
292
293 if (OperatingSystem.IsMacOS())
294 {
295 MacOS = true;
296 // Create the renderer bridge
297 sk = new SKDrawingArea();
298 sKSlideRenderer = new SKSlideRenderer(sk);
299 }
300 else if(OperatingSystem.IsLinux())
301 {
302 nativeSettings = new NativeWindowSettings()
303 {
304 ClientSize = new Vector2i(600, 400),
305 Location = new Vector2i(0,0),
306 Title = "OpenGL Context",
307 StartVisible = false, // Window starts hidden
308 API = ContextAPI.OpenGL,
309 Profile = ContextProfile.Core,
310 APIVersion = new Version(3, 3)
311 };
312 //tileCopy = new TileCopyGL(gameWindowSettings, nativeSettings);
313 Environment.SetEnvironmentVariable("GDK_BACKEND","x11");
314 Environment.SetEnvironmentVariable("GTK_BACKEND","x11");
315 window = new GLWindow(gameWindowSettings, nativeSettings);
316 // Create the GLArea widget
317 glArea = new SlideGLArea();
318 glArea.OnSkiaRender += RenderSkia;
319 // Create the renderer bridge
320 slideRenderer = new SlideRenderer(glArea);
321 GLFWProvider.SetErrorCallback((error, description) =>
322 {
323 if (description.Contains("Wayland") && description.Contains("window position"))
324 Console.WriteLine($"BioGTK Window Position Error.");
325 Console.WriteLine($"BioGTK GLFW Error {error}: {description}");
326 });
327
328 }
329 else if(OperatingSystem.IsWindows())
330 {
331 nativeSettings = new NativeWindowSettings()
332 {
333 ClientSize = new Vector2i(600, 400),
334 Title = "OpenGL Context",
335 StartVisible = false, // Window starts hidden
336 StartFocused = false, // Don't grab focus
337 WindowBorder = WindowBorder.Hidden, // No border
338 WindowState = OpenTK.Windowing.Common.WindowState.Minimized, // Start minimized
339 IsEventDriven = false, // Don't process window events
340 Flags = ContextFlags.Offscreen, // Offscreen rendering context
341 API = ContextAPI.OpenGL,
342 Profile = ContextProfile.Core,
343 APIVersion = new Version(3, 3)
344 };
345 window = new GLWindow(gameWindowSettings, nativeSettings);
346 // Create the renderer bridge
347 slideRenderer = new SlideRenderer(glArea);
348 GLFWProvider.SetErrorCallback((error, description) =>
349 {
350 if (description.Contains("Wayland") && description.Contains("window position"))
351 Console.WriteLine($"BioGTK Window Position Error.");
352 Console.WriteLine($"BioGTK GLFW Error {error}: {description}");
353 });
354 // Create the GLArea widget
355 glArea = new SlideGLArea();
356 glArea.OnSkiaRender += RenderSkia;
357 }
358
359 if (MacOS)
360 {
361 if (im.isPyramidal)
362 {
363 // Set the source based on image type
364 if (im.OpenSlideBase != null)
365 {
366 sKSlideRenderer.SetSource(im.OpenSlideBase);
367 }
368 else if (im.SlideBase != null)
369 {
370 sKSlideRenderer.SetSource(im.SlideBase);
371 }
372 }
373 // Add to view
374 viewStack.Add(sk);
375 }
376 else
377 {
378 // Set the source based on image type
379 if (im.OpenSlideBase != null)
380 {
381 slideRenderer.SetSource(im.OpenSlideBase);
382 }
383 else if (im.SlideBase != null)
384 {
385 slideRenderer.SetSource(im.SlideBase);
386 }
387 // Add to view
388 viewStack.Add(glArea);
389 }
390
391 viewStack.ShowAll();
392 if(!MacOS)
393 glArea.Show();
394 this.WidthRequest = 600;
395 this.HeightRequest = 400;
396 roi.Submenu = roiMenu;
397 roi.ShowAll();
398 AddImage(im);
399 ShowMasks = true;
400 pxWmicron = SelectedImage.PhysicalSizeX;
401 pxHmicron = SelectedImage.PhysicalSizeY;
403 //pictureBox.WidthRequest = im.SizeX;
404 //pictureBox.HeightRequest = im.SizeY;
405 Function.InitializeContextMenu();
406 this.Scale = new SizeF(1, 1);
407 // Set the text column to display for comboboxs.
408 var rendererr = new CellRendererText();
409 rBox.PackStart(rendererr, false);
410 rBox.AddAttribute(rendererr, "text", 0);
411 var rendererg = new CellRendererText();
412 gBox.PackStart(rendererg, false);
413 gBox.AddAttribute(rendererg, "text", 0);
414 var rendererb = new CellRendererText();
415 bBox.PackStart(rendererb, false);
416 bBox.AddAttribute(rendererb, "text", 0);
417 App.ApplyStyles(this);
418 }
void SetupHandlers()
Sets up the handlers.
void AddImage(BioImage im)
Definition ImageView.cs:75
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 75 of file ImageView.cs.

76 {
77 Images.Add(im);
78 selectedIndex = Images.Count - 1;
79 if (im.Resolutions[0].SizeX < 1920 && im.Resolutions[0].SizeY < 1080)
80 {
81 if(sk != null)
82 {
83 sk.WidthRequest = im.Resolutions[0].SizeX;
84 sk.HeightRequest = im.Resolutions[0].SizeY;
85 }
86 else
87 {
88 glArea.WidthRequest = im.Resolutions[0].SizeX;
89 glArea.HeightRequest = im.Resolutions[0].SizeY;
90 }
91 }
92
93 Initialize();
94 InitPreview();
95 UpdateImages(true);
96 UpdateGUI();
97 GoToImage(Images.Count - 1);
98 }
void GoToImage()
This function is used to go to the image at the specified index.
void UpdateGUI()
It updates the GUI to reflect the current state of the image.
void UpdateImages(bool force=false)
It updates the images.

◆ BitmapToSKImage()

static SKImage BioGTK.ImageView.BitmapToSKImage ( AForge.Bitmap bitm)
static

Definition at line 838 of file ImageView.cs.

839 {
840 if (bitm.PixelFormat == AForge.PixelFormat.Format24bppRgb)
841 return Convert24bppBitmapToSKImage(bitm);
842 if (bitm.PixelFormat == AForge.PixelFormat.Format32bppArgb)
843 return Convert32bppBitmapToSKImage(bitm);
844 if (bitm.PixelFormat == AForge.PixelFormat.Float)
845 return Convert32bppBitmapToSKImage(bitm.GetImageRGBA());
846 if (bitm.PixelFormat == AForge.PixelFormat.Format16bppGrayScale)
847 return Convert16bppBitmapToSKImage(bitm.GetImageRGBA());
848 if (bitm.PixelFormat == AForge.PixelFormat.Format48bppRgb)
849 return Convert16bppBitmapToSKImage(bitm.GetImageRGBA());
850 if (bitm.PixelFormat == AForge.PixelFormat.Format8bppIndexed)
851 return Convert8bppBitmapToSKImage(bitm);
852 else
853 throw new NotSupportedException("PixelFormat " + bitm.PixelFormat + " is not supported for SKImage.");
854 }

◆ Convert16bppBitmapToSKImage()

static SKImage BioGTK.ImageView.Convert16bppBitmapToSKImage ( Bitmap sourceBitmap)
static

Definition at line 804 of file ImageView.cs.

805 {
806 Bitmap bm = sourceBitmap.GetImageRGBA();
807 int width = bm.Width;
808 int height = bm.Height;
809
810 SKBitmap skBitmap = new SKBitmap(width, height, SKColorType.Bgra8888, SKAlphaType.Opaque);
811
812 BitmapData bitmapData = sourceBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bm.PixelFormat);
813
814 unsafe
815 {
816 byte* sourcePtr = (byte*)bm.Data.ToPointer();
817 byte* destPtr = (byte*)skBitmap.GetPixels().ToPointer();
818
819 for (int y = 0; y < height; y++)
820 {
821 for (int x = 0; x < width; x++)
822 {
823 destPtr[0] = sourcePtr[0]; // Blue
824 destPtr[1] = sourcePtr[1]; // Green
825 destPtr[2] = sourcePtr[2]; // Red
826 destPtr[3] = 255; // Alpha (fully opaque)
827
828 sourcePtr += 3;
829 destPtr += 4;
830 }
831 }
832 }
833
834 sourceBitmap.UnlockBits(bitmapData);
835
836 return SKImage.FromBitmap(skBitmap);
837 }

◆ CopySelection()

void BioGTK.ImageView.CopySelection ( )

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

Definition at line 2293 of file ImageView.cs.

2294 {
2295 copys.Clear();
2296 string s = "";
2297 List<ROI> rois = new List<ROI>();
2298 rois.AddRange(SelectedImage.AnnotationsR);
2299 rois.AddRange(SelectedImage.AnnotationsG);
2300 rois.AddRange(SelectedImage.AnnotationsB);
2301 foreach (ROI item in rois)
2302 {
2303 if (item.Selected)
2304 {
2305 copys.Add(item);
2306 s += BioImage.ROIToString(item);
2307 }
2308 }
2309 Clipboard clipboard = Clipboard.Get(Gdk.Selection.Clipboard);
2310 clipboard.Text = s;
2311 }

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

269 {
270 Console.WriteLine("Creating ImageView for " + bm.file);
271
272 Builder builder = new Builder(new FileStream(System.IO.Path.GetDirectoryName(Environment.ProcessPath) + "/" + "Glade/ImageView.glade", FileMode.Open));
273
274 ImageView v = new ImageView(builder, builder.GetObject("imageView").Handle, bm);
275 v.Title = bm.Filename;
276
277 return v;
278 }

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

1993 {
1994 return new Cairo.Color((double)color.R / 255, (double)color.G / 255, (double)color.B / 255);
1995 }

◆ GetCoordinate()

ZCT BioGTK.ImageView.GetCoordinate ( )

It returns the coordinate of the selected image

Returns
The Coordinate property of the SelectedImage object.

Definition at line 67 of file ImageView.cs.

68 {
69 return SelectedImage.Coordinate;
70 }

◆ GetScale()

double BioGTK.ImageView.GetScale ( )

Definition at line 2669 of file ImageView.cs.

2670 {
2671 return ToViewSizeW(ROI.selectBoxSize / Scale.Width);
2672 }

◆ GetSelectedROIs()

List< ROI > BioGTK.ImageView.GetSelectedROIs ( )

Definition at line 2719 of file ImageView.cs.

2720 {
2721 List<ROI> roi = new List<ROI>();
2722 List<ROI> rois = new List<ROI>();
2723 rois.AddRange(SelectedImage.AnnotationsR);
2724 rois.AddRange(SelectedImage.AnnotationsG);
2725 rois.AddRange(SelectedImage.AnnotationsB);
2726 foreach (ROI r in rois)
2727 {
2728 if (r.Selected)
2729 {
2730 roi.Add(r);
2731 }
2732 }
2733 return roi;
2734 }

◆ GoToImage() [1/2]

void BioGTK.ImageView.GoToImage ( )

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

Definition at line 3366 of file ImageView.cs.

3367 {
3368 GoToImage(0);
3369 }

◆ GoToImage() [2/2]

void BioGTK.ImageView.GoToImage ( int i)

It takes an image index and centers the image in the viewport

Parameters
ithe index of the image to go to
Returns
The method is returning the value of the variable "i"

Definition at line 3375 of file ImageView.cs.

3376 {
3377 if (Images.Count <= i)
3378 return;
3379 if (SelectedImage.Type == BioImage.ImageType.pyramidal)
3380 {
3381 if (SelectedImage.OpenSlideBase != null)
3382 {
3383 if (MacroResolution.HasValue)
3384 {
3385 int lev = MacroResolution.Value - 2;
3386 Resolution = _openSlideBase.Schema.Resolutions[lev].UnitsPerPixel * 0.98;
3387 }
3388 else
3389 {
3390 int lev = 0;
3391 Resolution = _openSlideBase.Schema.Resolutions[lev].UnitsPerPixel * 0.98;
3392 }
3393 }
3394 else
3395 {
3396 if (MacroResolution.HasValue)
3397 {
3398 int lev = MacroResolution.Value - 1;
3399 Resolution = SelectedImage.SlideBase.Schema.Resolutions[lev].UnitsPerPixel * 0.98;
3400 PyramidalOrigin = new PointD(0, 0);
3401 }
3402 else
3403 {
3404 Resolution = SelectedImage.GetUnitPerPixel(SelectedImage.Resolutions.Count - 1) * 0.98;
3405 }
3406 }
3407 }
3408 double dx = Images[i].Volume.Width / 2;
3409 double dy = Images[i].Volume.Height / 2;
3410 Origin = new PointD(-(Images[i].Volume.Location.X + dx), -(Images[i].Volume.Location.Y + dy));
3411 double wx, wy;
3412 wx = viewStack.AllocatedWidth / ToScreenW(SelectedImage.Volume.Width);
3413 wy = viewStack.AllocatedHeight / ToScreenH(SelectedImage.Volume.Height);
3414 Scale = new SizeF((float)wy, (float)wy);
3415 UpdateView();
3416 }
void UpdateView(bool updateImages=true)
It updates the view.
float ToScreenH(double y)
double ToScreenW(double x)

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

3071 {
3072 if (SelectedImage == null)
3073 return ToViewSpace(x, y);
3074 if (SelectedImage.isPyramidal)
3075 {
3076 return new PointD((PyramidalOrigin.X + x) * Resolution, (PyramidalOrigin.Y + y) * Resolution);
3077 }
3078 else
3079 return ToViewSpace(x, y);
3080 }
PointF ToViewSpace(PointF p)

◆ OnDestroyed()

override void BioGTK.ImageView.OnDestroyed ( )
protected

Definition at line 3013 of file ImageView.cs.

3014 {
3015 base.OnDestroyed();
3016 }

◆ OnMouseWheel()

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

Definition at line 2466 of file ImageView.cs.

2467 {
2468 if (e.Event.Direction == ScrollDirection.Up)
2469 ZoomAtPoint(PyramidalOrigin.X, PyramidalOrigin.Y, false);
2470 else if (e.Event.Direction == ScrollDirection.Down)
2471 ZoomAtPoint(PyramidalOrigin.X, PyramidalOrigin.Y, true);
2472 }

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

2315 {
2316 Clipboard clipboard = Clipboard.Get(Gdk.Selection.Clipboard);
2317 string text = clipboard.WaitForText();
2318 string[] sts = text.Split(BioImage.NewLine);
2319 foreach (string line in sts)
2320 {
2321 if (line.Length > 8)
2322 {
2323 ROI an = BioImage.StringToROI(line);
2324 //We set the coordinates of the ROI's we are pasting
2325 an.coord = GetCoordinate();
2326 SelectedImage.Annotations.Add(an);
2327 }
2328 }
2329 UpdateView();
2330 }
ZCT GetCoordinate()
Definition ImageView.cs:67

◆ RequestDeferredRender()

void BioGTK.ImageView.RequestDeferredRender ( )

Definition at line 981 of file ImageView.cs.

982 {
983 lock (_renderLock)
984 {
985 _pendingRender = true;
986
987 // Reset timer - only render after 50ms of no requests
988 _renderTimer?.Dispose();
989 _renderTimer = new System.Threading.Timer(
990 _ => ExecuteDeferredRender(),
991 null,
992 20, // Delay in milliseconds
993 Timeout.Infinite
994 );
995 }
996 }

◆ RequestImmediateRender()

void BioGTK.ImageView.RequestImmediateRender ( )

Definition at line 877 of file ImageView.cs.

878 {
879 UpdateView(true);
880 }

◆ SetCoordinate()

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

Definition at line 43 of file ImageView.cs.

44 {
45 if (SelectedImage == null)
46 return;
47 if (z > SelectedImage.SizeZ - 1 && SelectedImage.Type == BioImage.ImageType.well)
48 zBar.Value = zBar.Adjustment.Upper;
49 else
50 zBar.Value = z;
51 if (c > SelectedImage.SizeC - 1)
52 cBar.Value = cBar.Adjustment.Upper;
53 else
54 cBar.Value = c;
55 if (t > SelectedImage.SizeT - 1)
56 tBar.Value = tBar.Adjustment.Upper;
57 else
58 tBar.Value = t;
59 if (SelectedImage.Type == BioImage.ImageType.well)
60 SelectedImage.Coordinate = new ZCT(0, (int)cBar.Value, (int)tBar.Value);
61 else
62 SelectedImage.Coordinate = new ZCT((int)zBar.Value, (int)cBar.Value, (int)tBar.Value);
63 }

◆ SetTitle()

void BioGTK.ImageView.SetTitle ( string s)

Definition at line 1083 of file ImageView.cs.

1084 {
1085 this.Title = s;
1086 }

◆ SetupHandlers()

void BioGTK.ImageView.SetupHandlers ( )
protected

Sets up the handlers.

Definition at line 1343 of file ImageView.cs.

1344 {
1345 zBar.ValueChanged += ValueChangedZ;
1346 cBar.ValueChanged += ValueChangedC;
1347 tBar.ValueChanged += ValueChangedT;
1348 if (MacOS)
1349 {
1350 sk.MotionNotifyEvent += ImageView_MotionNotifyEvent;
1351 sk.ButtonPressEvent += ImageView_ButtonPressEvent;
1352 sk.ButtonReleaseEvent += ImageView_ButtonReleaseEvent;
1353 sk.ScrollEvent += ImageView_ScrollEvent;
1354 sk.ScrollEvent += OnMouseWheel;
1355 sk.PaintSurface += Sk_PaintSurface;
1356 sk.SizeAllocated += PictureBox_SizeAllocated;
1357 sk.SetSizeRequest(600, 400);
1358 sk.AddEvents((int)(EventMask.ButtonPressMask
1359 | EventMask.ButtonReleaseMask
1360 | EventMask.KeyPressMask
1361 | EventMask.PointerMotionMask
1362 | EventMask.ScrollMask));
1363 }
1364 else
1365 {
1366 glArea.MotionNotifyEvent += ImageView_MotionNotifyEvent;
1367 glArea.ButtonPressEvent += ImageView_ButtonPressEvent;
1368 glArea.ButtonReleaseEvent += ImageView_ButtonReleaseEvent;
1369 glArea.ScrollEvent += ImageView_ScrollEvent;
1370 glArea.ScrollEvent += OnMouseWheel;
1371 glArea.Render += GlArea_Render;
1372 glArea.SizeAllocated += PictureBox_SizeAllocated;
1373 glArea.AddEvents((int)(EventMask.ButtonPressMask
1374 | EventMask.ButtonReleaseMask
1375 | EventMask.KeyPressMask
1376 | EventMask.PointerMotionMask
1377 | EventMask.ScrollMask));
1378 }
1379
1380 this.KeyPressEvent += ImageView_KeyPressEvent;
1381 this.DestroyEvent += ImageView_DestroyEvent;
1382 this.DeleteEvent += ImageView_DeleteEvent;
1383 this.FocusInEvent += ImageView_FocusInEvent;
1384 rBox.Changed += RBox_Changed;
1385 gBox.Changed += GBox_Changed;
1386 bBox.Changed += BBox_Changed;
1387 //Context Menu
1388 goToImageMenu.ButtonPressEvent += GoToImageMenu_ButtonPressEvent;
1389 goToOriginMenu.ButtonPressEvent += GoToOriginMenu_ButtonPressEvent;
1390
1391 roiDelete.ButtonPressEvent += RoiDelete_ButtonPressEvent;
1392 roiID.ButtonPressEvent += RoiID_ButtonPressEvent;
1393 copy.ButtonPressEvent += Copy_ButtonPressEvent;
1394 paste.ButtonPressEvent += Paste_ButtonPressEvent;
1395 draw.ButtonPressEvent += Draw_ButtonPressEvent;
1396 fill.ButtonPressEvent += Fill_ButtonPressEvent;
1397
1398 play.ButtonPressEvent += Play_ButtonPressEvent;
1399 stop.ButtonPressEvent += Stop_ButtonPressEvent;
1400 playSpeed.ButtonPressEvent += PlaySpeed_ButtonPressEvent;
1401 setValueRange.ButtonPressEvent += SetValueRange_ButtonPressEvent;
1402 loop.ButtonPressEvent += Loop_ButtonPressEvent;
1403
1404 zBar.ButtonPressEvent += ZBar_ButtonPressEvent;
1405 tBar.ButtonPressEvent += TBar_ButtonPressEvent;
1406 cBar.ButtonPressEvent += CBar_ButtonPressEvent;
1407
1408 }

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

3362 {
3363 return (float)(y * PxHmicron);
3364 }

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

3275 {
3276 if (SelectedImage == null)
3277 {
3278 double dx = (pxWmicron * (-Origin.X)) * Scale.Width;
3279 double dy = (pxHmicron * (-Origin.Y)) * Scale.Height;
3280 RectangleD rf = new RectangleD((PxWmicron * x * Scale.Width + dx), (PxHmicron * y * Scale.Height + dy), (PxWmicron * w * Scale.Width), (PxHmicron * h * Scale.Height));
3281 return rf;
3282 }
3283 if (SelectedImage.isPyramidal)
3284 {
3285 PointD d = ToViewSpace(x, y);
3286 double dw = ToViewSizeW(w);
3287 double dh = ToViewSizeH(h);
3288 return new RectangleD(d.X, d.Y, dw, dh);
3289 }
3290 else
3291 {
3292 double dx = (pxWmicron * (Origin.X)) * Scale.Width;
3293 double dy = (pxHmicron * (Origin.Y)) * Scale.Height;
3294 RectangleD rf = new RectangleD((PxWmicron * x * Scale.Width + dx), (PxHmicron * y * Scale.Height + dy), (PxWmicron * w * Scale.Width), (PxHmicron * h * Scale.Height));
3295 return rf;
3296 }
3297 }
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 3260 of file ImageView.cs.

3261 {
3262 float x = ToScreenScaleW((float)p.X);
3263 float y = ToScreenScaleH((float)p.Y);
3264 return new PointF(x, y);
3265 }
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 3251 of file ImageView.cs.

3252 {
3253 return (float)(-y * PxHmicron * Scale.Height);
3254 }

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

3243 {
3244 return (float)(-x * PxWmicron * Scale.Width);
3245 }

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

3190 {
3191 RectangleD f = ToScreenRect(x, y, 1, 1);
3192 return new PointD(f.X, f.Y);
3193 }
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 3232 of file ImageView.cs.

3233 {
3234 PointD pd = ToScreenSpace(p.X, p.Y);
3235 return new PointF((float)pd.X, (float)pd.Y);
3236 }
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 3199 of file ImageView.cs.

3200 {
3201 return ToScreenSpace(p.X, p.Y);
3202 }

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

3338 {
3339 PointD[] rs = new PointD[p.Length];
3340 for (int i = 0; i < p.Length; i++)
3341 {
3342 PointD pd = ToScreenSpace(p[i]);
3343 rs[i] = new PointD((float)pd.X, (float)pd.Y);
3344 }
3345 return rs;
3346 }

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

3209 {
3210 PointD pd = ToScreenSpace(p.X, p.Y);
3211 return new PointF((float)pd.X, (float)pd.Y);
3212 }

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

3219 {
3220 PointF[] pf = new PointF[p.Length];
3221 for (int i = 0; i < p.Length; i++)
3222 {
3223 pf[i] = ToScreenSpace(p[i]);
3224 }
3225 return pf;
3226 }

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

3305 {
3306 return ToScreenRect(p.X, p.Y, p.W, p.H);
3307 }

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

3323 {
3324 RectangleD[] rs = new RectangleD[p.Length];
3325 for (int i = 0; i < p.Length; i++)
3326 {
3327 rs[i] = ToScreenSpace(p[i]);
3328 }
3329 return rs;
3330 }

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

3314 {
3315 return ToScreenRect(p.X, p.Y, p.Width, p.Height);
3316 }

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

3353 {
3354 return (float)(x * PxWmicron);
3355 }

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

3174 {
3175 if (SelectedImage != null)
3176 if (SelectedImage.isPyramidal)
3177 {
3178 return d / Resolution;
3179 }
3180 double y = (double)(d / PxHmicron) / scale.Height;
3181 return y;
3182 }

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

3144 {
3145 if (SelectedImage != null)
3146 if (SelectedImage.isPyramidal)
3147 {
3148 return d / Resolution;
3149 }
3150 double y = (double)(d / PxHmicron);
3151 return y;
3152 }

◆ ToViewSpace() [1/3]

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

Definition at line 3100 of file ImageView.cs.

3101 {
3102 if (SelectedImage == null)
3103 {
3104 double dx = (ToViewSizeW(x - (viewStack.AllocatedWidth / 2)) / Scale.Width) - Origin.X;
3105 double dy = (ToViewSizeH(y - (viewStack.AllocatedHeight / 2)) / Scale.Height) - Origin.Y;
3106 return new PointD(dx, dy);
3107 }
3108
3109 if (SelectedImage.isPyramidal)
3110 {
3111 PointD p = new PointD(x / Resolution, y / Resolution);
3112 return new PointD(p.X - PyramidalOrigin.X, p.Y - PyramidalOrigin.Y);
3113 }
3114 else
3115 {
3116 // Handle non-pyramidal case
3117 double dx = (ToViewSizeW(x - (viewStack.AllocatedWidth / 2)) / Scale.Width) - Origin.X;
3118 double dy = (ToViewSizeH(y - (viewStack.AllocatedHeight / 2)) / Scale.Height) - Origin.Y;
3119 return new PointD(dx, dy);
3120 }
3121 }

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

3097 {
3098 return ToViewSpace(p.X, p.Y); ;
3099 }

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

3087 {
3088 PointD d = ToViewSpace(p.X, p.Y);
3089 return new PointF((float)d.X, (float)d.Y);
3090 }

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

3159 {
3160 if (SelectedImage != null)
3161 if (SelectedImage.isPyramidal)
3162 {
3163 return d / Resolution;
3164 }
3165 double x = (double)(d / PxWmicron) / scale.Width;
3166 return x;
3167 }

◆ UpdateGUI()

void BioGTK.ImageView.UpdateGUI ( )

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

Definition at line 2223 of file ImageView.cs.

2224 {
2225 cBar.Adjustment.Lower = 0;
2226 cBar.Adjustment.Upper = Images[selectedIndex].SizeC - 1;
2227 zBar.Adjustment.Lower = 0;
2228 zBar.Adjustment.Upper = Images[selectedIndex].SizeZ - 1;
2229 tBar.Adjustment.Lower = 0;
2230 tBar.Adjustment.Upper = Images[selectedIndex].SizeT - 1;
2231 if (endz == 0 || endz > Images[selectedIndex].SizeZ - 1)
2232 endz = Images[selectedIndex].SizeZ - 1;
2233 if (endc == 0 || endc > Images[selectedIndex].SizeC - 1)
2234 endc = Images[selectedIndex].SizeC - 1;
2235 if (endt == 0 || endt > Images[selectedIndex].SizeT - 1)
2236 endt = Images[selectedIndex].SizeT - 1;
2237 var store = new ListStore(typeof(string));
2238 foreach (Channel c in SelectedImage.Channels)
2239 {
2240 store.AppendValues(c.Name);
2241 }
2242 // Set the model for the ComboBox
2243 rBox.Model = store;
2244 gBox.Model = store;
2245 bBox.Model = store;
2246 if (SelectedImage.Channels.Count > 2)
2247 {
2248 rBox.Active = 0;
2249 gBox.Active = 1;
2250 bBox.Active = 2;
2251 }
2252 else
2253 if (SelectedImage.Channels.Count == 2)
2254 {
2255 rBox.Active = 0;
2256 gBox.Active = 1;
2257 }
2258 imagesMenu = new Menu();
2259 foreach (BioImage b in Images)
2260 {
2261 MenuItem mi = new MenuItem(b.Filename);
2262 mi.ButtonPressEvent += Mi_ButtonPressEvent;
2263 imagesMenu.Append(mi);
2264 }
2265 goToImageMenu.Submenu = imagesMenu;
2266 goToImageMenu.ShowAll();
2267 }

◆ UpdateImage()

void BioGTK.ImageView.UpdateImage ( )

It updates the image.

Definition at line 1211 of file ImageView.cs.

1212 {
1213 UpdateImages();
1214 }

◆ UpdateImages()

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

It updates the images.

Definition at line 1106 of file ImageView.cs.

1107 {
1108 if (SelectedImage == null)
1109 return;
1110 if (zBar.Adjustment.Upper != SelectedImage.SizeZ - 1 ||
1111 tBar.Adjustment.Upper != SelectedImage.SizeT - 1)
1112 {
1113 UpdateGUI();
1114 }
1115 if (!MacOS)
1116 {
1117 if (SelectedImage.isPyramidal && glArea.AllocatedWidth > 1 && glArea.AllocatedHeight > 1)
1118 {
1119 // Use the new renderer - no more ReadPixels!
1120 _ = slideRenderer.UpdateViewAsync(
1121 PyramidalOrigin,
1122 glArea.AllocatedWidth,
1123 glArea.AllocatedHeight,
1124 Resolution,
1126 );
1127 }
1128 else if (!SelectedImage.isPyramidal)
1129 {
1130 SKImages.Clear();
1131 Bitmaps.Clear();
1132 foreach (BioImage b in Images)
1133 {
1134 ZCT c = GetCoordinate();
1135 AForge.Bitmap bitmap = null;
1136 int index = b.GetFrameIndex(c.Z, c.C, c.T);
1137 if (Mode == ViewMode.Filtered)
1138 {
1139 bitmap = b.GetFiltered(c, b.RChannel.RangeR, b.GChannel.RangeG, b.BChannel.RangeB);
1140 }
1141 else if (Mode == ViewMode.RGBImage)
1142 {
1143 bitmap = b.GetRGBBitmap(c, b.RChannel.RangeR, b.GChannel.RangeG, b.BChannel.RangeB);
1144 }
1145 else if (Mode == ViewMode.Raw)
1146 {
1147 bitmap = b.Buffers[index];
1148 }
1149 else
1150 {
1151 bitmap = b.GetEmission(c, b.RChannel.RangeR, b.GChannel.RangeG, b.BChannel.RangeB);
1152 }
1153 if (bitmap == null)
1154 return;
1155 var bm = bitmap.GetImageRGBA();
1156 SKImage skim = BitmapToSKImage(bm);
1157 SKImages.Add(skim);
1158 Bitmaps.Add(bm);
1159 }
1160 }
1161 }
1162 else
1163 {
1164 if (SelectedImage.isPyramidal && sk.AllocatedWidth > 1 && sk.AllocatedHeight > 1)
1165 {
1166 // Use the new renderer - no more ReadPixels!
1167 _ = sKSlideRenderer.UpdateViewAsync(
1168 PyramidalOrigin,
1169 Resolution,
1170 GetCoordinate(),
1171 sk.AllocatedWidth,
1172 sk.AllocatedHeight
1173 );
1174 }
1175 else if (!SelectedImage.isPyramidal)
1176 {
1177 SKImages.Clear();
1178 Bitmaps.Clear();
1179 foreach (BioImage b in Images)
1180 {
1181 ZCT c = GetCoordinate();
1182 AForge.Bitmap bitmap = null;
1183 int index = b.GetFrameIndex(c.Z, c.C, c.T);
1184 if (Mode == ViewMode.Filtered)
1185 {
1186 bitmap = b.GetFiltered(c, b.RChannel.RangeR, b.GChannel.RangeG, b.BChannel.RangeB);
1187 }
1188 else if (Mode == ViewMode.RGBImage)
1189 {
1190 bitmap = b.GetRGBBitmap(c, b.RChannel.RangeR, b.GChannel.RangeG, b.BChannel.RangeB);
1191 }
1192 else if (Mode == ViewMode.Raw)
1193 {
1194 bitmap = b.Buffers[index];
1195 }
1196 else
1197 {
1198 bitmap = b.GetEmission(c, b.RChannel.RangeR, b.GChannel.RangeG, b.BChannel.RangeB);
1199 }
1200 if (bitmap == null)
1201 return;
1202 var bm = bitmap.GetImageRGBA();
1203 SKImage skim = BitmapToSKImage(bm);
1204 SKImages.Add(skim);
1205 Bitmaps.Add(bm);
1206 }
1207 }
1208 }
1209 }
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 2602 of file ImageView.cs.

2603 {
2604 if (SelectedImage.Buffers.Count == 0)
2605 return;
2606 if (SelectedImage.Type == BioImage.ImageType.well)
2607 {
2608 statusLabel.Text = (zBar.Value + 1) + "/" + (zBar.Adjustment.Upper + 1) + ", " + (cBar.Value + 1) + "/" + (cBar.Adjustment.Upper + 1) + ", " + (tBar.Value + 1) + "/" + (tBar.Adjustment.Upper + 1) + ", " +
2609 mousePoint + mouseColor + ", " + SelectedImage.Buffers[0].PixelFormat.ToString() + ", (" + SelectedImage.Volume.Location.X.ToString("N2") + ", " + SelectedImage.Volume.Location.Y.ToString("N2") + ") "
2610 + Origin.X.ToString("N2") + "," + Origin.Y.ToString("N2") + " , Well:" + SelectedImage.Level;
2611 }
2612 else
2613 statusLabel.Text = (zBar.Value + 1) + "/" + (zBar.Adjustment.Upper + 1) + ", " + (cBar.Value + 1) + "/" + (cBar.Adjustment.Upper + 1) + ", " + (tBar.Value + 1) + "/" + (tBar.Adjustment.Upper + 1) + ", " +
2614 mousePoint + mouseColor + ", " + SelectedImage.Buffers[0].PixelFormat.ToString() + ", (" + SelectedImage.Volume.Location.X.ToString("N2") + ", " + SelectedImage.Volume.Location.Y.ToString("N2") + ") "
2615 + Origin.X.ToString("N2") + "," + Origin.Y.ToString("N2") + ", Res:" + Resolution + " Level:" + Level;
2616 }

◆ UpdateView()

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

It updates the view.

Definition at line 2618 of file ImageView.cs.

2619 {
2620 refresh = true;
2621 if (SelectedImage?.isPyramidal == true)
2622 {
2623 if (!MacOS)
2624 {
2625 // Trigger async tile update
2626 _ = slideRenderer.UpdateViewAsync(
2627 PyramidalOrigin,
2628 glArea.AllocatedWidth,
2629 glArea.AllocatedHeight,
2630 Resolution,
2632 );
2633 }
2634 else
2635 {
2636 AForge.Size s = new AForge.Size();
2637 if (sk.AllocatedWidth <= 1 || sk.AllocatedHeight <= 1)
2638 s = new AForge.Size(600, 400);
2639 else
2640 s = new AForge.Size(sk.AllocatedWidth, sk.AllocatedHeight);
2641 // Trigger async tile update
2642 _ = sKSlideRenderer.UpdateViewAsync(
2643 PyramidalOrigin,
2644 Resolution,
2645 GetCoordinate(),
2646 s.Width,
2647 s.Height
2648 );
2649 }
2650 }
2651 else
2652 {
2653 UpdateImages(true);
2654 if (!MacOS)
2655 {
2656 glArea.RequestRedraw();
2657 }
2658 else
2659 sk.QueueDraw();
2660 }
2661 }
void RequestRedraw()
Request a redraw of the GLArea.

◆ ZoomAtPoint() [1/2]

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

Definition at line 2473 of file ImageView.cs.

2474 {
2475 if (SelectedImage == null) return;
2476 float CurrentLevelWidth = SelectedImage.Resolutions[Level].SizeX;
2477 float CurrentLevelHeight = SelectedImage.Resolutions[Level].SizeY;
2478 // 1. Define zoom factor (e.g., 2.0x zoom steps)
2479 float zoomFactor = zoomIn ? 2.0f : 0.5f;
2480
2481 // 2. Get the current level's scale relative to Full Res (Level 0)
2482 // Formula: CurrentLevelWidth / FullResWidth
2483 double currentLevelScale = (double)CurrentLevelWidth / SelectedImage.Resolutions[0].SizeX;
2484
2485 // 3. Find the "World Point" (Full Res Level 0) currently under the mouse
2486 // We add the origin to the mouse offset and then scale up to Level 0
2487 double worldX = (PyramidalOrigin.X + mouseX) / currentLevelScale;
2488 double worldY = (PyramidalOrigin.Y + mouseY) / currentLevelScale;
2489
2490 // 5. Get the NEW level's scale relative to Full Res
2491 double newLevelScale = (double)CurrentLevelWidth / SelectedImage.Resolutions[0].SizeX;
2492
2493 // 6. Calculate the NEW PyramidalOrigin
2494 // To keep the world point at the same mouse position:
2495 // NewOrigin = (WorldPoint * NewScale) - MouseOffset
2496 float newOriginX = (float)(worldX * newLevelScale - mouseX);
2497 float newOriginY = (float)(worldY * newLevelScale - mouseY);
2498
2499 // 7. Apply and Clamp (to ensure we don't scroll past image edges)
2500 PyramidalOrigin = new PointD(
2501 Math.Max(0, Math.Min(newOriginX, CurrentLevelWidth - AllocatedWidth)),
2502 Math.Max(0, Math.Min(newOriginY, CurrentLevelHeight - AllocatedHeight))
2503 );
2504 }

◆ ZoomAtPoint() [2/2]

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

Definition at line 2735 of file ImageView.cs.

2736 {
2737 if (SelectedImage == null) return;
2738
2739 // 1. Define zoom factor (e.g., 2.0x zoom steps)
2740 float zoomFactor = zoomIn ? 2.0f : 0.5f;
2741
2742 // 2. Get the current level's scale relative to Full Res (Level 0)
2743 // Formula: CurrentLevelWidth / FullResWidth
2744 double currentLevelScale = (double)SelectedImage.Resolutions[SelectedImage.Level].SizeX / SelectedImage.SizeX;
2745
2746 // 3. Find the "World Point" (Full Res Level 0) currently under the mouse
2747 // We add the origin to the mouse offset and then scale up to Level 0
2748 double worldX = (PyramidalOrigin.X + mouseX) / currentLevelScale;
2749 double worldY = (PyramidalOrigin.Y + mouseY) / currentLevelScale;
2750
2751 // 4. Update your Level logic here
2752 // This is where you switch your 'CurrentLevelWidth' to the next level in the pyramid
2753 //UpdateLevel(zoomIn);
2754
2755 // 5. Get the NEW level's scale relative to Full Res
2756 double newLevelScale = (double)SelectedImage.Resolutions[SelectedImage.Level].SizeX / SelectedImage.SizeX;
2757
2758 // 6. Calculate the NEW PyramidalOrigin
2759 // To keep the world point at the same mouse position:
2760 // NewOrigin = (WorldPoint * NewScale) - MouseOffset
2761 float newOriginX = (float)(worldX * newLevelScale - mouseX);
2762 float newOriginY = (float)(worldY * newLevelScale - mouseY);
2763
2764 // 7. Apply and Clamp (to ensure we don't scroll past image edges)
2765 PyramidalOrigin = new PointD(
2766 Math.Max(0, Math.Min(newOriginX, SelectedImage.Resolutions[SelectedImage.Level].SizeX - AllocatedWidth)),
2767 Math.Max(0, Math.Min(newOriginY, SelectedImage.Resolutions[SelectedImage.Level].SizeY - AllocatedHeight))
2768 );
2769 }

Member Data Documentation

◆ contextMenu

Menu BioGTK.ImageView.contextMenu

Definition at line 217 of file ImageView.cs.

◆ endc

int BioGTK.ImageView.endc = 0
static

Definition at line 1477 of file ImageView.cs.

◆ endt

int BioGTK.ImageView.endt = 0
static

Definition at line 1478 of file ImageView.cs.

◆ endz

int BioGTK.ImageView.endz = 0
static

Definition at line 1476 of file ImageView.cs.

◆ glArea

SlideGLArea BioGTK.ImageView.glArea

Definition at line 254 of file ImageView.cs.

◆ Images

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

Definition at line 41 of file ImageView.cs.

◆ keyDown

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

Definition at line 2058 of file ImageView.cs.

◆ MacOS

bool BioGTK.ImageView.MacOS = false
static

Definition at line 258 of file ImageView.cs.

◆ mainBox

Gtk.Box BioGTK.ImageView.mainBox

Definition at line 207 of file ImageView.cs.

◆ Modifiers

ModifierType BioGTK.ImageView.Modifiers
static

Definition at line 2676 of file ImageView.cs.

◆ mouseLeftState

bool BioGTK.ImageView.mouseLeftState
static

Definition at line 2675 of file ImageView.cs.

◆ selectedROI

ROI BioGTK.ImageView.selectedROI = new ROI()

Definition at line 2685 of file ImageView.cs.

◆ showBROIs

bool BioGTK.ImageView.showBROIs = true

Definition at line 2667 of file ImageView.cs.

◆ showGROIs

bool BioGTK.ImageView.showGROIs = true

Definition at line 2666 of file ImageView.cs.

◆ showRROIs

bool BioGTK.ImageView.showRROIs = true

Definition at line 2665 of file ImageView.cs.

◆ sKSlideRenderer

SKSlideRenderer BioGTK.ImageView.sKSlideRenderer

Definition at line 256 of file ImageView.cs.

◆ slideRenderer

SlideRenderer BioGTK.ImageView.slideRenderer

Definition at line 255 of file ImageView.cs.

◆ startc

int BioGTK.ImageView.startc = 0
static

Definition at line 1474 of file ImageView.cs.

◆ startt

int BioGTK.ImageView.startt = 0
static

Definition at line 1475 of file ImageView.cs.

◆ startz

int BioGTK.ImageView.startz = 0
static

Definition at line 1473 of file ImageView.cs.

◆ waitc

int BioGTK.ImageView.waitc = 1000
static

Definition at line 1471 of file ImageView.cs.

◆ waitt

int BioGTK.ImageView.waitt = 1000
static

Definition at line 1472 of file ImageView.cs.

◆ waitz

int BioGTK.ImageView.waitz = 1000
static

Definition at line 1470 of file ImageView.cs.

◆ window

GLWindow BioGTK.ImageView.window

Definition at line 257 of file ImageView.cs.

◆ x1State

bool BioGTK.ImageView.x1State
static

Definition at line 2673 of file ImageView.cs.

◆ x2State

bool BioGTK.ImageView.x2State
static

Definition at line 2674 of file ImageView.cs.

Property Documentation

◆ AllowNavigation

bool BioGTK.ImageView.AllowNavigation
getset

Definition at line 148 of file ImageView.cs.

149 {
150 get { return allowNavigation; }
151 set { allowNavigation = value; }
152 }

◆ BChannel

Channel BioGTK.ImageView.BChannel
get

Definition at line 2409 of file ImageView.cs.

2410 {
2411 get
2412 {
2413 return SelectedImage.Channels[SelectedImage.rgbChannels[2]];
2414 }
2415 }

◆ GChannel

Channel BioGTK.ImageView.GChannel
get

Definition at line 2401 of file ImageView.cs.

2402 {
2403 get
2404 {
2405 return SelectedImage.Channels[SelectedImage.rgbChannels[1]];
2406 }
2407 }

◆ ImageViewHeight

double BioGTK.ImageView.ImageViewHeight
get

Definition at line 3056 of file ImageView.cs.

3057 {
3058 get
3059 {
3060 double d = glArea.AllocatedHeight / Resolution;
3061 return d;
3062 }
3063 }

◆ ImageViewWidth

double BioGTK.ImageView.ImageViewWidth
get

Definition at line 3048 of file ImageView.cs.

3049 {
3050 get
3051 {
3052 double d = glArea.AllocatedWidth / Resolution;
3053 return d;
3054 }
3055 }

◆ LabelResolution

int? BioGTK.ImageView.LabelResolution
get

Definition at line 1218 of file ImageView.cs.

1218{ get { return SelectedImage.LabelResolution; } }

◆ Level

int BioGTK.ImageView.Level
getset

Definition at line 2555 of file ImageView.cs.

2556 {
2557 get
2558 {
2559 if (SelectedImage.Type == BioImage.ImageType.well)
2560 {
2561 return (int)SelectedImage.Level;
2562 }
2563 if (SelectedImage.isPyramidal)
2564 if (!openSlide)
2565 l = OpenSlideGTK.TileUtil.GetLevel(_slideBase.Schema.Resolutions, Resolution);
2566 else
2567 l = OpenSlideGTK.TileUtil.GetLevel(_openSlideBase.Schema.Resolutions, Resolution);
2568 return l;
2569 }
2570 set
2571 {
2572 if (value < 0)
2573 return;
2574 if (l != value)
2575 {
2576 UpdateLevel();
2577 }
2578 l = value;
2579 SelectedImage.Level = l;
2580 if (SelectedImage.Type == BioImage.ImageType.well)
2581 {
2582 SelectedImage.UpdateBuffersWells();
2583 UpdateView();
2584 }
2585 }
2586 }

◆ MacroResolution

int? BioGTK.ImageView.MacroResolution
get

Definition at line 1217 of file ImageView.cs.

1217{ get { return SelectedImage.MacroResolution; } }

◆ Mode

ViewMode BioGTK.ImageView.Mode
getset

Definition at line 2363 of file ImageView.cs.

2364 {
2365 get
2366 {
2367 return viewMode;
2368 }
2369 set
2370 {
2371 viewMode = value;
2372 if (viewMode == ViewMode.RGBImage)
2373 {
2374 rgbStack.VisibleChild = rgbStack.Children[1];
2375 }
2376 else
2377 if (viewMode == ViewMode.Filtered)
2378 {
2379 rgbStack.VisibleChild = rgbStack.Children[0];
2380 }
2381 else
2382 if (viewMode == ViewMode.Raw)
2383 {
2384 rgbStack.VisibleChild = rgbStack.Children[0];
2385 }
2386 else
2387 {
2388 rgbStack.VisibleChild = rgbStack.Children[0];
2389 }
2390 }
2391 }

◆ MouseDown

PointD BioGTK.ImageView.MouseDown
getset

Definition at line 2702 of file ImageView.cs.

2703 {
2704 get { return mouseDown; }
2705 set { mouseDown = value; }
2706 }

◆ MouseDownInt

PointD BioGTK.ImageView.MouseDownInt
getset

Definition at line 2687 of file ImageView.cs.

2688 {
2689 get { return mouseDownInt; }
2690 set { mouseDownInt = value; }
2691 }

◆ MouseMove

PointD BioGTK.ImageView.MouseMove
getset

Definition at line 2712 of file ImageView.cs.

2713 {
2714 get { return mouseMove; }
2715 set { mouseMove = value; }
2716 }

◆ MouseMoveInt

PointD BioGTK.ImageView.MouseMoveInt
getset

Definition at line 2692 of file ImageView.cs.

2693 {
2694 get { return mouseMoveInt; }
2695 set { mouseMoveInt = value; }
2696 }

◆ MouseUp

PointD BioGTK.ImageView.MouseUp
getset

Definition at line 2707 of file ImageView.cs.

2708 {
2709 get { return mouseUp; }
2710 set { mouseUp = value; }
2711 }

◆ MouseUpInt

PointD BioGTK.ImageView.MouseUpInt
getset

Definition at line 2697 of file ImageView.cs.

2698 {
2699 get { return mouseUpInt; }
2700 set { mouseUpInt = value; }
2701 }

◆ OpenSlide

bool BioGTK.ImageView.OpenSlide
getset

Definition at line 2341 of file ImageView.cs.

2342 {
2343 get { return openSlide; }
2344 set { openSlide = value; }
2345 }

◆ Origin

PointD BioGTK.ImageView.Origin
getset

Definition at line 2418 of file ImageView.cs.

2419 {
2420 get { return origin; }
2421 set
2422 {
2423 if (AllowNavigation)
2424 origin = value;
2425 if (sk != null)
2426 {
2427 UpdateImages();
2428 sk.QueueDraw();
2429 }
2430 }
2431 }

◆ PxHmicron

double BioGTK.ImageView.PxHmicron
getset

Definition at line 125 of file ImageView.cs.

126 {
127 get
128 {
129 if (SelectedImage.Type == BioImage.ImageType.pyramidal)
130 if (openSlide)
131 {
132 int lev = OpenSlideGTK.TileUtil.GetLevel(_openSlideBase.Schema.Resolutions, Resolution);
133 return _openSlideBase.Schema.Resolutions[lev].UnitsPerPixel * pxHmicron;
134 }
135 else
136 {
137 int lev = OpenSlideGTK.TileUtil.GetLevel(_slideBase.Schema.Resolutions, Resolution);
138 return _slideBase.Schema.Resolutions[lev].UnitsPerPixel * pxHmicron;
139 }
140 return pxHmicron;
141 }
142 set
143 {
144 pxHmicron = value;
145 }
146 }

◆ PxWmicron

double BioGTK.ImageView.PxWmicron
getset

Definition at line 102 of file ImageView.cs.

103 {
104 get
105 {
106 if (SelectedImage.Type == BioImage.ImageType.pyramidal)
107 if (openSlide)
108 {
109 int lev = OpenSlideGTK.TileUtil.GetLevel(_openSlideBase.Schema.Resolutions, Resolution);
110 return _openSlideBase.Schema.Resolutions[lev].UnitsPerPixel * pxWmicron;
111 }
112 else
113 {
114 int lev = OpenSlideGTK.TileUtil.GetLevel(_slideBase.Schema.Resolutions, Resolution);
115 return _slideBase.Schema.Resolutions[lev].UnitsPerPixel * pxWmicron;
116 }
117
118 return pxWmicron;
119 }
120 set
121 {
122 pxWmicron = value;
123 }
124 }

◆ PyramidalOrigin

PointD BioGTK.ImageView.PyramidalOrigin
getset

Definition at line 2447 of file ImageView.cs.

2448 {
2449 get
2450 {
2451 return SelectedImage.PyramidalOrigin;
2452 }
2453 set
2454 {
2455 if (!AllowNavigation)
2456 return;
2457 SelectedImage.PyramidalOrigin = value;
2458 if (sk != null)
2459 {
2460 UpdateImages();
2461 sk.QueueDraw();
2462 }
2463 }
2464 }

◆ PyramidalOriginTransformed

PointD BioGTK.ImageView.PyramidalOriginTransformed
getset

Definition at line 2440 of file ImageView.cs.

2441 {
2442 get { return new PointD(PyramidalOrigin.X * Resolution, PyramidalOrigin.Y * Resolution); }
2443 set { PyramidalOrigin = new PointD(value.X / Resolution, value.Y / Resolution); }
2444 }

◆ RChannel

Channel BioGTK.ImageView.RChannel
get

Definition at line 2393 of file ImageView.cs.

2394 {
2395 get
2396 {
2397 return SelectedImage.Channels[SelectedImage.rgbChannels[0]];
2398 }
2399 }

◆ Resolution

double BioGTK.ImageView.Resolution
getset

Definition at line 2505 of file ImageView.cs.

2506 {
2507 get
2508 {
2509 if (!SelectedImage.isPyramidal)
2510 return 1;
2511 return SelectedImage.Resolution;
2512 }
2513 set
2514 {
2515 if (SelectedImage.isPyramidal)
2516 SelectedImage.Resolution = value;
2517 if (sk != null)
2518 {
2519 UpdateImages();
2520 sk.QueueDraw();
2521 }
2522 }
2523 }

◆ Scale

SizeF BioGTK.ImageView.Scale
getset

Definition at line 2590 of file ImageView.cs.

2591 {
2592 get
2593 {
2594 return scale;
2595 }
2596 set
2597 {
2598 scale = value;
2599 }
2600 }

◆ SelectedAnnotation

ROI BioGTK.ImageView.SelectedAnnotation
staticget

Definition at line 3035 of file ImageView.cs.

3036 {
3037 get
3038 {
3039 foreach (var item in SelectedImage.Annotations)
3040 {
3041 if (item.Selected)
3042 return item;
3043 }
3044 return null;
3045 }
3046 }

◆ selectedAnnotations

List<ROI> BioGTK.ImageView.selectedAnnotations
staticget

Definition at line 176 of file ImageView.cs.

177 {
178 get
179 {
180 List<ROI> rois = new List<ROI>();
181 foreach (var item in SelectedImage.Annotations)
182 {
183 if (item.BoundingBox.IntersectsWith(App.viewer.MouseDown))
184 rois.Add(item);
185 }
186 return rois;
187 }
188 }

◆ SelectedBuffer

AForge.Bitmap BioGTK.ImageView.SelectedBuffer
staticget

Definition at line 157 of file ImageView.cs.

158 {
159 get
160 {
161 int ind = SelectedImage.GetFrameIndex(SelectedImage.Coordinate.Z, SelectedImage.Coordinate.C, SelectedImage.Coordinate.T);
162 return SelectedImage.Buffers[ind];
163 }
164 }

◆ SelectedImage

BioImage BioGTK.ImageView.SelectedImage
staticgetset

Definition at line 2346 of file ImageView.cs.

2347 {
2348 get
2349 {
2350 if (App.viewer == null)
2351 return null;
2352 if (App.viewer.Images.Count == 0)
2353 return null;
2354 return App.viewer.Images[App.viewer.SelectedIndex];
2355 }
2356 set
2357 {
2358 App.viewer.Images[App.viewer.SelectedIndex] = value;
2359 }
2360 }

◆ SelectedIndex

int BioGTK.ImageView.SelectedIndex
getset

Definition at line 166 of file ImageView.cs.

167 {
168 get { return selectedIndex; }
169 set
170 {
171 selectedIndex = value;
172 Images[selectedIndex] = SelectedImage;
173 }
174 }

◆ ShowMasks

bool BioGTK.ImageView.ShowMasks = true
getset

Definition at line 154 of file ImageView.cs.

154{ get; set; } = true;

◆ ShowOverview

bool BioGTK.ImageView.ShowOverview = true
getset

Definition at line 155 of file ImageView.cs.

155{ get; set; } = true;

◆ TopRightOrigin

PointD BioGTK.ImageView.TopRightOrigin
get

Definition at line 2433 of file ImageView.cs.

2434 {
2435 get
2436 {
2437 return new PointD((Origin.X - ((glArea.AllocatedWidth / 2) * pxWmicron)), (Origin.Y - ((glArea.AllocatedHeight / 2) * pxHmicron)));
2438 }
2439 }

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