BioLib  3.7.0
A GUI-less version of Bio .NET library for editing & annotating various microscopy image formats.
Loading...
Searching...
No Matches
BioLib.BioImage Class Reference
Inheritance diagram for BioLib.BioImage:

Classes

class  ImageJDesc
 
class  WellPlate
 

Public Types

enum  ImageType { stack , pyramidal , well }
 
enum  Order { ZCT , CZT , TCZ }
 
enum  BackEnd { OpenSlide , Bioformats , LibVips }
 

Public Member Functions

BioImage Copy (bool rois)
 
BioImage Copy ()
 
double GetLevelDownsample (int level)
 Get the downsampling factor of a given level.
 
double[] GetLevelDownsamples ()
 
int LevelFromResolution (double Resolution)
 Returns the level of a given resolution.
 
double GetUnitPerPixel (int level)
 Get Unit Per Pixel for pyramidal images.
 
void To8Bit ()
 Converts a 16-bit image to an 8-bit image.
 
void To16Bit ()
 Converts the image to 16 bit.
 
void To24Bit ()
 Converts the image to 24 bit.
 
void To32Bit ()
 Converts the image to 32 bit.
 
void To48Bit ()
 
void ToShort ()
 
void ToFloat ()
 
void RotateFlip (AForge.RotateFlipType rot)
 
void Bake (int rmin, int rmax, int gmin, int gmax, int bmin, int bmax)
 Bake(int rmin, int rmax, int gmin, int gmax, int bmin, int bmax)
 
void Bake (IntRange rf, IntRange gf, IntRange bf)
 It takes a range of values for each channel, and creates a new image with the filtered values.
 
void UpdateCoords ()
 It takes a list of images and assigns them to a 3D array of coordinates.
 
void UpdateCoords (int sz, int sc, int st)
 It takes the number of Z, C, and T planes in the image and then assigns each image buffer a coordinate in the ZCT space.
 
void UpdateCoords (int sz, int sc, int st, Order order)
 It takes a list of images and assigns them to a 3D array of coordinates.
 
double ToImageSizeX (double d)
 Convert a physical size to an image size.
 
double ToImageSizeY (double d)
 Convert a physical size in Y direction to an image size in Y direction.
 
double ToImageSpaceX (double x)
 
double ToImageSpaceY (double y)
 
PointD ToImageSpace (PointD p)
 Convert a point in the stage coordinate system to a point in the image coordinate system.
 
PointD[] ToImageSpace (List< PointD > p)
 Convert a list of points from stage space to image space.
 
PointF[] ToImageSpace (PointF[] p)
 
RectangleF ToImageSpace (RectangleD p)
 
PointD ToStageSpace (PointD p)
 
PointD ToStageSpace (PointD p, int resolution)
 Convert a point in the image space to a point in the stage space.
 
RectangleD ToStageSpace (RectangleD p)
 
PointD[] ToStageSpace (PointD[] p)
 
 BioImage (string file)
 
BioImage[] SplitChannels ()
 It takes a single image and splits it into three images, one for each channel.
 
Bitmap GetImageByCoord (int z, int c, int t)
 
Bitmap GetBitmap (int z, int c, int t)
 "Given a z, c, t coordinate, return the bitmap at that coordinate."
 
int GetIndex (int ix, int iy)
 
int GetIndexRGB (int ix, int iy, int index)
 
ushort GetValue (ZCTXY coord)
 If the coordinate is within the bounds of the image, then return the value of the pixel at that coordinate.
 
ushort GetValueRGB (ZCTXY coord, int index)
 It takes a coordinate and an index and returns the value of the pixel at that coordinate.
 
ushort GetValue (ZCT coord, int x, int y)
 
ushort GetValue (int z, int c, int t, int x, int y)
 
float GetValueRGB (ZCT coord, int x, int y, int RGBindex)
 
float GetValueRGB (int z, int c, int t, int x, int y, int RGBindex)
 This function returns the value of the pixel at the specified coordinates in the specified channel, frame, and RGB index.
 
void SetValue (ZCTXY coord, ushort value)
 It takes a coordinate and a value, and sets the value at that coordinate.
 
void SetValue (int x, int y, int ind, ushort value)
 It sets the value of a pixel in a buffer.
 
void SetValue (int x, int y, ZCT coord, ushort value)
 This function sets the value of a pixel at a given x,y coordinate in a given image plane.
 
void SetValueRGB (ZCTXY coord, int RGBindex, ushort value)
 It takes a coordinate, an RGB index, and a value, and sets the value of the pixel at that coordinate to the value.
 
Bitmap GetBitmap (ZCT coord)
 
Bitmap GetFiltered (ZCT coord, IntRange r, IntRange g, IntRange b)
 
Bitmap GetFiltered (int ind, IntRange r, IntRange g, IntRange b)
 It takes an image, and returns a filtered version of that image.
 
UnmanagedImage GetChannelImage (int ind, short s)
 It takes an image, and returns a channel of that image.
 
Bitmap GetEmission (ZCT coord, IntRange rf, IntRange gf, IntRange bf)
 
Bitmap GetRGBBitmap (ZCT coord, IntRange rf, IntRange gf, IntRange bf)
 
List< ROIGetAnnotations (ZCT coord)
 
List< ROIGetAnnotations (int Z, int C, int T)
 This function returns a list of ROI objects that are associated with the specified Z, C, and T coordinates.
 
int GetFrameIndex (int z, int c, int t)
 
void SetFrameIndex (int z, int c, int t, int val)
 
BioImage GetRegion (int x, int y, int w, int h)
 
void StackThreshold (bool bit16)
 This function sets the minimum and maximum values of the image to the minimum and maximum values of the stack.
 
async Task UpdateBuffersPyramidal ()
 Updates the Buffers based on current pyramidal origin and resolution.
 
void UpdateBuffersWells ()
 
async Task< Bitmap[]> GetSlice (int x, int y, int w, int h, double resolution)
 
void Update ()
 
void Rename (string name)
 
void Dispose ()
 It disposes of all the buffers and channels in the image, removes the image from the Images list, and then forces the garbage collector to run.
 
override string ToString ()
 This function returns the filename of the object, and the location of the object in the 3D space.
 

Static Public Member Functions

static BioImage Copy (BioImage b, bool rois)
 
static BioImage Copy (BioImage b)
 
static BioImage CopyInfo (BioImage b, bool copyAnnotations, bool copyChannels)
 
static PointD ToStageSpace (PointD p, double physicalSizeX, double physicalSizeY, double volumeX, double volumeY)
 
static RectangleD ToStageSpace (RectangleD p, double physicalSizeX, double physicalSizeY, double volumeX, double volumeY)
 
static PointD[] ToStageSpace (PointD[] p, double physicalSizeX, double physicalSizeY, double volumeX, double volumeY)
 It takes a list of points, and converts them from a coordinate system where the origin is in the center of the image, to a coordinate system where the origin is in the top left corner of the image.
 
static BioImage Substack (BioImage orig, int ser, int zs, int ze, int cs, int ce, int ts, int te)
 It takes a BioImage object, and returns a new BioImage object that is a subset of the original.
 
static BioImage MergeChannels (BioImage b2, BioImage b)
 This function takes two images and merges them together.
 
static BioImage MergeChannels (string bname, string b2name)
 MergeChannels(b, b2) takes two images, b and b2, and merges the channels of b2 into b.
 
static BioImage MergeZ (BioImage b)
 It takes a 3D image and merges the Z-stack into a single 2D image.
 
static BioImage MergeT (BioImage b)
 It takes a 3D image and merges the time dimension into a single image.
 
static BioImage[] SplitChannels (BioImage bb)
 
static BioImage[] SplitChannels (string name)
 This function takes an image and splits it into its individual channels.
 
static IntRange MapIntRangeToByteRange (IntRange ushortRange)
 
static unsafe Bitmap GetBitmapRGB (int w, int h, PixelFormat px, byte[] bts)
 It takes a byte array of RGB or RGBA data and converts it to a Bitmap.
 
static void Initialize (string imageJPath)
 Initializes ImageJ/Fiji with the given path.
 
static void Initialize ()
 
static void SaveFile (string file, string ID)
 This function takes a string array of file names and a string ID and saves the files to the database.
 
static void SaveSeries (string[] IDs, string file)
 It takes a list of image IDs, and saves them as a single multi-page TIFF file.
 
static BioImage[] OpenSeries (string file, bool tab)
 It opens a tiff file, reads the number of pages, reads the number of channels, and then reads each page into a BioImage object.
 
static BioImage OpenFile (string file)
 This function opens a file and returns a BioImage object.
 
static BioImage OpenFile (string file, bool tab)
 
static BioImage OpenFile (string file, int series, bool tab, bool addToImages)
 It opens a TIFF file and returns a BioImage object.
 
static BioImage OpenFile (string file, int series, bool tab, bool addToImages, bool tile, int tileX, int tileY, int tileSizeX, int tileSizeY)
 The OpenFile function opens a BioImage file, reads its metadata, and loads the image data into a BioImage object.
 
static bool isTiffSeries (string file)
 
static bool isOME (string file)
 If the file is a TIFF, check the ImageDescription tag for the string "OME-XML". If it's there, return true. If it's not a TIFF, return true. If it's a PNG, JPG, JPEG, or BMP, return false.
 
static bool isOMESeries (string file)
 
static void SaveOME (string file, string ID)
 
static void SaveOME (BioImage image, string file)
 
static ROI[] SortByType (ROI[] annotations)
 Sorts an array of ROIs by their Type property (alphabetically by default).
 
static void SaveOMESeries (BioImage[] files, string f, bool planes)
 This function takes a list of image files and saves them as a single OME-TIFF file.
 
static int GetBands (PixelFormat format)
 The function "GetBands" returns the number of color bands for a given pixel format in the AForge library.
 
static void SaveOMEPyramidal (BioImage[] bms, string file, Enums.ForeignTiffCompression compression, int compressionLevel)
 The function SaveOMEPyramidal saves a collection of BioImages as a pyramidal OME-TIFF file.
 
static BioImage OpenOME (string file, bool tab)
 The function "OpenOME" opens a bioimage file in the OME format and returns the first image in the series.
 
static BioImage OpenOME (string file, int serie)
 
static BioImage FromNumpy (string file)
 Converts a numpy array to BioImage.
 
static BioImage FilesToStack (string[] files, int sizeZ, int sizeC, int sizeT)
 It takes a list of files, and creates a new BioImage object with the first file in the list. Then it loops through the rest of the files, adding the buffers from each file to the new BioImage object. Finally, it updates the coordinates of the new BioImage object, and adds it to the Images list.
 
static BioImage FolderToStack (string path, bool tab)
 It takes a folder of images and creates a stack from them.
 
static void OpenVips (BioImage b)
 The function "OpenVips" takes a BioImage object and an integer representing the number of pages, and adds each page of the image file to the BioImage's vipPages list using the NetVips library.
 
static Bitmap ExtractRegionFromTiledTiff (BioImage b, int x, int y, int width, int height, int level)
 The function ExtractRegionFromTiledTiff takes a BioImage object, coordinates, width, height, and resolution as input, and returns a Bitmap object representing the extracted region from the tiled TIFF image.
 
static BioImage OpenOME (string file, int serie, bool tab, bool addToImages, bool tile, int tilex, int tiley, int tileSizeX, int tileSizeY, bool useOpenSlide=true)
 The function "OpenOME" opens a bioimage file, with options to specify the series, whether to display it in a tab, whether to add it to existing images, whether to tile the image, and the tile size.
 
static Bitmap GetTile (BioImage b, int index, int level, int tilex, int tiley, int tileSizeX, int tileSizeY)
 It reads a tile from a file, and returns a bitmap.
 
static int GetBitsPerPixel (int bt)
 
static int GetBitMaxValue (int bt)
 It returns the maximum value of a bit.
 
static PointD[] ToImageSpace (List< PointD > p, double stageSizeX, double stageSizeY, double physicalSizeX, double physicalSizeY)
 The function takes a list of points in stage space and converts them to image space using the provided stage and physical size parameters.
 
static PixelFormat GetPixelFormat (int rgbChannelCount, int bitsPerPixel)
 If the bits per pixel is 8, then the pixel format is either 8bppIndexed, 24bppRgb, or 32bppArgb. If the bits per pixel is 16, then the pixel format is either 16bppGrayScale or 48bppRgb.
 
static PixelFormat GetPixelFormat (int rgbChannelCount, ome.xml.model.enums.PixelType px)
 The function returns the appropriate PixelFormat based on the number of RGB channels and the pixel type.
 
static BioImage[] OpenOMESeries (string file, bool tab, bool addToImages)
 It opens a file, checks if it's tiled, if it is, it opens it as a tiled image, if not, it opens it as a normal image.
 
static async Task OpenAsync (string file, bool OME, bool newtab, bool images, int series)
 It opens a file in a new thread.
 
static async Task OpenAsync (string[] files, bool OME, bool tab, bool images)
 It opens a file asynchronously.
 
static void Open (string file)
 It opens a file.
 
static void Open (string[] files)
 It opens a file.
 
static BioImage ImagesToStack (string[] files, bool tab)
 It takes a list of files, opens them, and then combines them into a single BioImage object.
 
static void Update (BioImage b)
 The function takes a BioImage object, opens the file, and returns a updated BioImage object.
 
static async Task SaveAsync (string file, string id, int serie, bool ome)
 The SaveAsync function saves data to a file asynchronously.
 
static async Task SaveSeriesAsync (BioImage[] imgs, string file, bool ome)
 The function SaveSeriesAsync saves a series of BioImage objects to a file asynchronously.
 
static async Task SavePyramidalAsync (BioImage[] imgs, string file, Enums.ForeignTiffCompression com, int compLevel)
 The function SavePyramidalAsync saves an array of BioImage objects as a pyramidal TIFF file asynchronously.
 
static bool VipsSupport (string file)
 The function checks if a given file is supported by the Vips library and returns true if it is, false otherwise.
 
static string OpenXML (string file)
 
static List< ROIOpenOMEROIs (string file, int series)
 It reads the OME-XML file and converts the ROIs to a list of ROI objects.
 
static string ROIsToString (List< ROI > Annotations)
 It takes a list of ROI objects and returns a string of all the ROI objects in the list.
 
static string ROIToString (ROI an)
 This function takes an ROI object and returns a string that contains all the information about the ROI.
 
static ROI StringToROI (string sts)
 It takes a string and returns an ROI object.
 
static void ExportROIsCSV (string filename, List< ROI > Annotations)
 This function takes a list of ROIs and writes them to a CSV file.
 
static List< ROIImportROIsCSV (string filename)
 It reads the CSV file and converts each line into a ROI object.
 
static void ExportROIFolder (string path, string filename)
 ExportROIFolder(path, filename)
 
static void AutoThreshold (BioImage b, bool updateImageStats)
 It takes a BioImage object, and calculates the mean histogram for each channel, and for the entire image.
 
static void AutoThreshold ()
 It takes the current image, and finds the best threshold value for it.
 
static void AutoThresholdThread (BioImage b)
 It creates a new thread that calls the AutoThreshold function.
 
static int FindFocus (BioImage im, int Channel, int Time)
 The function finds the focus of a given BioImage at a specific channel and time by calculating the focus quality of each Z-plane and returning the coordinate with the highest focus quality.
 
static long CalculateFocusQuality (Bitmap b)
 The function calculates the focus quality of a given bitmap image.
 
static int GetSeriesCount (string file)
 
static BioImage operator/ (BioImage a, float b)
 This function divides each pixel in the image by a constant value.
 
static BioImage operator* (BioImage a, float b)
 
static BioImage operator+ (BioImage a, float b)
 This function adds a constant value to each pixel in the image.
 
static BioImage operator- (BioImage a, float b)
 Subtracts a scalar value from each pixel in the image.
 
static BioImage operator/ (BioImage a, ColorS b)
 This function divides each pixel in the image by the value of the color.
 
static BioImage operator* (BioImage a, ColorS b)
 This function takes a BioImage object and a ColorS object and returns a BioImage object.
 
static BioImage operator+ (BioImage a, ColorS b)
 It takes a BioImage object and a ColorS object and adds the ColorS object to each buffer in the BioImage object.
 
static BioImage operator- (BioImage a, ColorS b)
 The function subtracts a color from each pixel in the image.
 

Public Attributes

WellPlate Plate = null
 
int[,,] Coords
 
List< Channel > Channels = new List<Channel>()
 
List< ResolutionResolutions = new List<Resolution>()
 
List< AForge.Bitmap > Buffers = new List<AForge.Bitmap>()
 
List< NetVips.Image > vipPages = new List<NetVips.Image>()
 
VolumeD Volume
 
List< ROIAnnotations = new List<ROI>()
 
string filename = ""
 
string script = ""
 
int[] rgbChannels = new int[3] { 0, 1, 2 }
 
int bitsPerPixel
 
int imagesPerSeries = 0
 
int seriesCount = 1
 
double frameInterval = 0
 
bool littleEndian = false
 
bool isGroup = false
 
long loadTimeMS = 0
 
long loadTimeTicks = 0
 
bool selected = false
 
Stopwatch watch = new Stopwatch()
 
string file
 
bool Loading = false
 
ImageReader imRead
 
Tiff tifRead
 
OpenSlideImage openSlideImage
 

Static Public Attributes

static float Progress = 0
 
static bool Planes = false
 
static string progFile
 
static LevelsLinear filter8 = new LevelsLinear()
 
static LevelsLinear16bpp filter16 = new LevelsLinear16bpp()
 
static Stopwatch swatch = new Stopwatch()
 
const char NewLine = '\n'
 
const string columns = "ROIID,ROINAME,TYPE,ID,SHAPEINDEX,TEXT,S,C,Z,T,X,Y,W,H,POINTS,STROKECOLOR,STROKECOLORW,FILLCOLOR,FONTSIZE\n"
 

Properties

ZCT Coordinate [get, set]
 
ImageType Type [get, set]
 
int Level [get, set]
 
string Filename [get, set]
 
int RGBChannelCount [get]
 
Statistics Statistics [get, set]
 
double Resolution [get, set]
 
string ID [get, set]
 
int ImageCount [get]
 
double PhysicalSizeX [get]
 
double PhysicalSizeY [get]
 
double PhysicalSizeZ [get]
 
double StageSizeX [get]
 
double StageSizeY [get]
 
double StageSizeZ [get]
 
AForge.Size PyramidalSize [get, set]
 
PointD PyramidalOrigin [get, set]
 
int series [get, set]
 
OpenSlideBase OpenSlideBase [get]
 
SlideBase SlideBase [get, set]
 
Channel RChannel [get]
 
Channel GChannel [get]
 
Channel BChannel [get]
 
List< ROIAnnotationsR [get]
 
List< ROIAnnotationsG [get]
 
List< ROIAnnotationsB [get]
 
int SizeX [get]
 
int SizeY [get]
 
int SizeZ [get]
 
int SizeC [get]
 
int SizeT [get]
 
double Magnification [get, set]
 
Order StackOrder [get, set]
 
object Tag [get, set]
 
IntRange RRange [get]
 
IntRange GRange [get]
 
IntRange BRange [get]
 
Bitmap SelectedBuffer [get]
 
bool isRGB [get]
 
bool isTime [get]
 
bool isSeries [get]
 
bool isPyramidal [get]
 
static string Status [get, set]
 
static bool Initialized [get]
 
int? MacroResolution [get, set]
 
int? LabelResolution [get, set]
 

Member Enumeration Documentation

◆ BackEnd

enum BioLib.BioImage.BackEnd
7183 {
7184 OpenSlide,
7185 Bioformats,
7186 LibVips,
7187 }

◆ ImageType

enum BioLib.BioImage.ImageType
1934 {
1935 stack,
1936 pyramidal,
1937 well,
1938 }

◆ Order

enum BioLib.BioImage.Order
2573 {
2574 ZCT,
2575 CZT,
2576 TCZ
2577 }

Constructor & Destructor Documentation

◆ BioImage()

BioLib.BioImage.BioImage ( string file)
3511 {
3512 id = file;
3513 this.file = file;
3514 filename = Images.GetImageName(id);
3515 Coordinate = new ZCT();
3516 rgbChannels[0] = 0;
3517 rgbChannels[1] = 0;
3518 rgbChannels[2] = 0;
3519 }

Member Function Documentation

◆ AutoThreshold() [1/2]

static void BioLib.BioImage.AutoThreshold ( )
static

It takes the current image, and finds the best threshold value for it.

8673 {
8674 AutoThreshold(bstats, update);
8675 }
static void AutoThreshold()
It takes the current image, and finds the best threshold value for it.
Definition Bio.cs:8672

◆ AutoThreshold() [2/2]

static void BioLib.BioImage.AutoThreshold ( BioImage b,
bool updateImageStats )
static

It takes a BioImage object, and calculates the mean histogram for each channel, and for the entire image.

The BioImage object is a class that contains a list of buffers, each of which contains a byte array of pixel data.

The function also calculates the mean histogram for each buffer, and stores it in the buffer's stats property.

The function also calculates the mean histogram for each channel, and stores it in the channel's stats property.

The function also calculates the mean histogram for the entire image, and stores it in the image's statistics property.

The mean histogram is calculated by adding up the histograms of each buffer, and then dividing by the number of buffers.

The histogram is calculated by looping through the byte array of pixel data, and incrementing the value of the histogram at the index of the pixel value.

The histogram

Parameters
BioImageThis is the image object that contains the image data.
updateImageStatsif true, the image stats will be updated.
8599 {
8600 bstats = b;
8601 Statistics statistics = null;
8602 if (b.bitsPerPixel > 8)
8603 statistics = new Statistics(true);
8604 else
8605 statistics = new Statistics(false);
8606 for (int i = 0; i < b.Buffers.Count; i++)
8607 {
8608 if (b.Buffers[i].Stats == null || updateImageStats)
8609 b.Buffers[i].Stats = Statistics.FromBytes(b.Buffers[i]);
8610 if (b.Buffers[i].RGBChannelsCount == 1)
8611 statistics.AddStatistics(b.Buffers[i].Stats[0]);
8612 else
8613 {
8614 for (int r = 0; r < b.Buffers[i].RGBChannelsCount; r++)
8615 {
8616 statistics.AddStatistics(b.Buffers[i].Stats[r]);
8617 }
8618 }
8619 }
8620 for (int c = 0; c < b.Channels.Count; c++)
8621 {
8622 Statistics[] sts = new Statistics[b.Buffers[0].RGBChannelsCount];
8623 for (int i = 0; i < b.Buffers[0].RGBChannelsCount; i++)
8624 {
8625 if (b.bitsPerPixel > 8)
8626 {
8627 sts[i] = new Statistics(true);
8628 }
8629 else
8630 sts[i] = new Statistics(false);
8631 }
8632 for (int z = 0; z < b.SizeZ; z++)
8633 {
8634 for (int t = 0; t < b.SizeT; t++)
8635 {
8636 int ind;
8637 if (b.Channels.Count > b.SizeC)
8638 {
8639 ind = b.GetFrameIndex(z, 0, t);
8640 }
8641 else
8642 ind = b.GetFrameIndex(z, c, t);
8643 if (b.Buffers[ind].RGBChannelsCount == 1)
8644 sts[0].AddStatistics(b.Buffers[ind].Stats[0]);
8645 else
8646 {
8647 sts[0].AddStatistics(b.Buffers[ind].Stats[0]);
8648 sts[1].AddStatistics(b.Buffers[ind].Stats[1]);
8649 sts[2].AddStatistics(b.Buffers[ind].Stats[2]);
8650 if (b.Buffers[ind].RGBChannelsCount == 4)
8651 sts[3].AddStatistics(b.Buffers[ind].Stats[3]);
8652 }
8653 }
8654 }
8655 if (b.RGBChannelCount == 1)
8656 sts[0].MeanHistogram();
8657 else
8658 {
8659 sts[0].MeanHistogram();
8660 sts[1].MeanHistogram();
8661 sts[2].MeanHistogram();
8662 if (b.Buffers[0].RGBChannelsCount == 4)
8663 sts[3].MeanHistogram();
8664 }
8665 b.Channels[c].stats = sts;
8666 }
8667 statistics.MeanHistogram();
8668 b.statistics = statistics;
8669 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), true, b, updateImageStats);
8670 }
Definition Recorder.cs:12
Definition Bio.cs:45

◆ AutoThresholdThread()

static void BioLib.BioImage.AutoThresholdThread ( BioImage b)
static

It creates a new thread that calls the AutoThreshold function.

Parameters
BioImageThis is a class that holds the image data and some other information.
8680 {
8681 bstats = b;
8682 Thread th = new Thread(AutoThreshold);
8683 th.Start();
8684 }

◆ Bake() [1/2]

void BioLib.BioImage.Bake ( int rmin,
int rmax,
int gmin,
int gmax,
int bmin,
int bmax )

Bake(int rmin, int rmax, int gmin, int gmax, int bmin, int bmax)

Parameters
rminThe minimum value of the red channel.
rmaxThe maximum value of the red channel.
gminThe minimum value of the green channel.
gmaxThe maximum value of the green channel.
bminThe minimum value of the blue channel.
bmaxThe maximum value of the blue channel.
3087 {
3088 Bake(new IntRange(rmin, rmax), new IntRange(gmin, gmax), new IntRange(bmin, bmax));
3089 }
void Bake(int rmin, int rmax, int gmin, int gmax, int bmin, int bmax)
Bake(int rmin, int rmax, int gmin, int gmax, int bmin, int bmax)
Definition Bio.cs:3086

◆ Bake() [2/2]

void BioLib.BioImage.Bake ( IntRange rf,
IntRange gf,
IntRange bf )

It takes a range of values for each channel, and creates a new image with the filtered values.

Parameters
IntRange
IntRange
IntRange
3097 {
3098 BioImage bm = new BioImage(Images.GetImageName(ID));
3099 bm = CopyInfo(this, true, true);
3100 for (int i = 0; i < Buffers.Count; i++)
3101 {
3102 ZCT co = Buffers[i].Coordinate;
3103 UnmanagedImage b = GetFiltered(i, rf, gf, bf);
3104 Bitmap inf = new Bitmap(bm.ID, b, co, i);
3105 bm.SetFrameIndex(co.Z, co.C, co.T, i);
3106 bm.Buffers.Add(inf);
3107 }
3108 foreach (Channel item in bm.Channels)
3109 {
3110 for (int i = 0; i < item.range.Length; i++)
3111 {
3112 item.range[i].Min = 0;
3113 if (bm.bitsPerPixel > 8)
3114 item.range[i].Max = ushort.MaxValue;
3115 else
3116 item.range[i].Max = 255;
3117 }
3118 }
3119 AutoThreshold(bm, true);
3120 Images.AddImage(bm);
3121 }
Definition Bio.cs:1849
Bitmap GetFiltered(ZCT coord, IntRange r, IntRange g, IntRange b)
Definition Bio.cs:4076
static BioImage CopyInfo(BioImage b, bool copyAnnotations, bool copyChannels)
Definition Bio.cs:2122

◆ CalculateFocusQuality()

static long BioLib.BioImage.CalculateFocusQuality ( Bitmap b)
static

The function calculates the focus quality of a given bitmap image.

Parameters
BitmapA class representing a bitmap image, which contains information about the image's size, pixel data, and color channels.
Returns
The method is returning a long value which represents the calculated focus quality of the input Bitmap image.
8724 {
8725 if (b.RGBChannelsCount == 1)
8726 {
8727 long sum = 0;
8728 long sumOfSquaresR = 0;
8729 for (int y = 0; y < b.SizeY; y++)
8730 for (int x = 0; x < b.SizeX; x++)
8731 {
8732 ColorS pixel = b.GetPixel(x, y);
8733 sum += pixel.R;
8734 sumOfSquaresR += pixel.R * pixel.R;
8735 }
8736 return sumOfSquaresR * b.SizeX * b.SizeY - sum * sum;
8737 }
8738 else
8739 {
8740 long sum = 0;
8741 long sumOfSquares = 0;
8742 for (int y = 0; y < b.SizeY; y++)
8743 for (int x = 0; x < b.SizeX; x++)
8744 {
8745 ColorS pixel = b.GetPixel(x, y);
8746 int p = (pixel.R + pixel.G + pixel.B) / 3;
8747 sum += p;
8748 sumOfSquares += p * p;
8749 }
8750 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), true, b);
8751 return sumOfSquares * b.SizeX * b.SizeY - sum * sum;
8752 }
8753 }

◆ Copy() [1/4]

BioImage BioLib.BioImage.Copy ( )

‍This function copies the current BioImage object and returns a new BioImage object

Returns
A copy of the BioImage object.
2112 {
2113 return BioImage.Copy(this, true);
2114 }
static BioImage Copy(BioImage b, bool rois)
Definition Bio.cs:2033

◆ Copy() [2/4]

static BioImage BioLib.BioImage.Copy ( BioImage b)
static

Copy a BioImage object.

Parameters
BioImageThe image to copy
Returns
A copy of the BioImage object.
2096 {
2097 return Copy(b, true);
2098 }
BioImage Copy()
Definition Bio.cs:2111

◆ Copy() [3/4]

static BioImage BioLib.BioImage.Copy ( BioImage b,
bool rois )
static

It copies the BioImage b and returns a new BioImage object.

Parameters
BioImageThe BioImage object to copy
roisIf true, the ROIs will be copied. If false, the ROIs will be ignored.
2034 {
2035 BioImage bi = new BioImage(b.ID);
2036 if (rois)
2037 foreach (ROI an in b.Annotations)
2038 {
2039 bi.Annotations.Add(an);
2040 }
2041 foreach (Bitmap bf in b.Buffers)
2042 {
2043 bi.Buffers.Add(bf.Copy());
2044 }
2045 foreach (Channel c in b.Channels)
2046 {
2047 bi.Channels.Add(c);
2048 }
2049 bi.Volume = b.Volume;
2050 bi.Coords = b.Coords;
2051 bi.sizeZ = b.sizeZ;
2052 bi.sizeC = b.sizeC;
2053 bi.sizeT = b.sizeT;
2054 bi.series = b.series;
2055 bi.seriesCount = b.seriesCount;
2056 bi.frameInterval = b.frameInterval;
2057 bi.littleEndian = b.littleEndian;
2058 bi.isGroup = b.isGroup;
2059 bi.imageInfo = b.imageInfo;
2060 bi.bitsPerPixel = b.bitsPerPixel;
2061 bi.file = b.file;
2062 bi.filename = b.filename;
2063 foreach (var item in b.Resolutions)
2064 {
2065 bi.Resolutions.Add(item);
2066 }
2067 bi.statistics = b.statistics;
2068 bi.MacroResolution = b.MacroResolution;
2069 bi.LabelResolution = b.LabelResolution;
2070 bi.Resolution = b.Resolution;
2071 bi.imagesPerSeries = b.imagesPerSeries;
2072 bi.imRead = b.imRead;
2073 bi.Type = b.Type;
2074 bi.tifRead = b.tifRead;
2075 if (b.OpenSlideBase != null)
2076 {
2077 bi.openslideBase = b.openslideBase;
2078 bi.openSlideImage = b.openSlideImage;
2079 }
2080 else
2081 {
2082 bi.slideBase = b.slideBase;
2083 }
2084 bi.PyramidalOrigin = b.PyramidalOrigin;
2085 bi.PyramidalSize = b.PyramidalSize;
2086 bi.Plate = b.Plate;
2087 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, b, rois);
2088 return bi;
2089 }
Definition ROI.cs:27

◆ Copy() [4/4]

BioImage BioLib.BioImage.Copy ( bool rois)

Copy the image and optionally the ROIs

Parameters
roisBoolean value indicating whether to copy the ROIs or not.
Returns
A copy of the BioImage object.
2105 {
2106 return BioImage.Copy(this, rois);
2107 }

◆ CopyInfo()

static BioImage BioLib.BioImage.CopyInfo ( BioImage b,
bool copyAnnotations,
bool copyChannels )
static

CopyInfo() copies the information from one BioImage to another

Parameters
BioImagethe image to copy
copyAnnotationstrue
copyChannelstrue
Returns
A new BioImage object.
2123 {
2124 BioImage bi = new BioImage(b.ID);
2125 if (copyAnnotations)
2126 foreach (ROI an in b.Annotations)
2127 {
2128 bi.Annotations.Add(an);
2129 }
2130 if (copyChannels)
2131 foreach (Channel c in b.Channels)
2132 {
2133 bi.Channels.Add(c.Copy());
2134 }
2135 foreach (var item in b.Resolutions)
2136 {
2137 bi.Resolutions.Add(item);
2138 }
2139 bi.Coords = b.Coords;
2140 bi.Volume = b.Volume;
2141 bi.sizeZ = b.sizeZ;
2142 bi.sizeC = b.sizeC;
2143 bi.sizeT = b.sizeT;
2144 bi.series = b.series;
2145 bi.seriesCount = b.seriesCount;
2146 bi.frameInterval = b.frameInterval;
2147 bi.littleEndian = b.littleEndian;
2148 bi.isGroup = b.isGroup;
2149 bi.imageInfo = b.imageInfo;
2150 bi.bitsPerPixel = b.bitsPerPixel;
2151 bi.Coordinate = b.Coordinate;
2152 bi.file = b.file;
2153 bi.Filename = b.Filename;
2154 bi.ID = Images.GetImageName(b.file);
2155 bi.statistics = b.statistics;
2156 bi.MacroResolution = b.MacroResolution;
2157 bi.LabelResolution = b.LabelResolution;
2158 bi.Resolution = b.Resolution;
2159 bi.imagesPerSeries = b.imagesPerSeries;
2160 bi.imRead = b.imRead;
2161 bi.tifRead = b.tifRead;
2162 bi.Type = b.Type;
2163 bi.PyramidalOrigin = b.PyramidalOrigin;
2164 bi.PyramidalSize = b.PyramidalSize;
2165 if (b.OpenSlideBase != null)
2166 {
2167 bi.openslideBase = b.openslideBase;
2168 bi.openSlideImage = b.openSlideImage;
2169 }
2170 else
2171 {
2172 bi.slideBase = b.slideBase;
2173 }
2174 bi.Plate = b.Plate;
2175 return bi;
2176 }

◆ Dispose()

void BioLib.BioImage.Dispose ( )

It disposes of all the buffers and channels in the image, removes the image from the Images list, and then forces the garbage collector to run.

8757 {
8758 for (int i = 0; i < Buffers.Count; i++)
8759 {
8760 Buffers[i].Dispose();
8761 }
8762 for (int i = 0; i < Channels.Count; i++)
8763 {
8764 Channels[i].Dispose();
8765 }
8766 for (int i = 0; i < Annotations.Count; i++)
8767 {
8768 Annotations[i].Dispose();
8769 }
8770 }

◆ ExportROIFolder()

static void BioLib.BioImage.ExportROIFolder ( string path,
string filename )
static

ExportROIFolder(path, filename)

This function takes a folder path and a filename as input and exports all the ROIs in the folder as CSV files

Parameters
paththe path to the folder containing the OMERO ROI files
filenamethe name of the file you want to export
8558 {
8559 string[] fs = Directory.GetFiles(path);
8560 int i = 0;
8561 foreach (string f in fs)
8562 {
8563 List<ROI> annotations = OpenOMEROIs(f, 0);
8564 string ff = Path.GetFileNameWithoutExtension(f);
8565 ExportROIsCSV(path + "//" + ff + "-" + i.ToString() + ".csv", annotations);
8566 i++;
8567 }
8568 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, path, filename);
8569 }
static void ExportROIsCSV(string filename, List< ROI > Annotations)
This function takes a list of ROIs and writes them to a CSV file.
Definition Bio.cs:8524
static List< ROI > OpenOMEROIs(string file, int series)
It reads the OME-XML file and converts the ROIs to a list of ROI objects.
Definition Bio.cs:7941

◆ ExportROIsCSV()

static void BioLib.BioImage.ExportROIsCSV ( string filename,
List< ROI > Annotations )
static

This function takes a list of ROIs and writes them to a CSV file.

Parameters
filenamethe name of the file to be saved
AnnotationsList of ROI objects
8525 {
8526 string con = columns;
8527 con += ROIsToString(Annotations);
8528 File.WriteAllText(filename, con);
8529 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, filename, Annotations);
8530 }
static string ROIsToString(List< ROI > Annotations)
It takes a list of ROI objects and returns a string of all the ROI objects in the list.
Definition Bio.cs:8325

◆ ExtractRegionFromTiledTiff()

static Bitmap BioLib.BioImage.ExtractRegionFromTiledTiff ( BioImage b,
int x,
int y,
int width,
int height,
int level )
static

The function ExtractRegionFromTiledTiff takes a BioImage object, coordinates, width, height, and resolution as input, and returns a Bitmap object representing the extracted region from the tiled TIFF image.

Parameters
BioImageThe BioImage object represents an image file that contains multiple pages or resolutions. It contains information about the image file, such as the file path, the number of pages, and the format of each page.
xThe x-coordinate of the top-left corner of the region to extract from the tiled TIFF image.
yThe parameter "y" represents the starting y-coordinate of the region to be extracted from the tiled TIFF image.
widthThe width parameter represents the width of the region to be extracted from the tiled TIFF image.
heightThe height parameter represents the height of the region to be extracted from the tiled TIFF image.
resThe parameter "res" represents the resolution level of the tiled TIFF image. It is used to specify the level of detail or zoom level at which the image is being extracted.
Returns
The method is returning a Bitmap object.
6303 {
6304 try
6305 {
6306 // Validate inputs
6307 if (b == null) throw new ArgumentNullException(nameof(b));
6308 if (b.vipPages == null || b.vipPages.Count <= level) throw new ArgumentException("Invalid image level.");
6309
6310 // Extract the region from the specified level
6311 NetVips.Image subImage = b.vipPages[level].ExtractArea(x, y, width, height);
6312
6313 // Convert the NetVips.Image to Bitmap
6314 Bitmap bitmap = ConvertVipsImageToBitmap(subImage, b.bitsPerPixel);
6315
6316 // Clean up
6317 subImage.Dispose();
6318
6319 return bitmap;
6320 }
6321 catch (Exception ex)
6322 {
6323 Console.WriteLine($"Error: {ex.Message}\n{ex.StackTrace}");
6324 return null;
6325 }
6326 }

◆ FilesToStack()

static BioImage BioLib.BioImage.FilesToStack ( string[] files,
int sizeZ,
int sizeC,
int sizeT )
static

It takes a list of files, and creates a new BioImage object with the first file in the list. Then it loops through the rest of the files, adding the buffers from each file to the new BioImage object. Finally, it updates the coordinates of the new BioImage object, and adds it to the Images list.

Parameters
filesan array of file paths
sizeZnumber of slices in the stack
sizeCnumber of channels
sizeTnumber of time points
Returns
A BioImage object.
6195 {
6196 BioImage b = new BioImage(files[0]);
6197 for (int i = 0; i < files.Length; i++)
6198 {
6199 BioImage bb = OpenFile(files[i], false);
6200 b.Buffers.AddRange(bb.Buffers);
6201 }
6202 b.UpdateCoords(sizeZ, sizeC, sizeT);
6203 Images.AddImage(b);
6204 return b;
6205 }
static BioImage OpenFile(string file)
This function opens a file and returns a BioImage object.
Definition Bio.cs:4799
void UpdateCoords()
It takes a list of images and assigns them to a 3D array of coordinates.
Definition Bio.cs:3123

◆ FindFocus()

static int BioLib.BioImage.FindFocus ( BioImage im,
int Channel,
int Time )
static

The function finds the focus of a given BioImage at a specific channel and time by calculating the focus quality of each Z-plane and returning the coordinate with the highest focus quality.

Parameters
BioImageA BioImage object that contains the image data.
ChannelThe channel of the BioImage to analyze. A BioImage can have multiple channels, each representing a different fluorescent label or imaging modality.
TimeThe time point at which the focus is being calculated.
Returns
an integer value which represents the coordinate of the image with the highest focus quality in a given channel and time.
8697 {
8698 long mf = 0;
8699 int fr = 0;
8700 List<double> dt = new List<double>();
8701 ZCT c = new ZCT(0, 0, 0);
8702 for (int i = 0; i < im.SizeZ; i++)
8703 {
8704 long f = CalculateFocusQuality(im.Buffers[im.GetFrameIndex(i, Channel, Time)]);
8705 dt.Add(f);
8706 if (f > mf)
8707 {
8708 mf = f;
8709 fr = im.GetFrameIndex(i, Channel, Time);
8710 }
8711 }
8712
8713 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, im, Channel, Time);
8714 return fr;
8715 }
static long CalculateFocusQuality(Bitmap b)
The function calculates the focus quality of a given bitmap image.
Definition Bio.cs:8723

◆ FolderToStack()

static BioImage BioLib.BioImage.FolderToStack ( string path,
bool tab )
static

It takes a folder of images and creates a stack from them.

Parameters
paththe path to the folder containing the images
Returns
A BioImage object.
6212 {
6213 string[] files = Directory.GetFiles(path);
6214 BioImage b = new BioImage(files[0]);
6215 int z = 0;
6216 int c = 0;
6217 int t = 0;
6218 BioImage bb = null;
6219 for (int i = 0; i < files.Length; i++)
6220 {
6221 string[] st = files[i].Split('_');
6222 if (st.Length > 3)
6223 {
6224 z = int.Parse(st[1].Replace("Z", ""));
6225 c = int.Parse(st[2].Replace("C", ""));
6226 t = int.Parse(st[3].Replace("T", ""));
6227 }
6228 bb = OpenFile(files[i], tab);
6229 b.Buffers.AddRange(bb.Buffers);
6230 }
6231 if (z == 0)
6232 {
6233 /*TO DO
6234 ImagesToStack im = new ImagesToStack();
6235 if (im.ShowDialog() != DialogResult.OK)
6236 return null;
6237 b.UpdateCoords(im.SizeZ, im.SizeC, im.SizeT);
6238 */
6239 }
6240 else
6241 b.UpdateCoords(z + 1, c + 1, t + 1);
6242 Images.AddImage(b);
6243 return b;
6244 }

◆ FromNumpy()

static BioImage BioLib.BioImage.FromNumpy ( string file)
static

Converts a numpy array to BioImage.

Parameters
file
Returns
5971 {
5972 BioImage bm = new BioImage(file);
5973 var (shape, dataType, data) = NumPy.ReadNpyFile(file);
5974
5975 // Handle different shapes and cast the data into appropriate multi-dimensional arrays
5976 if (shape.Length == 5)
5977 {
5978 if (dataType == NumPy.NpyDataType.Float32)
5979 {
5980 float[,,,,] fs = NumPy.ConvertToMultidimensional<float, float[,,,,]>(data, shape);
5981 for (int z = 0; z < shape[2]; z++)
5982 {
5983 for (int c = 0; c < shape[1]; c++)
5984 {
5985 for (int t = 0; t < shape[0]; t++)
5986 {
5987 Bitmap b = new Bitmap(shape[3], shape[4], PixelFormat.Float);
5988 for (int y = 0; y < shape[4]; y++)
5989 {
5990 for (int x = 0; x < shape[3]; x++)
5991 {
5992 b.SetValue(x, y, fs[t, c, z, x, y]);
5993 }
5994 }
5995 bm.Buffers.Add(b);
5996 }
5997 }
5998 }
5999 }
6000 else if (dataType == NumPy.NpyDataType.UInt8)
6001 {
6002 uint[,,,,] fs = NumPy.ConvertToMultidimensional<uint, uint[,,,,]>(data, shape);
6003 for (int z = 0; z < shape[2]; z++)
6004 {
6005 for (int c = 0; c < shape[1]; c++)
6006 {
6007 for (int t = 0; t < shape[0]; t++)
6008 {
6009 Bitmap b = new Bitmap(shape[3], shape[4], PixelFormat.Format8bppIndexed);
6010 for (int y = 0; y < shape[4]; y++)
6011 {
6012 for (int x = 0; x < shape[3]; x++)
6013 {
6014 b.SetValue(x, y, fs[t, c, z, x, y]);
6015 }
6016 }
6017 bm.Buffers.Add(b);
6018 }
6019 }
6020 }
6021 }
6022 bm.sizeZ = shape[2];
6023 bm.sizeC = shape[1];
6024 bm.sizeT = shape[0];
6025 }
6026 else if (shape.Length == 4)
6027 {
6028 if (dataType == NumPy.NpyDataType.Float32)
6029 {
6030 float[,,,] fs = NumPy.ConvertToMultidimensional<float, float[,,,]>(data, shape);
6031 for (int z = 0; z < shape[1]; z++)
6032 {
6033 for (int c = 0; c < shape[0]; c++)
6034 {
6035 Bitmap b = new Bitmap(shape[2], shape[3], PixelFormat.Float);
6036 for (int y = 0; y < shape[3]; y++)
6037 {
6038 for (int x = 0; x < shape[2]; x++)
6039 {
6040 b.SetValue(x, y, fs[c, z, x, y]);
6041 }
6042 }
6043 bm.Buffers.Add(b);
6044 }
6045 }
6046 }
6047 else if (dataType == NumPy.NpyDataType.UInt8)
6048 {
6049 uint[,,,] fs = NumPy.ConvertToMultidimensional<uint, uint[,,,]>(data, shape);
6050 for (int z = 0; z < shape[1]; z++)
6051 {
6052 for (int c = 0; c < shape[0]; c++)
6053 {
6054 Bitmap b = new Bitmap(shape[2], shape[3], PixelFormat.Format8bppIndexed);
6055 for (int y = 0; y < shape[3]; y++)
6056 {
6057 for (int x = 0; x < shape[2]; x++)
6058 {
6059 b.SetValue(x, y, fs[c, z, x, y]);
6060 }
6061 }
6062 bm.Buffers.Add(b);
6063 }
6064 }
6065 }
6066 bm.sizeZ = shape[1];
6067 bm.sizeC = shape[0];
6068 }
6069 else if (shape.Length == 3)
6070 {
6071 if (dataType == NumPy.NpyDataType.Float32)
6072 {
6073 float[,,] fs = NumPy.ConvertToMultidimensional<float, float[,,]>(data, shape);
6074 for (int z = 0; z < shape[0]; z++)
6075 {
6076 Bitmap b = new Bitmap(shape[1], shape[2], PixelFormat.Float);
6077 for (int y = 0; y < shape[1]; y++)
6078 {
6079 for (int x = 0; x < shape[2]; x++)
6080 {
6081 b.SetValue(x, y, fs[z, x, y]);
6082 }
6083 }
6084 bm.Buffers.Add(b);
6085 }
6086 }
6087 else if (dataType == NumPy.NpyDataType.UInt8)
6088 {
6089 uint[,,] fs = NumPy.ConvertToMultidimensional<uint, uint[,,]>(data, shape);
6090 for (int z = 0; z < shape[0]; z++)
6091 {
6092 Bitmap b = new Bitmap(shape[1], shape[2], PixelFormat.Format8bppIndexed);
6093 for (int y = 0; y < shape[1]; y++)
6094 {
6095 for (int x = 0; x < shape[2]; x++)
6096 {
6097 b.SetValue(x, y, fs[z, x, y]);
6098 }
6099 }
6100 bm.Buffers.Add(b);
6101 }
6102 }
6103 bm.sizeZ = shape[0];
6104 bm.sizeC = 1;
6105 }
6106 else if (shape.Length == 2)
6107 {
6108 if (dataType == NumPy.NpyDataType.Float32)
6109 {
6110 float[,] fs = NumPy.ConvertToMultidimensional<float, float[,]>(data, shape);
6111 Bitmap b = new Bitmap(shape[0], shape[1], PixelFormat.Float);
6112 for (int y = 0; y < shape[1]; y++)
6113 {
6114 for (int x = 0; x < shape[0]; x++)
6115 {
6116 b.SetValue(x, y, fs[x, y]);
6117 }
6118 }
6119 bm.Buffers.Add(b);
6120 }
6121 else if (dataType == NumPy.NpyDataType.UInt8)
6122 {
6123 uint[,] fs = NumPy.ConvertToMultidimensional<uint, uint[,]>(data, shape);
6124 Bitmap b = new Bitmap(shape[0], shape[1], PixelFormat.Format8bppIndexed);
6125 for (int y = 0; y < shape[1]; y++)
6126 {
6127 for (int x = 0; x < shape[0]; x++)
6128 {
6129 b.SetValue(x, y, fs[x, y]);
6130 }
6131 }
6132 bm.Buffers.Add(b);
6133 }
6134 bm.sizeC = 1;
6135 bm.sizeZ = 1;
6136 }
6137 else
6138 {
6139 throw new InvalidOperationException("Unsupported array shape.");
6140 }
6141
6142 for (int i = 0; i < bm.SizeC; i++)
6143 {
6144 if (bm.Buffers[0].PixelFormat == PixelFormat.Float || bm.Buffers[0].PixelFormat == PixelFormat.UInt || bm.Buffers[0].PixelFormat == PixelFormat.Int)
6145 bm.Channels.Add(new Channel(i, 32, 1));
6146 else
6147 if (bm.Buffers[0].PixelFormat == PixelFormat.Format8bppIndexed)
6148 bm.Channels.Add(new Channel(i, 8, 1));
6149 }
6150 bm.sizeT = 1;
6151 bm.Coords = new int[bm.SizeZ, bm.SizeC, bm.SizeT];
6152 bm.UpdateCoords();
6153 bm.bitsPerPixel = 8;
6154 if (dataType == NumPy.NpyDataType.Float32)
6155 bm.Resolutions.Add(new Resolution(bm.SizeX, bm.SizeY, PixelFormat.Float, 96 * (1 / 2.54) / 1000, 96 * (1 / 2.54) / 1000, 96 * (1 / 2.54) / 1000, 0, 0, 0));
6156 else
6157 if (dataType == NumPy.NpyDataType.UInt32)
6158 bm.Resolutions.Add(new Resolution(bm.SizeX, bm.SizeY, PixelFormat.UInt, 96 * (1 / 2.54) / 1000, 96 * (1 / 2.54) / 1000, 96 * (1 / 2.54) / 1000, 0, 0, 0));
6159 else
6160 if (dataType == NumPy.NpyDataType.Int32)
6161 bm.Resolutions.Add(new Resolution(bm.SizeX, bm.SizeY, PixelFormat.Int, 96 * (1 / 2.54) / 1000, 96 * (1 / 2.54) / 1000, 96 * (1 / 2.54) / 1000, 0, 0, 0));
6162 else
6163 if (dataType == NumPy.NpyDataType.UInt8)
6164 bm.Resolutions.Add(new Resolution(bm.SizeX, bm.SizeY, PixelFormat.Format8bppIndexed, 96 * (1 / 2.54) / 1000, 96 * (1 / 2.54) / 1000, 96 * (1 / 2.54) / 1000, 0, 0, 0));
6165 foreach (var item in bm.Buffers)
6166 {
6167 item.Stats = Statistics.FromBytes(item);
6168 }
6169 bm.Type = ImageType.stack;
6170 bm.Volume = new VolumeD(new Point3D(bm.StageSizeX, bm.StageSizeY, bm.StageSizeZ), new Point3D(bm.PhysicalSizeX * bm.SizeX, bm.PhysicalSizeY * bm.SizeY, bm.PhysicalSizeZ * bm.SizeZ));
6171 AutoThreshold(bm, false);
6172 if (bm.bitsPerPixel > 8)
6173 bm.StackThreshold(true);
6174 else
6175 bm.StackThreshold(false);
6176 bm.StackOrder = Order.ZCT;
6177 bm.ID = Path.GetFileName(file);
6178 bm.Filename = bm.ID;
6179 bm.file = file;
6180 Images.AddImage(bm);
6181 return bm;
6182 }
void StackThreshold(bool bit16)
This function sets the minimum and maximum values of the image to the minimum and maximum values of t...
Definition Bio.cs:7316
Definition Bio.cs:1142
ImageType
Image type.
Definition ISlideSource.cs:553
Definition Bio.cs:178

◆ GetAnnotations() [1/2]

List< ROI > BioLib.BioImage.GetAnnotations ( int Z,
int C,
int T )

This function returns a list of ROI objects that are associated with the specified Z, C, and T coordinates.

Parameters
ZThe Z-stack index
CChannel
TTime
Returns
A list of ROI objects.
4422 {
4423 List<ROI> annotations = new List<ROI>();
4424 foreach (ROI an in Annotations)
4425 {
4426 if (an.coord.Z == Z && an.coord.Z == Z && an.coord.C == C && an.coord.T == T)
4427 annotations.Add(an);
4428 }
4429 return annotations;
4430 }

◆ GetAnnotations() [2/2]

List< ROI > BioLib.BioImage.GetAnnotations ( ZCT coord)

GetAnnotations() returns a list of ROI objects that are associated with the ZCT coordinate passed in as a parameter

Parameters
ZCTa 3D coordinate (Z, C, T)
Returns
A list of ROI objects.
4402 {
4403 List<ROI> annotations = new List<ROI>();
4404 foreach (ROI an in Annotations)
4405 {
4406 if (an == null)
4407 continue;
4408 if (an.coord == coord)
4409 annotations.Add(an);
4410 }
4411 return annotations;
4412 }

◆ GetBands()

static int BioLib.BioImage.GetBands ( PixelFormat format)
static

The function "GetBands" returns the number of color bands for a given pixel format in the AForge library.

Parameters
PixelFormatThe PixelFormat parameter is an enumeration that represents the format of a pixel in an image. It specifies the number of bits per pixel and the color space used by the pixel. The PixelFormat enumeration is defined in the AForge.Imaging namespace.
Returns
The method is returning the number of color bands for a given pixel format.
5782 {
5783 switch (format)
5784 {
5785 case AForge.PixelFormat.Format8bppIndexed: return 1;
5786 case AForge.PixelFormat.Format16bppGrayScale: return 1;
5787 case AForge.PixelFormat.Format24bppRgb: return 3;
5788 case AForge.PixelFormat.Format32bppArgb:
5789 case AForge.PixelFormat.Format32bppPArgb:
5790 case AForge.PixelFormat.Format32bppRgb:
5791 return 4;
5792 case AForge.PixelFormat.Format48bppRgb:
5793 return 3;
5794 default:
5795 throw new NotSupportedException($"Unsupported pixel format: {format}");
5796 }
5797 }

◆ GetBitmap() [1/2]

Bitmap BioLib.BioImage.GetBitmap ( int z,
int c,
int t )

"Given a z, c, t coordinate, return the bitmap at that coordinate."

The function is called by the following code:

Parameters
zthe z-stack index
cchannel
ttime
Returns
A bitmap.
3890 {
3891 return Buffers[GetFrameIndex(z, c, t)];
3892 }

◆ GetBitmap() [2/2]

Bitmap BioLib.BioImage.GetBitmap ( ZCT coord)

‍This function returns a Bitmap object from the image data stored in the OME-TIFF file

Parameters
ZCTZ = Z-stack, C = channel, T = timepoint
Returns
A Bitmap object.
4065 {
4066 return (Bitmap)GetImageByCoord(coord.Z, coord.C, coord.T);
4067 }
Bitmap GetImageByCoord(int z, int c, int t)
Definition Bio.cs:3876

◆ GetBitmapRGB()

static unsafe Bitmap BioLib.BioImage.GetBitmapRGB ( int w,
int h,
PixelFormat px,
byte[] bts )
static

It takes a byte array of RGB or RGBA data and converts it to a Bitmap.

Parameters
wwidth of the image
hheight of the image
PixelFormatThe pixel format of the image.
btsthe byte array of the image
Returns
A Bitmap object.
4236 {
4237 if (px == PixelFormat.Format32bppArgb)
4238 {
4239 //opening a 8 bit per pixel jpg image
4240 Bitmap bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);
4241 //creating the bitmapdata and lock bits
4242 AForge.Rectangle rec = new AForge.Rectangle(0, 0, w, h);
4243 BitmapData bmd = bmp.LockBits(rec, ImageLockMode.ReadWrite, bmp.PixelFormat);
4244 //iterating through all the pixels in y direction
4245 for (int y = 0; y < h; y++)
4246 {
4247 //getting the pixels of current row
4248 byte* row = (byte*)bmd.Scan0 + (y * bmd.Stride);
4249 int rowRGB = y * w * 4;
4250 //iterating through all the pixels in x direction
4251 for (int x = 0; x < w; x++)
4252 {
4253 int indexRGB = x * 4;
4254 int indexRGBA = x * 4;
4255 row[indexRGBA + 3] = bts[rowRGB + indexRGB + 3];//byte A
4256 row[indexRGBA + 2] = bts[rowRGB + indexRGB + 2];//byte R
4257 row[indexRGBA + 1] = bts[rowRGB + indexRGB + 1];//byte G
4258 row[indexRGBA] = bts[rowRGB + indexRGB];//byte B
4259 }
4260 }
4261 //unlocking bits and disposing image
4262 bmp.UnlockBits(bmd);
4263 return bmp;
4264 }
4265 else if (px == PixelFormat.Format24bppRgb)
4266 {
4267 //opening a 8 bit per pixel jpg image
4268 Bitmap bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);
4269 //creating the bitmapdata and lock bits
4270 AForge.Rectangle rec = new AForge.Rectangle(0, 0, w, h);
4271 BitmapData bmd = bmp.LockBits(rec, ImageLockMode.ReadWrite, bmp.PixelFormat);
4272 //iterating through all the pixels in y direction
4273 for (int y = 0; y < h; y++)
4274 {
4275 //getting the pixels of current row
4276 byte* row = (byte*)bmd.Scan0 + (y * bmd.Stride);
4277 int rowRGB = y * w * 3;
4278 //iterating through all the pixels in x direction
4279 for (int x = 0; x < w; x++)
4280 {
4281 int indexRGB = x * 3;
4282 int indexRGBA = x * 4;
4283 row[indexRGBA + 3] = byte.MaxValue;//byte A
4284 row[indexRGBA + 2] = bts[rowRGB + indexRGB + 2];//byte R
4285 row[indexRGBA + 1] = bts[rowRGB + indexRGB + 1];//byte G
4286 row[indexRGBA] = bts[rowRGB + indexRGB];//byte B
4287 }
4288 }
4289 //unlocking bits and disposing image
4290 bmp.UnlockBits(bmd);
4291 return bmp;
4292 }
4293 else
4294 if (px == PixelFormat.Format48bppRgb)
4295 {
4296 //opening a 8 bit per pixel jpg image
4297 Bitmap bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);
4298 //creating the bitmapdata and lock bits
4299 AForge.Rectangle rec = new AForge.Rectangle(0, 0, w, h);
4300 BitmapData bmd = bmp.LockBits(rec, ImageLockMode.ReadWrite, bmp.PixelFormat);
4301 unsafe
4302 {
4303 //iterating through all the pixels in y direction
4304 for (int y = 0; y < h; y++)
4305 {
4306 //getting the pixels of current row
4307 byte* row = (byte*)bmd.Scan0 + (y * bmd.Stride);
4308 int rowRGB = y * w * 6;
4309 //iterating through all the pixels in x direction
4310 for (int x = 0; x < w; x++)
4311 {
4312 int indexRGB = x * 6;
4313 int indexRGBA = x * 4;
4314 int b = (int)((float)BitConverter.ToUInt16(bts, rowRGB + indexRGB) / 255);
4315 int g = (int)((float)BitConverter.ToUInt16(bts, rowRGB + indexRGB + 2) / 255);
4316 int r = (int)((float)BitConverter.ToUInt16(bts, rowRGB + indexRGB + 4) / 255);
4317 row[indexRGBA + 3] = 255;//byte A
4318 row[indexRGBA + 2] = (byte)(b);//byte R
4319 row[indexRGBA + 1] = (byte)(g);//byte G
4320 row[indexRGBA] = (byte)(r);//byte B
4321 }
4322 }
4323 }
4324 bmp.UnlockBits(bmd);
4325 return bmp;
4326 }
4327 else
4328 if (px == PixelFormat.Format8bppIndexed)
4329 {
4330 //opening a 8 bit per pixel jpg image
4331 Bitmap bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);
4332 //creating the bitmapdata and lock bits
4333 AForge.Rectangle rec = new AForge.Rectangle(0, 0, w, h);
4334 BitmapData bmd = bmp.LockBits(rec, ImageLockMode.ReadWrite, bmp.PixelFormat);
4335 unsafe
4336 {
4337 //iterating through all the pixels in y direction
4338 for (int y = 0; y < h; y++)
4339 {
4340 //getting the pixels of current row
4341 byte* row = (byte*)bmd.Scan0 + (y * bmd.Stride);
4342 int rowRGB = y * w;
4343 //iterating through all the pixels in x direction
4344 for (int x = 0; x < w; x++)
4345 {
4346 int indexRGB = x;
4347 int indexRGBA = x * 4;
4348 byte b = bts[rowRGB + indexRGB];
4349 row[indexRGBA + 3] = 255;//byte A
4350 row[indexRGBA + 2] = (byte)(b);//byte R
4351 row[indexRGBA + 1] = (byte)(b);//byte G
4352 row[indexRGBA] = (byte)(b);//byte B
4353 }
4354 }
4355 }
4356 bmp.UnlockBits(bmd);
4357 return bmp;
4358 }
4359 else
4360 if (px == PixelFormat.Format16bppGrayScale)
4361 {
4362 //opening a 8 bit per pixel jpg image
4363 Bitmap bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);
4364 //creating the bitmapdata and lock bits
4365 AForge.Rectangle rec = new AForge.Rectangle(0, 0, w, h);
4366 BitmapData bmd = bmp.LockBits(rec, ImageLockMode.ReadWrite, bmp.PixelFormat);
4367 unsafe
4368 {
4369 //iterating through all the pixels in y direction
4370 for (int y = 0; y < h; y++)
4371 {
4372 //getting the pixels of current row
4373 byte* row = (byte*)bmd.Scan0 + (y * bmd.Stride);
4374 int rowRGB = y * w * 2;
4375 //iterating through all the pixels in x direction
4376 for (int x = 0; x < w; x++)
4377 {
4378 int indexRGB = x * 2;
4379 int indexRGBA = x * 4;
4380 ushort b = (ushort)((float)BitConverter.ToUInt16(bts, rowRGB + indexRGB) / 255);
4381 row[indexRGBA + 3] = 255;//byte A
4382 row[indexRGBA + 2] = (byte)(b);//byte R
4383 row[indexRGBA + 1] = (byte)(b);//byte G
4384 row[indexRGBA] = (byte)(b);//byte B
4385 }
4386 }
4387 }
4388 bmp.UnlockBits(bmd);
4389 return bmp;
4390 }
4391
4392 throw new NotSupportedException("Pixelformat " + px + " is not supported.");
4393 }

◆ GetBitMaxValue()

static int BioLib.BioImage.GetBitMaxValue ( int bt)
static

It returns the maximum value of a bit.

Parameters
btbit depth
Returns
The maximum value of a bit.
7383 {
7384 if (bt == 8)
7385 return 255;
7386 if (bt == 9)
7387 return 512;
7388 else if (bt == 10)
7389 return 1023;
7390 else if (bt == 11)
7391 return 2047;
7392 else if (bt == 12)
7393 return 4095;
7394 else if (bt == 13)
7395 return 8191;
7396 else if (bt == 14)
7397 return 16383;
7398 else if (bt == 15)
7399 return 32767;
7400 else
7401 return 65535;
7402 }

◆ GetBitsPerPixel()

static int BioLib.BioImage.GetBitsPerPixel ( int bt)
static

‍If the number is less than or equal to 255, then it's 8 bits. If it's less than or equal to 512, then it's 9 bits. If it's less than or equal to 1023, then it's 10 bits. If it's less than or equal to 2047, then it's 11 bits. If it's less than or equal to 4095, then it's 12 bits. If it's less than or equal to 8191, then it's 13 bits. If it's less than or equal to 16383, then it's 14 bits. If it's less than or equal to 32767, then it's 15 bits. If it's less than or equal to 65535, then it's 16 bits

Parameters
btThe number of bits per pixel.
Returns
The number of bits per pixel.
7357 {
7358 if (bt <= 255)
7359 return 8;
7360 if (bt <= 512)
7361 return 9;
7362 else if (bt <= 1023)
7363 return 10;
7364 else if (bt <= 2047)
7365 return 11;
7366 else if (bt <= 4095)
7367 return 12;
7368 else if (bt <= 8191)
7369 return 13;
7370 else if (bt <= 16383)
7371 return 14;
7372 else if (bt <= 32767)
7373 return 15;
7374 else
7375 return 16;
7376 }

◆ GetChannelImage()

UnmanagedImage BioLib.BioImage.GetChannelImage ( int ind,
short s )

It takes an image, and returns a channel of that image.

Parameters
indthe index of the buffer
s0, 1, 2
4142 {
4143 Bitmap bf = Buffers[ind];
4144 if (bf.isRGB)
4145 {
4146 if (s == 0)
4147 return extractR.Apply(Buffers[ind].Image);
4148 else
4149 if (s == 1)
4150 return extractG.Apply(Buffers[ind].Image);
4151 else
4152 return extractB.Apply(Buffers[ind].Image);
4153 }
4154 else
4155 throw new InvalidOperationException();
4156 }

◆ GetEmission()

Bitmap BioLib.BioImage.GetEmission ( ZCT coord,
IntRange rf,
IntRange gf,
IntRange bf )

GetEmission() returns an UnmanagedImage object that is a composite of the emission channels

Parameters
ZCTZ, C, T coordinates
IntRange
IntRange
IntRange
Returns
A Bitmap or an UnmanagedImage.
4167 {
4168 if (RGBChannelCount == 1)
4169 {
4170 Bitmap[] bs = new Bitmap[Channels.Count];
4171 List<Channel> chs = new List<Channel>();
4172 for (int c = 0; c < Channels.Count; c++)
4173 {
4174 int index = GetFrameIndex(coord.Z, c, coord.T);
4175 bs[c] = Buffers[index];
4176 chs.Add(Channels[c]);
4177 }
4178 Bitmap bm = (Bitmap)Bitmap.GetEmissionBitmap(bs, chs.ToArray());
4179 return bm;
4180 }
4181 else
4182 {
4183 int index = GetFrameIndex(coord.Z, coord.C, coord.T);
4184 return Buffers[index];
4185 }
4186 }

◆ GetFiltered() [1/2]

Bitmap BioLib.BioImage.GetFiltered ( int ind,
IntRange r,
IntRange g,
IntRange b )

It takes an image, and returns a filtered version of that image.

Parameters
indthe index of the buffer to be filtered
IntRange
IntRange
IntRange
Returns
A filtered image.
4102 {
4103 if (Buffers[ind].PixelFormat == PixelFormat.Float)
4104 {
4105 if (Statistics.StackMax <= 1)
4106 {
4107 Bitmap bm = Buffers[ind].GetImageRGBA(true);
4108 return bm;
4109 }
4110 else
4111 {
4112 BioImage.filter8.InRed = MapIntRangeToByteRange(r);
4113 BioImage.filter8.InGreen = MapIntRangeToByteRange(g);
4114 BioImage.filter8.InBlue = MapIntRangeToByteRange(b);
4115 Bitmap bm = BioImage.filter8.Apply(Buffers[ind].GetImageRGBA(false));
4116 return bm;
4117 }
4118 }
4119 else
4120 if (Buffers[ind].BitsPerPixel > 8)
4121 {
4122 BioImage.filter16.InRed = r;
4123 BioImage.filter16.InGreen = g;
4124 BioImage.filter16.InBlue = b;
4125 Bitmap bm = BioImage.filter16.Apply(Buffers[ind]);
4126 return bm;
4127 }
4128 else
4129 {
4130 // set ranges
4131 BioImage.filter8.InRed = r;
4132 BioImage.filter8.InGreen = g;
4133 BioImage.filter8.InBlue = b;
4134 return BioImage.filter8.Apply(Buffers[ind]);
4135 }
4136 }

◆ GetFiltered() [2/2]

Bitmap BioLib.BioImage.GetFiltered ( ZCT coord,
IntRange r,
IntRange g,
IntRange b )

‍Get the image at the specified ZCT coordinate, and return a filtered version of it

Parameters
ZCTa 3-tuple of integers (z, c, t)
IntRange
IntRange
IntRange
Returns
An UnmanagedImage object.
4077 {
4078 int index = GetFrameIndex(coord.Z, coord.C, coord.T);
4079 return GetFiltered(index, r, g, b);
4080 }

◆ GetFrameIndex()

int BioLib.BioImage.GetFrameIndex ( int z,
int c,
int t )
7154 {
7155 try
7156 {
7157 if (StackOrder == Order.ZCT)
7158 {
7159 return Coords[z, c, t];
7160 }
7161 else if (StackOrder == Order.CZT)
7162 {
7163 return Coords[c, z, t];
7164 }
7165 else
7166 return Coords[t, c, z];
7167 }
7168 catch (Exception e)
7169 {
7170 return 0;
7171 }
7172
7173 }

◆ GetImageByCoord()

Bitmap BioLib.BioImage.GetImageByCoord ( int z,
int c,
int t )

‍Get the image at the specified coordinates

Parameters
zthe z-stack index
cchannel
ttime
Returns
A Bitmap object.
3877 {
3878 return Buffers[GetFrameIndex(z, c, t)];
3879 }

◆ GetIndex()

int BioLib.BioImage.GetIndex ( int ix,
int iy )

‍GetIndex(x,y) = (y * stridex + x) * 2

The stridex is the width of the image in bytes.

The stridey is the height of the image in bytes.

Parameters
ixx coordinate of the pixel
iyThe y coordinate of the pixel
Returns
The index of the pixel in the array.
3904 {
3905 if (ix > SizeX || iy > SizeY || ix < 0 || iy < 0)
3906 return 0;
3907 int stridex = SizeX;
3908 int x = ix;
3909 int y = iy;
3910 if (bitsPerPixel > 8)
3911 {
3912 return (y * stridex + x) * 2;
3913 }
3914 else
3915 {
3916 return (y * stridex + x);
3917 }
3918 }

◆ GetIndexRGB()

int BioLib.BioImage.GetIndexRGB ( int ix,
int iy,
int index )

‍The function returns the index of the pixel in the buffer

Parameters
ixx coordinate of the pixel
iyThe y coordinate of the pixel
index0 = Red, 1 = Green, 2 = Blue
Returns
The index of the pixel in the buffer.
3927 {
3928 int stridex = SizeX;
3929 //For 16bit (2*8bit) images we multiply buffer index by 2
3930 int x = ix;
3931 int y = iy;
3932 if (bitsPerPixel > 8)
3933 {
3934 return (y * stridex + x) * 2 * index;
3935 }
3936 else
3937 {
3938 return (y * stridex + x) * index;
3939 }
3940 }

◆ GetLevelDownsample()

double BioLib.BioImage.GetLevelDownsample ( int level)

Get the downsampling factor of a given level.

Parameters
levelThe desired level.

<return> The downsampling factor for this level. </return>

Exceptions
OpenSlideException
2186 {
2187 int originalWidth = Resolutions[0].SizeX; // Width of the original level
2188 int nextLevelWidth = Resolutions[level].SizeX; // Width of the next level (downsampled)
2189 return (double)originalWidth / (double)nextLevelWidth;
2190 }

◆ GetLevelDownsamples()

double[] BioLib.BioImage.GetLevelDownsamples ( )
2192 {
2193 double[] ds = new double[Resolutions.Count];
2194 for (int i = 0; i < Resolutions.Count; i++)
2195 {
2196 ds[i] = Resolutions[0].PhysicalSizeX * GetLevelDownsample(i);
2197 }
2198 return ds;
2199 }
double GetLevelDownsample(int level)
Get the downsampling factor of a given level.
Definition Bio.cs:2185

◆ GetPixelFormat() [1/2]

static PixelFormat BioLib.BioImage.GetPixelFormat ( int rgbChannelCount,
int bitsPerPixel )
static

If the bits per pixel is 8, then the pixel format is either 8bppIndexed, 24bppRgb, or 32bppArgb. If the bits per pixel is 16, then the pixel format is either 16bppGrayScale or 48bppRgb.

Parameters
rgbChannelCountThe number of channels in the image. For example, a grayscale image has 1 channel, a color image has 3 channels (red, green, blue).
bitsPerPixel8 or 16
Returns
The PixelFormat of the image.
7440 {
7441 if (bitsPerPixel == 8)
7442 {
7443 if (rgbChannelCount == 1)
7444 return PixelFormat.Format8bppIndexed;
7445 else if (rgbChannelCount == 3)
7446 return PixelFormat.Format24bppRgb;
7447 else if (rgbChannelCount == 4)
7448 return PixelFormat.Format32bppArgb;
7449 }
7450 else
7451 {
7452 if (rgbChannelCount == 1)
7453 return PixelFormat.Format16bppGrayScale;
7454 if (rgbChannelCount == 3)
7455 return PixelFormat.Format48bppRgb;
7456 }
7457 throw new NotSupportedException("Not supported pixel format.");
7458 }

◆ GetPixelFormat() [2/2]

static PixelFormat BioLib.BioImage.GetPixelFormat ( int rgbChannelCount,
ome.xml.model.enums.PixelType px )
static

The function returns the appropriate PixelFormat based on the number of RGB channels and the pixel type.

Parameters
rgbChannelCountThe rgbChannelCount parameter represents the number of channels in the RGB color model. It can have a value of either 1 (for grayscale images) or 3 (for RGB color images).
pxThe parameter "px" is of type ome.xml.model.enums.PixelType. It represents the pixel type of the image, such as INT8, UINT8, INT16, or UINT16.
Returns
The method returns a PixelFormat value based on the input parameters.
7470 {
7471 if (rgbChannelCount == 1)
7472 {
7473 if (px == ome.xml.model.enums.PixelType.INT8 || px == ome.xml.model.enums.PixelType.UINT8)
7474 return PixelFormat.Format8bppIndexed;
7475 else if (px == ome.xml.model.enums.PixelType.INT16 || px == ome.xml.model.enums.PixelType.UINT16)
7476 return PixelFormat.Format16bppGrayScale;
7477 }
7478 else if (rgbChannelCount == 3)
7479 {
7480 if (px == ome.xml.model.enums.PixelType.INT8 || px == ome.xml.model.enums.PixelType.UINT8)
7481 return PixelFormat.Format24bppRgb;
7482 else if (px == ome.xml.model.enums.PixelType.INT16 || px == ome.xml.model.enums.PixelType.UINT16)
7483 return PixelFormat.Format48bppRgb;
7484 }
7485 else
7486 return PixelFormat.Format32bppArgb;
7487 throw new InvalidDataException("RGBChannels Count of " + rgbChannelCount + " not supported.");
7488 }

◆ GetRegion()

BioImage BioLib.BioImage.GetRegion ( int x,
int y,
int w,
int h )
7299 {
7300 string id = System.IO.Path.GetFileNameWithoutExtension(Filename);
7301 id.Replace(".ome", "");
7302 BioImage bm = Copy();
7303 bm.ID = id + ".ome.tif";
7304 bm.Filename = id + ".ome.tif";
7305 bm.Volume = new VolumeD(new Point3D(StageSizeX + (PhysicalSizeX * PyramidalOrigin.X), StageSizeY + (PhysicalSizeY * PyramidalOrigin.Y), StageSizeZ),
7306 new Point3D(w * PhysicalSizeX, h * PhysicalSizeY, SizeZ * PhysicalSizeZ));
7307 bm.Resolutions.Add(new Resolution(w, h, bm.Buffers[0].PixelFormat, PhysicalSizeX, PhysicalSizeY, PhysicalSizeZ, StageSizeX, StageSizeY, StageSizeZ));
7308 bm.Resolutions.RemoveAt(0);
7309 Recorder.AddLine("BioLib.Images.GetImage(\"" + bm.ID + "\").GetRegion(" + x + "," + y + "," + w + "," + h + ");", false);
7310 return bm;
7311 }

◆ GetRGBBitmap()

Bitmap BioLib.BioImage.GetRGBBitmap ( ZCT coord,
IntRange rf,
IntRange gf,
IntRange bf )

‍Get the RGB bitmap for the specified ZCT coordinate

Parameters
ZCTZ, C, T coordinates
IntRange
IntRange
IntRange
Returns
A Bitmap object.
4196 {
4197 int index = GetFrameIndex(coord.Z, 0, coord.T);
4198 if (Buffers[0].RGBChannelsCount == 1)
4199 {
4200 if (Channels.Count >= 3)
4201 {
4202 Bitmap[] bs = new Bitmap[3];
4203 bs[2] = Buffers[index + RChannel.Index];
4204 bs[1] = Buffers[index + GChannel.Index];
4205 bs[0] = Buffers[index + BChannel.Index];
4206 return Bitmap.GetRGBBitmap(bs, rf, gf, bf);
4207 }
4208 else
4209 {
4210 Bitmap[] bs = new Bitmap[3];
4211 bs[2] = Buffers[index + RChannel.Index];
4212 bs[1] = Buffers[index + RChannel.Index + 1];
4213 bs[0] = Buffers[index + RChannel.Index + 2];
4214 return Bitmap.GetRGBBitmap(bs, rf, gf, bf);
4215 }
4216 }
4217 else
4218 {
4219 if (Buffers[0].PixelFormat == PixelFormat.Float || Buffers[0].PixelFormat == PixelFormat.Short)
4220 {
4221 return Buffers[index].GetImageRGBA();
4222 }
4223 else
4224 return Buffers[index];
4225 }
4226 }

◆ GetSeriesCount()

static int BioLib.BioImage.GetSeriesCount ( string file)
static
8780 {
8781 ImageReader r = new ImageReader();
8782 r.setId(file);
8783 return r.getSeriesCount();
8784 }

◆ GetSlice()

async Task< Bitmap[]> BioLib.BioImage.GetSlice ( int x,
int y,
int w,
int h,
double resolution )
7723 {
7724 List<Bitmap> Buffers = new List<Bitmap>();
7725 for (int i = 0; i < imagesPerSeries; i++)
7726 {
7727 if (openSlideImage != null)
7728 {
7730 openslideBase.SetSliceInfo(lev, Resolutions[lev].PixelFormat, Coordinate);
7731 byte[] bts = openslideBase.GetSlice(new OpenSlideGTK.SliceInfo(x, y, w, h, resolution));
7732 Buffers.Add(new Bitmap((int)Math.Round(OpenSlideBase.destExtent.Width), (int)Math.Round(OpenSlideBase.destExtent.Height), PixelFormat.Format24bppRgb, bts, new ZCT(), ""));
7733 }
7734 else
7735 {
7736 start:
7737 byte[] bts = await slideBase.GetSlice(new SliceInfo(x, y, w, h, resolution, Coordinate));
7738 if (bts == null)
7739 {
7740 if (x == 0 && y == 0)
7741 {
7743 }
7744 pyramidalOrigin = new PointD(0, 0);
7745 goto start;
7746 }
7747 Buffers.Add(new Bitmap((int)Math.Round(SlideBase.destExtent.Width), (int)Math.Round(SlideBase.destExtent.Height), Resolutions[Level].PixelFormat, bts, new ZCT(), ""));
7748 }
7749 }
7750 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), true, x, y, w, h, resolution);
7751 return Buffers.ToArray();
7752 }
int LevelFromResolution(double Resolution)
Returns the level of a given resolution.
Definition Bio.cs:2205
double GetUnitPerPixel(int level)
Get Unit Per Pixel for pyramidal images.
Definition Bio.cs:2232
Slice info.
Definition ISlideSource.cs:452
Definition SlideBase.cs:15
async Task< byte[]> GetSlice(SliceInfo sliceInfo)
Get slice.
Definition ISlideSource.cs:181

◆ GetTile()

static Bitmap BioLib.BioImage.GetTile ( BioImage b,
int index,
int level,
int tilex,
int tiley,
int tileSizeX,
int tileSizeY )
static

It reads a tile from a file, and returns a bitmap.

Parameters
BioImageThis is a class that contains the image file name, the image reader, and the coordinates of the image.
ZCTZ, C, T
seriethe series number (0-based)
tilexthe x coordinate of the tile
tileythe y coordinate of the tile
tileSizeXthe width of the tile
tileSizeYthe height of the tile
Returns
A Bitmap object.
7203 {
7204 if (b.Tag != null)
7205 {
7206 if (b.Tag.ToString() != "OMERO")
7207 return null;
7208 //This is a OMERO file we need to update it.
7209 int i = 0;
7210 for (int z = 0; z < b.SizeZ; z++)
7211 {
7212 for (int c = 0; c < b.SizeC; c++)
7213 {
7214 for (int t = 0; t < b.SizeT; t++)
7215 {
7216 if(i == index)
7217 return OMERO.GetTile(b, new ZCT(z,c,t), tilex, tiley, tileSizeX, tileSizeY, level);
7218 i++;
7219 }
7220 }
7221 }
7222 }
7223 if (vips && b.vipPages.Count > 0)
7224 {
7225 //We can get a tile faster with libvips rather than bioformats.
7226 Bitmap bmp = ExtractRegionFromTiledTiff(b, tilex, tiley, tileSizeX, tileSizeY, level);
7227 if (bmp != null)
7228 {
7229 return bmp;
7230 }
7231 }
7232 //We check if we can open this with OpenSlide as this is faster than Bioformats with IKVM.
7233 if (b.openSlideImage != null)
7234 {
7235 byte[] bts = b.openSlideImage.ReadRegion(level, tilex, tiley, tileSizeX, tileSizeY);
7236 Bitmap bm = new Bitmap("", tileSizeX, tileSizeY, AForge.PixelFormat.Format32bppArgb, bts, new ZCT(), 0, null, true, true);
7237 return bm;
7238 }
7239
7240 string curfile = b.imRead.getCurrentFile();
7241 if (curfile == null)
7242 {
7243 b.meta = (IMetadata)((OMEXMLService)factory.getInstance(typeof(OMEXMLService))).createOMEXMLMetadata();
7244 b.imRead.close();
7245 b.imRead.setMetadataStore(b.meta);
7246 b.imRead.setId(b.file);
7247 }
7248 else
7249 {
7250 string fi = b.file.Replace("\\", "/");
7251 string cf = curfile.Replace("\\", "/");
7252 if (cf != fi)
7253 {
7254 b.imRead.close();
7255 b.meta = (IMetadata)((OMEXMLService)factory.getInstance(typeof(OMEXMLService))).createOMEXMLMetadata();
7256 b.imRead.setMetadataStore(b.meta);
7257 b.imRead.setId(b.file);
7258 }
7259 }
7260 if (b.imRead.getSeries() != level)
7261 b.imRead.setSeries(level);
7262 int SizeX = b.imRead.getSizeX();
7263 int SizeY = b.imRead.getSizeY();
7264 bool flat = b.imRead.hasFlattenedResolutions();
7265 bool littleEndian = b.imRead.isLittleEndian();
7266 bool interleaved = b.imRead.isInterleaved();
7267 PixelFormat PixelFormat = b.Resolutions[level].PixelFormat;
7268 if (tilex < 0)
7269 tilex = 0;
7270 if (tiley < 0)
7271 tiley = 0;
7272 if (tilex >= SizeX)
7273 tilex = SizeX;
7274 if (tiley >= SizeY)
7275 tiley = SizeY;
7276 int sx = tileSizeX;
7277 if (tilex + tileSizeX > SizeX)
7278 sx -= (tilex + tileSizeX) - (SizeX);
7279 int sy = tileSizeY;
7280 if (tiley + tileSizeY > SizeY)
7281 sy -= (tiley + tileSizeY) - (SizeY);
7282 //For some reason calling openBytes with 1x1px area causes an exception.
7283 if (sx <= 1)
7284 return null;
7285 if (sy <= 1)
7286 return null;
7287 try
7288 {
7289 byte[] bytesr = b.imRead.openBytes(index, tilex, tiley, sx, sy);
7290 return new Bitmap(b.file, sx, sy, PixelFormat, bytesr, new ZCT(), index, null, littleEndian, interleaved);
7291 }
7292 catch (Exception e)
7293 {
7294 Console.WriteLine(e.Message);
7295 return null;
7296 }
7297 }
static Bitmap ExtractRegionFromTiledTiff(BioImage b, int x, int y, int width, int height, int level)
The function ExtractRegionFromTiledTiff takes a BioImage object, coordinates, width,...
Definition Bio.cs:6302
Definition OMERO.cs:32

◆ GetUnitPerPixel()

double BioLib.BioImage.GetUnitPerPixel ( int level)

Get Unit Per Pixel for pyramidal images.

Parameters
level
Returns
2233 {
2234 return Resolutions[0].PhysicalSizeX * GetLevelDownsample(level);
2235 }

◆ GetValue() [1/3]

ushort BioLib.BioImage.GetValue ( int z,
int c,
int t,
int x,
int y )

‍This function returns the value of the pixel at the specified ZCTXY coordinates

Parameters
zThe Z-plane of the image.
cchannel
ttime
xx coordinate of the pixel
ythe y coordinate of the pixel
Returns
The value of the pixel at the given coordinates.
3988 {
3989 return GetValueRGB(new ZCTXY(z, c, t, x, y), 0);
3990 }
ushort GetValueRGB(ZCTXY coord, int index)
It takes a coordinate and an index and returns the value of the pixel at that coordinate.
Definition Bio.cs:3957

◆ GetValue() [2/3]

ushort BioLib.BioImage.GetValue ( ZCT coord,
int x,
int y )

‍Get the value of the pixel at the given coordinates

Parameters
ZCTZ is the Z-plane, C is the channel, T is the timepoint
xx coordinate of the pixel
yThe y coordinate of the pixel
Returns
The value of the pixel at the given coordinates.
3975 {
3976 return GetValueRGB(new ZCTXY(coord.Z, coord.C, coord.T, x, y), 0);
3977 }

◆ GetValue() [3/3]

ushort BioLib.BioImage.GetValue ( ZCTXY coord)

If the coordinate is within the bounds of the image, then return the value of the pixel at that coordinate.

Parameters
ZCTXYa struct that contains the X, Y, Z, C, and T coordinates of the pixel.
Returns
The value of the pixel at the given coordinate.
3948 {
3949 return GetValueRGB(coord, 0);
3950 }

◆ GetValueRGB() [1/3]

float BioLib.BioImage.GetValueRGB ( int z,
int c,
int t,
int x,
int y,
int RGBindex )

This function returns the value of the pixel at the specified coordinates in the specified channel, frame, and RGB index.

Parameters
zThe Z-plane index
cchannel
ttime index
xx coordinate of the pixel
yThe y coordinate of the pixel
RGBindex0 = Red, 1 = Green, 2 = Blue
Returns
The value of the pixel at the given coordinates.
4016 {
4017 return GetValueRGB(new ZCT(z, c, t), x, y, RGBindex);
4018 }

◆ GetValueRGB() [2/3]

float BioLib.BioImage.GetValueRGB ( ZCT coord,
int x,
int y,
int RGBindex )

‍Get the value of a pixel at a given coordinate, x, y, and RGB index

Parameters
ZCTThe ZCT coordinate of the image.
xx coordinate of the pixel
ythe y coordinate of the pixel
RGBindex0 = Red, 1 = Green, 2 = Blue
Returns
The value of the pixel at the given coordinates.
4000 {
4001 int i = GetFrameIndex(coord.Z, coord.C, coord.T);
4002 return Buffers[i].GetValue(x, y, RGBindex);
4003 }

◆ GetValueRGB() [3/3]

ushort BioLib.BioImage.GetValueRGB ( ZCTXY coord,
int index )

It takes a coordinate and an index and returns the value of the pixel at that coordinate.

Parameters
ZCTXYa struct that contains the Z, C, T, X, and Y coordinates of the pixel.
index0, 1, 2
Returns
A ushort value.
3958 {
3959 int ind = 0;
3960 if (coord.C >= SizeC)
3961 {
3962 coord.C = 0;
3963 }
3964 ind = GetFrameIndex(coord.Z, coord.C, coord.T);
3965 return (ushort)Buffers[ind].GetValue(coord.X, coord.Y, index);
3966 }

◆ ImagesToStack()

static BioImage BioLib.BioImage.ImagesToStack ( string[] files,
bool tab )
static

It takes a list of files, opens them, and then combines them into a single BioImage object.

Parameters
filesan array of file paths
Returns
A BioImage object.
7576 {
7577 BioImage[] bs = new BioImage[files.Length];
7578 int z = 0;
7579 int c = 0;
7580 int t = 0;
7581 for (int i = 0; i < files.Length; i++)
7582 {
7583 string str = Path.GetFileNameWithoutExtension(files[i]);
7584 str = str.Replace(".ome", "");
7585 string[] st = str.Split('_');
7586 if (st.Length > 3)
7587 {
7588 z = int.Parse(st[1].Replace("Z", ""));
7589 c = int.Parse(st[2].Replace("C", ""));
7590 t = int.Parse(st[3].Replace("T", ""));
7591 }
7592 if (i == 0)
7593 bs[0] = OpenOME(files[i], tab);
7594 else
7595 {
7596 bs[i] = OpenFile(files[i], 0, tab, false);
7597 }
7598 }
7599 BioImage b = BioImage.CopyInfo(bs[0], true, true);
7600 for (int i = 0; i < files.Length; i++)
7601 {
7602 for (int bc = 0; bc < bs[i].Buffers.Count; bc++)
7603 {
7604 b.Buffers.Add(bs[i].Buffers[bc]);
7605 }
7606 }
7607 b.UpdateCoords(z + 1, c + 1, t + 1);
7608 b.Volume = new VolumeD(bs[0].Volume.Location, new Point3D(bs[0].SizeX * bs[0].PhysicalSizeX, bs[0].SizeY * bs[0].PhysicalSizeY, (z + 1) * bs[0].PhysicalSizeZ));
7609 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, files, tab);
7610 return b;
7611 }
static BioImage OpenOME(string file, bool tab)
The function "OpenOME" opens a bioimage file in the OME format and returns the first image in the ser...
Definition Bio.cs:5949

◆ ImportROIsCSV()

static List< ROI > BioLib.BioImage.ImportROIsCSV ( string filename)
static

It reads the CSV file and converts each line into a ROI object.

Parameters
filenameThe path to the CSV file.
Returns
A list of ROI objects.
8537 {
8538 List<ROI> list = new List<ROI>();
8539 if (!File.Exists(filename))
8540 return list;
8541 string[] sts = File.ReadAllLines(filename);
8542 //We start reading from line 1.
8543 for (int i = 1; i < sts.Length; i++)
8544 {
8545 list.Add(StringToROI(sts[i]));
8546 }
8547 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, filename);
8548 return list;
8549 }
static ROI StringToROI(string sts)
It takes a string and returns an ROI object.
Definition Bio.cs:8365

◆ Initialize() [1/2]

static void BioLib.BioImage.Initialize ( )
static
4451 {
4452 //We initialize OME on a seperate thread so the user doesn't have to wait for initialization to
4453 //view images.
4454 InitFactory();
4455 InitReader();
4456 InitWriter();
4457 }

◆ Initialize() [2/2]

static void BioLib.BioImage.Initialize ( string imageJPath)
static

Initializes ImageJ/Fiji with the given path.

Parameters
imageJPath
4437 {
4438 //We initialize OME on a seperate thread so the user doesn't have to wait for initialization to
4439 //view images.
4440 InitFactory();
4441 InitReader();
4442 InitWriter();
4443 if (imageJPath.Contains("Fiji"))
4444 {
4445 Fiji.Initialize(imageJPath);
4446 }
4447 else
4448 ImageJ.Initialize(imageJPath);
4449 }

◆ isOME()

static bool BioLib.BioImage.isOME ( string file)
static

If the file is a TIFF, check the ImageDescription tag for the string "OME-XML". If it's there, return true. If it's not a TIFF, return true. If it's a PNG, JPG, JPEG, or BMP, return false.

Parameters
filethe path to the image file
Returns
A boolean value.
5281 {
5282 if (file.EndsWith("ome.tif") || file.EndsWith("ome.tiff"))
5283 {
5284 return true;
5285 }
5286 if (file.EndsWith(".tif") || file.EndsWith(".TIF") || file.EndsWith("tiff") || file.EndsWith("TIFF"))
5287 {
5288 Tiff image = Tiff.Open(file, "r");
5289 string desc = "";
5290 FieldValue[] f = image.GetField(TiffTag.IMAGEDESCRIPTION);
5291 desc = f[0].ToString();
5292 image.Close();
5293 if (desc.Contains("OME-XML"))
5294 return true;
5295 else
5296 return false;
5297 }
5298 if ((file.EndsWith("png") || file.EndsWith("PNG") || file.EndsWith("jpg") || file.EndsWith("JPG") ||
5299 file.EndsWith("jpeg") || file.EndsWith("JPEG") || file.EndsWith("bmp") || file.EndsWith("BMP")))
5300 {
5301 return false;
5302 }
5303 else return true;
5304 }

◆ isOMESeries()

static bool BioLib.BioImage.isOMESeries ( string file)
static

‍If the file is an OME file and has more than one series, return true

Parameters
filethe file to be checked
Returns
A boolean value.
5311 {
5312 if (!isOME(file))
5313 return false;
5314 ImageReader reader = new ImageReader();
5315 var meta = (IMetadata)((OMEXMLService)new ServiceFactory().getInstance(typeof(OMEXMLService))).createOMEXMLMetadata();
5316 reader.setMetadataStore((MetadataStore)meta);
5317 file = file.Replace("\\", "/");
5318 reader.setId(file);
5319 bool ser = false;
5320 if (reader.getSeriesCount() > 1)
5321 ser = true;
5322 reader.close();
5323 reader = null;
5324 return ser;
5325 }
static bool isOME(string file)
If the file is a TIFF, check the ImageDescription tag for the string "OME-XML". If it's there,...
Definition Bio.cs:5280

◆ isTiffSeries()

static bool BioLib.BioImage.isTiffSeries ( string file)
static

‍The function checks if the image is a Tiff image and if it is, it checks if the image is a series of images

Parameters
filethe path to the file
Returns
a boolean value.
5246 {
5247 Tiff image = Tiff.Open(file, "r");
5248 string desc = "";
5249 FieldValue[] f = image.GetField(TiffTag.IMAGEDESCRIPTION);
5250 image.Close();
5251 string[] sts = desc.Split('\n');
5252 int index = 0;
5253 for (int i = 0; i < sts.Length; i++)
5254 {
5255 if (sts[i].StartsWith("-ImageInfo"))
5256 {
5257 string val = sts[i].Substring(11);
5258 val = val.Substring(0, val.IndexOf(':'));
5259 int serie = int.Parse(val);
5260 if (sts[i].Length > 10)
5261 {
5262 string cht = sts[i].Substring(sts[i].IndexOf('{'), sts[i].Length - sts[i].IndexOf('{'));
5263 ImageInfo info = JsonConvert.DeserializeObject<ImageInfo>(cht);
5264 if (info.Series > 1)
5265 return true;
5266 else
5267 return false;
5268 }
5269 }
5270 }
5271 return false;
5272 }
Definition Bio.cs:1043

◆ LevelFromResolution()

int BioLib.BioImage.LevelFromResolution ( double Resolution)

Returns the level of a given resolution.

Parameters
Resolution
Returns
2206 {
2207 int l = 0;
2208 double[] ds = GetLevelDownsamples();
2209 if (MacroResolution.HasValue)
2210 {
2211 for (int i = 0; i < MacroResolution.Value; i++)
2212 {
2213 if (ds[i] < Resolution)
2214 l = i;
2215 }
2216 }
2217 else
2218 {
2219 for (int i = 0; i < Resolutions.Count; i++)
2220 {
2221 if (ds[i] < Resolution)
2222 l = i;
2223 }
2224 }
2225 return l;
2226 }

◆ MapIntRangeToByteRange()

static IntRange BioLib.BioImage.MapIntRangeToByteRange ( IntRange ushortRange)
static
4082 {
4083 // Ensure the range is valid
4084 if (ushortRange.Min < 0 || ushortRange.Max > ushort.MaxValue)
4085 throw new ArgumentOutOfRangeException(nameof(ushortRange), "Range must be within 0 to ushort.MaxValue.");
4086
4087 // Map each value in the range
4088 int mappedMin = (int)((ushortRange.Min / (float)ushort.MaxValue) * byte.MaxValue);
4089 int mappedMax = (int)((ushortRange.Max / (float)ushort.MaxValue) * byte.MaxValue);
4090
4091 return new IntRange(mappedMin, mappedMax);
4092 }

◆ MergeChannels() [1/2]

static BioImage BioLib.BioImage.MergeChannels ( BioImage b2,
BioImage b )
static

This function takes two images and merges them together.

Parameters
BioImageThe image to be merged
BioImageThe image to be merged
Returns
A new BioImage object.
3577 {
3578 BioImage res = new BioImage(b2.ID);
3579 res.ID = Images.GetImageName(b2.ID);
3580 res.series = b2.series;
3581 res.sizeZ = b2.SizeZ;
3582 int cOrig = b2.SizeC;
3583 res.sizeC = b2.SizeC + b.SizeC;
3584 res.sizeT = b2.SizeT;
3585 res.bitsPerPixel = b2.bitsPerPixel;
3586 res.imageInfo = b2.imageInfo;
3587 res.littleEndian = b2.littleEndian;
3588 res.seriesCount = b2.seriesCount;
3589 res.imagesPerSeries = res.ImageCount / res.seriesCount;
3590 res.Coords = new int[res.SizeZ, res.SizeC, res.SizeT];
3591 res.Resolutions.Add(b2.Resolutions[0]);
3592 res.Volume = new VolumeD(new Point3D(res.StageSizeX, res.StageSizeY, res.StageSizeZ), new Point3D(b2.SizeX, b2.SizeY, b2.SizeZ));
3593 int i = 0;
3594 for (int ci = 0; ci < res.SizeC; ci++)
3595 {
3596 for (int ti = 0; ti < res.SizeT; ti++)
3597 {
3598 for (int zi = 0; zi < res.SizeZ; zi++)
3599 {
3600 if (i < b.ImageCount)
3601 {
3602 ZCT co = new ZCT(zi, ci, ti);
3603 int ind = b.GetFrameIndex(zi, 0, ti);
3604 //This plane is not part of b1 so we add the planes from b2 channels.
3605 Bitmap copy = new Bitmap(b.id, b.SizeX, b.SizeY, b.Buffers[0].PixelFormat, b.Buffers[ind].Bytes, co, ind);
3606 res.SetFrameIndex(zi, ci, ti, ind);
3607 res.Buffers.Add(copy);
3608 //Lets copy the ROI's from the original image.
3609 List<ROI> anns = b.GetAnnotations(zi, ci, ti);
3610 if (anns.Count > 0)
3611 res.Annotations.AddRange(anns);
3612 }
3613 else
3614 {
3615 ZCT co = new ZCT(zi, ci, ti);
3616 int ind = b2.GetFrameIndex(zi, 0, ti);
3617 //This plane is not part of b1 so we add the planes from b2 channels.
3618 Bitmap copy = new Bitmap(b2.id, b2.SizeX, b2.SizeY, b2.Buffers[0].PixelFormat, b2.Buffers[ind].Bytes, co, ind);
3619 res.SetFrameIndex(zi, ci, ti, b.ImageCount + ind);
3620 res.Buffers.Add(copy);
3621 //Lets copy the ROI's from the original image.
3622 List<ROI> anns = b2.GetAnnotations(zi, ci, ti);
3623 if (anns.Count > 0)
3624 res.Annotations.AddRange(anns);
3625 }
3626 i++;
3627 }
3628 }
3629 }
3630 for (int ci = 0; ci < b.SizeC; ci++)
3631 {
3632 res.Channels.Add(b.Channels[ci].Copy());
3633 }
3634 for (int ci = 0; ci < b2.SizeC; ci++)
3635 {
3636 res.Channels.Add(b2.Channels[ci].Copy());
3637 }
3638 res.rgbChannels[0] = 0;
3639 if (res.Channels.Count > 1)
3640 res.rgbChannels[1] = 1;
3641 if (res.Channels.Count > 2)
3642 res.rgbChannels[2] = 2;
3643 Images.AddImage(res);
3644 res.imagesPerSeries = res.Buffers.Count;
3645 //We wait for threshold image statistics calculation
3646 do
3647 {
3648 Thread.Sleep(100);
3649 } while (res.Buffers[res.Buffers.Count - 1].Stats == null);
3650 AutoThreshold(res, false);
3651 if (res.bitsPerPixel > 8)
3652 res.StackThreshold(true);
3653 else
3654 res.StackThreshold(false);
3655 return res;
3656 }
List< ROI > GetAnnotations(ZCT coord)
Definition Bio.cs:4401

◆ MergeChannels() [2/2]

static BioImage BioLib.BioImage.MergeChannels ( string bname,
string b2name )
static

MergeChannels(b, b2) takes two images, b and b2, and merges the channels of b2 into b.

Parameters
bnameThe name of the first image
b2nameThe name of the image to merge with the first image.
Returns
A BioImage object.
3664 {
3665 BioImage b = Images.GetImage(bname);
3666 BioImage b2 = Images.GetImage(b2name);
3667 return MergeChannels(b, b2);
3668 }
static BioImage MergeChannels(BioImage b2, BioImage b)
This function takes two images and merges them together.
Definition Bio.cs:3576

◆ MergeT()

static BioImage BioLib.BioImage.MergeT ( BioImage b)
static

It takes a 3D image and merges the time dimension into a single image.

Parameters
BioImageThe image to be processed
Returns
A new BioImage object.
3713 {
3714 BioImage bi = BioImage.CopyInfo(b, true, true);
3715 int ind = 0;
3716 for (int c = 0; c < b.SizeC; c++)
3717 {
3718 for (int z = 0; z < b.sizeZ; z++)
3719 {
3720 Merge m = new Merge(b.Buffers[b.GetFrameIndex(z, c, 0)]);
3721 Bitmap bm = new Bitmap(b.SizeX, b.SizeY, b.Buffers[0].PixelFormat);
3722 for (int i = 1; i < b.sizeT; i++)
3723 {
3724 m.OverlayImage = bm;
3725 bm = m.Apply(b.Buffers[b.GetFrameIndex(z, c, i)]);
3726 }
3727 Bitmap bf = new Bitmap(b.file, bm, new ZCT(z, c, 0), ind);
3728 bi.Buffers.Add(bf);
3729 bf.Stats = Statistics.FromBytes(bf);
3730 ind++;
3731 }
3732 }
3733 Images.AddImage(bi);
3734 bi.UpdateCoords(1, b.SizeC, b.SizeT);
3735 bi.Coordinate = new ZCT(0, 0, 0);
3736 bi.Resolutions.Add(new Resolution(b.Buffers[0].SizeX, b.Buffers[0].SizeY, b.Buffers[0].PixelFormat, b.PhysicalSizeX, b.PhysicalSizeY, b.PhysicalSizeZ, b.StageSizeX, b.StageSizeY, b.StageSizeZ));
3737 AutoThreshold(bi, false);
3738 if (bi.bitsPerPixel > 8)
3739 bi.StackThreshold(true);
3740 else
3741 bi.StackThreshold(false);
3742 return bi;
3743 }

◆ MergeZ()

static BioImage BioLib.BioImage.MergeZ ( BioImage b)
static

It takes a 3D image and merges the Z-stack into a single 2D image.

Parameters
BioImageThe image to be merged
Returns
A new BioImage object.
3675 {
3676 BioImage bi = BioImage.CopyInfo(b, true, true);
3677 int ind = 0;
3678 for (int c = 0; c < b.SizeC; c++)
3679 {
3680 for (int t = 0; t < b.sizeT; t++)
3681 {
3682 Merge m = new Merge(b.Buffers[b.GetFrameIndex(0, c, t)]);
3683 Bitmap bm = new Bitmap(b.SizeX, b.SizeY, b.Buffers[0].PixelFormat);
3684 for (int i = 1; i < b.sizeZ; i++)
3685 {
3686 m.OverlayImage = bm;
3687 bm = m.Apply(b.Buffers[b.GetFrameIndex(i, c, t)]);
3688 }
3689 Bitmap bf = new Bitmap(b.file, bm, new ZCT(0, c, t), ind);
3690 bi.Buffers.Add(bf);
3691 bf.Stats = Statistics.FromBytes(bf);
3692 ind++;
3693 }
3694 }
3695 Images.AddImage(bi);
3696 bi.UpdateCoords(1, b.SizeC, b.SizeT);
3697 bi.Coordinate = new ZCT(0, 0, 0);
3698 bi.Resolutions.Add(new Resolution(b.Buffers[0].SizeX, b.Buffers[0].SizeY, b.Buffers[0].PixelFormat, b.PhysicalSizeX, b.PhysicalSizeY, b.PhysicalSizeZ, b.StageSizeX, b.StageSizeY, b.StageSizeZ));
3699
3700 AutoThreshold(bi, false);
3701 if (bi.bitsPerPixel > 8)
3702 bi.StackThreshold(true);
3703 else
3704 bi.StackThreshold(false);
3705 return bi;
3706 }

◆ Open() [1/2]

static void BioLib.BioImage.Open ( string file)
static

It opens a file.

Parameters
fileThe file to open.
7557 {
7558 OpenFile(file);
7559 }

◆ Open() [2/2]

static void BioLib.BioImage.Open ( string[] files)
static

It opens a file.

Parameters
filesThe files to open.
7564 {
7565 foreach (string file in files)
7566 {
7567 Open(file);
7568 }
7569 }
static void Open(string file)
It opens a file.
Definition Bio.cs:7556

◆ OpenAsync() [1/2]

static async Task BioLib.BioImage.OpenAsync ( string file,
bool OME,
bool newtab,
bool images,
int series )
static

It opens a file in a new thread.

Parameters
fileThe file to open
7535 {
7536 openfile = file;
7537 omes = OME;
7538 tab = newtab;
7539 add = images;
7540 serie = series;
7541 await Task.Run(OpenThread);
7542 }

◆ OpenAsync() [2/2]

static async Task BioLib.BioImage.OpenAsync ( string[] files,
bool OME,
bool tab,
bool images )
static

It opens a file asynchronously.

Parameters
filesThe file(s) to open.
7547 {
7548 foreach (string file in files)
7549 {
7550 await OpenAsync(file, OME, tab, images, 0);
7551 }
7552 }
static async Task OpenAsync(string file, bool OME, bool newtab, bool images, int series)
It opens a file in a new thread.
Definition Bio.cs:7534

◆ OpenFile() [1/4]

static BioImage BioLib.BioImage.OpenFile ( string file)
static

This function opens a file and returns a BioImage object.

Parameters
fileThe path to the file to open.
Returns
A BioImage object.
4800 {
4801 return OpenFile(file, 0, true, true);
4802 }

◆ OpenFile() [2/4]

static BioImage BioLib.BioImage.OpenFile ( string file,
bool tab )
static
4804 {
4805 return OpenFile(file, 0, tab, true);
4806 }

◆ OpenFile() [3/4]

static BioImage BioLib.BioImage.OpenFile ( string file,
int series,
bool tab,
bool addToImages )
static

It opens a TIFF file and returns a BioImage object.

Parameters
filethe file path
seriesthe series number of the image to open
Returns
A BioImage object.
4814 {
4815 return OpenFile(file, series, tab, addToImages, false, 0, 0, 0, 0);
4816 }

◆ OpenFile() [4/4]

static BioImage BioLib.BioImage.OpenFile ( string file,
int series,
bool tab,
bool addToImages,
bool tile,
int tileX,
int tileY,
int tileSizeX,
int tileSizeY )
static

The OpenFile function opens a BioImage file, reads its metadata, and loads the image data into a BioImage object.

Parameters
fileThe file path of the bioimage to be opened.
seriesThe series parameter is an integer that specifies the series number of the image to open.
tabThe "tab" parameter is a boolean value that determines whether the BioImage should be opened in a new tab or not. If set to true, the BioImage will be opened in a new tab. If set to false, the BioImage will be opened in the current tab.
addToImagesA boolean value indicating whether the BioImage should be added to the Images collection.
tileThe "tile" parameter is a boolean value that determines whether the image should be opened as a tiled image or not. If set to true, the image will be opened as a tiled image. If set to false, the image will be opened as a regular image.
tileXThe tileX parameter is an integer that represents the starting X coordinate of the tile. It is used when opening a tiled image to specify the position of the tile within the image.
tileYThe tileY parameter is used to specify the starting Y coordinate of the tile when opening a tiled image. It determines the position of the tile within the image.
tileSizeXThe tileSizeX parameter is the width of each tile in pixels. It is used when opening a tiled TIFF image to specify the size of the tiles.
tileSizeYThe tileSizeY parameter is the height of each tile in pixels when the image is tiled.
Returns
The method is returning a BioImage object.
4941 {
4942 string fs = file.Replace("\\", "/");
4943 Console.WriteLine("Opening BioImage: " + file);
4944 if (file.EndsWith(".npy"))
4945 return BioImage.FromNumpy(file);
4946 bool ome = isOME(file);
4947 if (ome) return OpenOME(file, series, tab, addToImages, tile, tileX, tileY, tileSizeX, tileSizeY);
4948 bool tiled = IsTiffTiled(file);
4949 Console.WriteLine("IsTiled=" + tiled.ToString());
4950 tile = tiled;
4951
4952 Stopwatch st = new Stopwatch();
4953 st.Start();
4954 Status = "Opening Image";
4955 progFile = file;
4956 BioImage b = new BioImage(file);
4957 if (tiled && file.EndsWith(".tif") && !file.EndsWith(".ome.tif"))
4958 {
4959 try
4960 {
4961 //To open this we need libvips
4962 vips = VipsSupport(b.file);
4963 }
4964 catch (Exception e)
4965 {
4966 Console.WriteLine(e.Message);
4967 }
4968 }
4969 b.series = series;
4970 b.file = file;
4971 if (tiled)
4972 b.Type = ImageType.pyramidal;
4973 string fn = Path.GetFileNameWithoutExtension(file);
4974 string dir = Path.GetDirectoryName(file);
4975 if (File.Exists(fn + ".csv"))
4976 {
4977 string f = dir + "//" + fn + ".csv";
4978 b.Annotations = BioImage.ImportROIsCSV(f);
4979 }
4980 if (file.EndsWith("tif") || file.EndsWith("tiff") || file.EndsWith("TIF") || file.EndsWith("TIFF"))
4981 {
4982 Tiff image = Tiff.Open(file, "r");
4983 b.tifRead = image;
4984 int SizeX = image.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
4985 int SizeY = image.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
4986 b.bitsPerPixel = image.GetField(TiffTag.BITSPERSAMPLE)[0].ToInt();
4987 b.littleEndian = !image.IsBigEndian();
4988 int RGBChannelCount = image.GetField(TiffTag.SAMPLESPERPIXEL)[0].ToInt();
4989 string desc = "";
4990
4991 FieldValue[] f = image.GetField(TiffTag.IMAGEDESCRIPTION);
4992 desc = f[0].ToString();
4993 ImageJDesc imDesc = null;
4994 b.sizeC = 1;
4995 b.sizeT = 1;
4996 b.sizeZ = 1;
4997 bool imagej = false;
4998 if (f != null && !tile)
4999 {
5000 imDesc = new ImageJDesc();
5001 desc = f[0].ToString();
5002 if (desc.StartsWith("ImageJ"))
5003 {
5004 imDesc.SetString(desc);
5005 if (imDesc.channels != 0)
5006 b.sizeC = imDesc.channels;
5007 else
5008 b.sizeC = 1;
5009 if (imDesc.slices != 0)
5010 b.sizeZ = imDesc.slices;
5011 else
5012 b.sizeZ = 1;
5013 if (imDesc.frames != 0)
5014 b.sizeT = imDesc.frames;
5015 else
5016 b.sizeT = 1;
5017 if (imDesc.finterval != 0)
5018 b.frameInterval = imDesc.finterval;
5019 else
5020 b.frameInterval = 1;
5021 if (imDesc.spacing != 0)
5022 b.imageInfo.PhysicalSizeZ = imDesc.spacing;
5023 else
5024 b.imageInfo.PhysicalSizeZ = 1;
5025 imagej = true;
5026 }
5027 }
5028 int stride = 0;
5029 PixelFormat PixelFormat;
5030 if (RGBChannelCount == 1)
5031 {
5032 if (b.bitsPerPixel > 8)
5033 {
5034 PixelFormat = PixelFormat.Format16bppGrayScale;
5035 stride = SizeX * 2;
5036 }
5037 else
5038 {
5039 PixelFormat = PixelFormat.Format8bppIndexed;
5040 stride = SizeX;
5041 }
5042 }
5043 else
5044 if (RGBChannelCount == 3)
5045 {
5046 b.sizeC = 1;
5047 if (b.bitsPerPixel > 8)
5048 {
5049 PixelFormat = PixelFormat.Format48bppRgb;
5050 stride = SizeX * 2 * 3;
5051 }
5052 else
5053 {
5054 PixelFormat = PixelFormat.Format24bppRgb;
5055 stride = SizeX * 3;
5056 }
5057 }
5058 else
5059 {
5060 PixelFormat = PixelFormat.Format32bppArgb;
5061 stride = SizeX * 4;
5062 }
5063
5064 string[] sts = desc.Split('\n');
5065 int index = 0;
5066 for (int i = 0; i < sts.Length; i++)
5067 {
5068 if (sts[i].StartsWith("-Channel"))
5069 {
5070 string val = sts[i].Substring(9);
5071 val = val.Substring(0, val.IndexOf(':'));
5072 int serie = int.Parse(val);
5073 if (serie == series && sts[i].Length > 7)
5074 {
5075 string cht = sts[i].Substring(sts[i].IndexOf('{'), sts[i].Length - sts[i].IndexOf('{'));
5076 Channel.ChannelInfo info = JsonConvert.DeserializeObject<Channel.ChannelInfo>(cht);
5077 Channel ch = new Channel(index, b.bitsPerPixel, info.SamplesPerPixel);
5078 ch.info = info;
5079 b.Channels.Add(ch);
5080 if (index == 0)
5081 {
5082 b.rgbChannels[0] = 0;
5083 }
5084 else
5085 if (index == 1)
5086 {
5087 b.rgbChannels[1] = 1;
5088 }
5089 else
5090 if (index == 2)
5091 {
5092 b.rgbChannels[2] = 2;
5093 }
5094 index++;
5095 }
5096 }
5097 else
5098 if (sts[i].StartsWith("-ROI"))
5099 {
5100 string val = sts[i].Substring(5);
5101 val = val.Substring(0, val.IndexOf(':'));
5102 int serie = int.Parse(val);
5103 if (serie == series && sts[i].Length > 7)
5104 {
5105 string s = sts[i].Substring(sts[i].IndexOf("ROI:") + 4, sts[i].Length - (sts[i].IndexOf("ROI:") + 4));
5106 string ro = s.Substring(s.IndexOf(":") + 1, s.Length - (s.IndexOf(':') + 1));
5107 ROI roi = StringToROI(ro);
5108 b.Annotations.Add(roi);
5109 }
5110 }
5111 else
5112 if (sts[i].StartsWith("-ImageInfo"))
5113 {
5114 string val = sts[i].Substring(11);
5115 val = val.Substring(0, val.IndexOf(':'));
5116 int serie = int.Parse(val);
5117 if (serie == series && sts[i].Length > 10)
5118 {
5119 string cht = sts[i].Substring(sts[i].IndexOf('{'), sts[i].Length - sts[i].IndexOf('{'));
5120 b.imageInfo = JsonConvert.DeserializeObject<ImageInfo>(cht);
5121 }
5122 }
5123 }
5124 b.Coords = new int[b.SizeZ, b.SizeC, b.SizeT];
5125 if (tiled && tileSizeX == 0 && tileSizeY == 0)
5126 {
5127 tileSizeX = 1920;
5128 tileSizeY = 1080;
5129 }
5130
5131 //If this is a tiff file not made by Bio we init channels based on RGBChannels.
5132 if (b.Channels.Count == 0)
5133 b.Channels.Add(new Channel(0, b.bitsPerPixel, RGBChannelCount));
5134
5135 //Lets check to see the channels are correctly defined in this file
5136 for (int ch = 0; ch < b.Channels.Count; ch++)
5137 {
5138 if (b.Channels[ch].SamplesPerPixel != RGBChannelCount)
5139 {
5140 b.Channels[ch].SamplesPerPixel = RGBChannelCount;
5141 }
5142 }
5143
5144 b.Buffers = new List<Bitmap>();
5145 int pages = image.NumberOfDirectories() / b.seriesCount;
5146 if (!imagej)
5147 b.sizeZ = pages;
5148 int str = image.ScanlineSize();
5149 bool inter = true;
5150 if (stride != str)
5151 inter = false;
5152 InitDirectoryResolution(b, image, imDesc);
5153 if (tiled)
5154 {
5155 Console.WriteLine("Opening tiles.");
5156 if (vips)
5157 OpenVips(b);
5158 for (int t = 0; t < b.SizeT; t++)
5159 {
5160 for (int c = 0; c < b.SizeC; c++)
5161 {
5162 for (int z = 0; z < b.SizeZ; z++)
5163 {
5164 Bitmap bmp = GetTile(b, b.GetFrameIndex(z, c, t), b.level, tileX, tileY, tileSizeX, tileSizeY);
5165 b.Buffers.Add(bmp);
5166 bmp.Stats = Statistics.FromBytes(bmp);
5167 }
5168 }
5169 }
5170 Console.WriteLine("Calculating statisitics.");
5171 }
5172 else
5173 {
5174 for (int p = series * pages; p < (series + 1) * pages; p++)
5175 {
5176 image.SetDirectory((short)p);
5177
5178 byte[] bytes = new byte[stride * SizeY];
5179 for (int im = 0, offset = 0; im < SizeY; im++)
5180 {
5181 image.ReadScanline(bytes, offset, im, 0);
5182 offset += stride;
5183 }
5184 Bitmap inf = new Bitmap(file, SizeX, SizeY, b.Resolutions[series].PixelFormat, bytes, new ZCT(0, 0, 0), p, null, b.littleEndian, inter);
5185 b.Buffers.Add(inf);
5186 inf.Stats = Statistics.FromBytes(inf);
5187 }
5188 }
5189 image.Close();
5190 b.UpdateCoords();
5191 }
5192 else
5193 {
5194 Gdk.Pixbuf pf = new Gdk.Pixbuf(file);
5195 b.littleEndian = BitConverter.IsLittleEndian;
5196 PixelFormat px = GetPixelFormat(pf.NChannels, pf.BitsPerSample);
5197 b.Resolutions.Add(new Resolution(pf.Width, pf.Height, px, 96 * (1 / 2.54) / 1000, 96 * (1 / 2.54) / 1000, 96 * (1 / 2.54) / 1000, 0, 0, 0));
5198 b.bitsPerPixel = pf.BitsPerSample;
5199 b.Buffers.Add(new Bitmap(pf.Width, pf.Height, pf.Width * pf.NChannels, px, pf.Pixels));
5200 b.Buffers.Last().ID = Bitmap.CreateID(file, 0);
5201 b.Buffers.Last().Stats = Statistics.FromBytes(b.Buffers.Last());
5202 b.Channels.Add(new Channel(0, b.bitsPerPixel, b.RGBChannelCount));
5203 b.Coords = new int[1, 1, 1];
5204 b.sizeC = 1;
5205 b.sizeT = 1;
5206 b.sizeZ = 1;
5207 }
5208 /*
5209 if (b.StageSizeX == -1)
5210 {
5211 b.imageInfo.Series = 0;
5212 b.stageSizeX = 0;
5213 b.stageSizeY = 0;
5214 b.stageSizeZ = 0;
5215 }
5216 */
5217 b.Volume = new VolumeD(new Point3D(b.StageSizeX, b.StageSizeY, b.StageSizeZ), new Point3D(b.PhysicalSizeX * b.SizeX, b.PhysicalSizeY * b.SizeY, b.PhysicalSizeZ * b.SizeZ));
5218
5219 //If file is ome and we have OME support then check for annotation in metadata.
5220 if (ome)
5221 {
5222 b.Annotations.AddRange(OpenOMEROIs(file, series));
5223 }
5224 AutoThreshold(b, false);
5225 if (b.bitsPerPixel > 8)
5226 b.StackThreshold(true);
5227 else
5228 b.StackThreshold(false);
5229 if (addToImages)
5230 Images.AddImage(b);
5231 //pr.Close();
5232 //pr.Dispose();
5233 st.Stop();
5234 b.loadTimeMS = st.ElapsedMilliseconds;
5235 Console.WriteLine("BioImage loaded " + b.ToString());
5236 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, file, series, tab, addToImages, tile, tileX, tileY, tileSizeX, tileSizeY);
5237 return b;
5238 }
override string ToString()
This function returns the filename of the object, and the location of the object in the 3D space.
Definition Bio.cs:8775
static PixelFormat GetPixelFormat(int rgbChannelCount, int bitsPerPixel)
If the bits per pixel is 8, then the pixel format is either 8bppIndexed, 24bppRgb,...
Definition Bio.cs:7439
static bool VipsSupport(string file)
The function checks if a given file is supported by the Vips library and returns true if it is,...
Definition Bio.cs:7889
static void OpenVips(BioImage b)
The function "OpenVips" takes a BioImage object and an integer representing the number of pages,...
Definition Bio.cs:6254
static BioImage FromNumpy(string file)
Converts a numpy array to BioImage.
Definition Bio.cs:5970
static List< ROI > ImportROIsCSV(string filename)
It reads the CSV file and converts each line into a ROI object.
Definition Bio.cs:8536
static Bitmap GetTile(BioImage b, int index, int level, int tilex, int tiley, int tileSizeX, int tileSizeY)
It reads a tile from a file, and returns a bitmap.
Definition Bio.cs:7202

◆ OpenOME() [1/3]

static BioImage BioLib.BioImage.OpenOME ( string file,
bool tab )
static

The function "OpenOME" opens a bioimage file in the OME format and returns the first image in the series.

Parameters
fileThe "file" parameter is a string that represents the file path or name of the OME file that you want to open.
tabThe "tab" parameter is a boolean value that determines whether the image is opened in a new tab.
Returns
The method is returning a BioImage object.
5950 {
5951 return OpenOMESeries(file, tab, true)[0];
5952 }
static BioImage[] OpenOMESeries(string file, bool tab, bool addToImages)
It opens a file, checks if it's tiled, if it is, it opens it as a tiled image, if not,...
Definition Bio.cs:7496

◆ OpenOME() [2/3]

static BioImage BioLib.BioImage.OpenOME ( string file,
int serie )
static

OpenOME(string file, int serie)

The first parameter is a string, the second is an integer

Parameters
filethe path to the file
seriethe image series to open
Returns
A BioImage object.
5962 {
5963 return OpenOME(file, serie, true, false, false, 0, 0, 0, 0);
5964 }

◆ OpenOME() [3/3]

static BioImage BioLib.BioImage.OpenOME ( string file,
int serie,
bool tab,
bool addToImages,
bool tile,
int tilex,
int tiley,
int tileSizeX,
int tileSizeY,
bool useOpenSlide = true )
static

The function "OpenOME" opens a bioimage file, with options to specify the series, whether to display it in a tab, whether to add it to existing images, whether to tile the image, and the tile size.

Parameters
fileThe file parameter is a string that represents the file path or name of the OME (Open Microscopy Environment) file that you want to open.
serieThe "serie" parameter is an integer that represents the series number of the image to be opened.
tabThe "tab" parameter is a boolean value that determines whether the image should be opened in a new tab or not. If set to true, the image will be opened in a new tab. If set to false, the image will be opened in the current tab.
addToImagesThe "addToImages" parameter is a boolean value that determines whether the opened image should be added to a collection of images. If set to true, the image will be added to the collection. If set to false, the image will not be added.
tileThe "tile" parameter is a boolean value that determines whether or not to tile the images. If set to true, the images will be tiled according to the specified tilex, tiley, tileSizeX, and tileSizeY parameters. If set to false, the images will not be tiled.
tilexThe parameter "tilex" is an integer that represents the starting x-coordinate of the tile.
tileyThe parameter "tiley" is used to specify the number of tiles in the y-direction when tiling the image.
tileSizeXThe tileSizeX parameter specifies the width of each tile in pixels when tiling the images.
tileSizeYThe tileSizeY parameter is the height of each tile in pixels when tiling the images.

The function "OpenOME" opens a bioimage file, with options to specify the series, whether to

6411 {
6412 if (file == null || file == "")
6413 throw new InvalidDataException("File is empty or null");
6414 //We wait incase OME has not initialized.
6415 do
6416 {
6417 Thread.Sleep(10);
6418 } while (!initialized);
6419 Console.WriteLine("OpenOME " + file);
6420 reader = new ImageReader();
6421 if (tileSizeX == 0)
6422 tileSizeX = 1920;
6423 if (tileSizeY == 0)
6424 tileSizeY = 1080;
6425 progFile = file;
6426 BioImage b = new BioImage(file);
6427 b.Type = ImageType.stack;
6428 b.Loading = true;
6429 if (b.meta == null)
6430 b.meta = service.createOMEXMLMetadata();
6431 string f = file.Replace("\\", "/");
6432 string cf = reader.getCurrentFile();
6433 if (cf != null)
6434 cf = cf.Replace("\\", "/");
6435 if (cf != f)
6436 {
6437 reader.close();
6438 reader.setMetadataStore(b.meta);
6439 try
6440 {
6441 Status = "Opening file " + b.Filename;
6442 reader.setId(f);
6443 }
6444 catch (Exception e)
6445 {
6446 Console.WriteLine(e.Message);
6447 return null;
6448 }
6449 }
6450
6451 //status = "Reading OME Metadata.";
6452 reader.setSeries(serie);
6453 int RGBChannelCount = reader.getRGBChannelCount();
6454 //OME reader.getBitsPerPixel(); sometimes returns incorrect bits per pixel, like when opening ImageJ images.
6455 //So we check the pixel type from xml metadata and if it fails we use the readers value.
6456 PixelFormat PixelFormat;
6457 try
6458 {
6459 PixelFormat = GetPixelFormat(RGBChannelCount, b.meta.getPixelsType(serie));
6460 }
6461 catch (Exception)
6462 {
6463 PixelFormat = GetPixelFormat(RGBChannelCount, reader.getBitsPerPixel());
6464 }
6465
6466 b.id = file;
6467 b.file = file;
6468 int SizeX, SizeY;
6469 SizeX = reader.getSizeX();
6470 SizeY = reader.getSizeY();
6471 int SizeZ = reader.getSizeZ();
6472 b.sizeC = reader.getSizeC();
6473 b.sizeZ = reader.getSizeZ();
6474 b.sizeT = reader.getSizeT();
6475 b.littleEndian = reader.isLittleEndian();
6476 b.seriesCount = reader.getSeriesCount();
6477 b.imagesPerSeries = reader.getImageCount();
6478 b.imRead = reader;
6479 List<Resolution> ress = new List<Resolution>();
6480 if (PixelFormat == PixelFormat.Format8bppIndexed || PixelFormat == PixelFormat.Format24bppRgb || PixelFormat == PixelFormat.Format32bppArgb)
6481 b.bitsPerPixel = 8;
6482 else
6483 b.bitsPerPixel = 16;
6484 b.series = serie;
6485 string order = reader.getDimensionOrder();
6486 if (vips && tile)
6487 OpenVips(b);
6488 //Lets get the channels and initialize them
6489 int i = 0;
6490 int sumSamples = 0;
6491 while (true)
6492 {
6493 Status = "Reading channels.";
6494 bool def = false;
6495 try
6496 {
6497 int s = b.meta.getChannelSamplesPerPixel(serie, i).getNumberValue().intValue();
6498 Channel ch = new Channel(i, b.bitsPerPixel, s);
6499 if (b.meta.getChannelSamplesPerPixel(serie, i) != null)
6500 {
6501 ch.SamplesPerPixel = s;
6502 sumSamples += s;
6503 def = true;
6504 b.Channels.Add(ch);
6505 }
6506 if (i == 0)
6507 {
6508 b.rgbChannels[0] = 0;
6509 }
6510 else
6511 if (i == 1)
6512 {
6513 b.rgbChannels[1] = 1;
6514 }
6515 else
6516 if (i == 2)
6517 {
6518 b.rgbChannels[2] = 2;
6519 }
6520 //If this channel is not defined we have loaded all the channels in the file.
6521 if (!def)
6522 break;
6523 if (b.meta.getChannelName(serie, i) != null)
6524 ch.Name = b.meta.getChannelName(serie, i);
6525 if (b.meta.getChannelAcquisitionMode(serie, i) != null)
6526 ch.AcquisitionMode = b.meta.getChannelAcquisitionMode(serie, i).ToString();
6527 if (b.meta.getChannelID(serie, i) != null)
6528 ch.info.ID = b.meta.getChannelID(serie, i);
6529 if (b.meta.getChannelFluor(serie, i) != null)
6530 ch.Fluor = b.meta.getChannelFluor(serie, i);
6531 if (b.meta.getChannelColor(serie, i) != null)
6532 {
6533 ome.xml.model.primitives.Color cc = b.meta.getChannelColor(serie, i);
6534 ch.Color = Color.FromArgb(cc.getRed(), cc.getGreen(), cc.getBlue());
6535 }
6536 if (b.meta.getChannelIlluminationType(serie, i) != null)
6537 ch.IlluminationType = b.meta.getChannelIlluminationType(serie, i).ToString();
6538 if (b.meta.getChannelContrastMethod(serie, i) != null)
6539 ch.ContrastMethod = b.meta.getChannelContrastMethod(serie, i).ToString();
6540 if (b.meta.getChannelEmissionWavelength(serie, i) != null)
6541 ch.Emission = b.meta.getChannelEmissionWavelength(serie, i).value().intValue();
6542 if (b.meta.getChannelExcitationWavelength(serie, i) != null)
6543 ch.Excitation = b.meta.getChannelExcitationWavelength(serie, i).value().intValue();
6544 if (b.meta.getLightEmittingDiodePower(serie, i) != null)
6545 ch.LightSourceIntensity = b.meta.getLightEmittingDiodePower(serie, i).value().doubleValue();
6546 if (b.meta.getLightEmittingDiodeID(serie, i) != null)
6547 ch.DiodeName = b.meta.getLightEmittingDiodeID(serie, i);
6548 if (b.meta.getChannelLightSourceSettingsAttenuation(serie, i) != null)
6549 ch.LightSourceAttenuation = b.meta.getChannelLightSourceSettingsAttenuation(serie, i).toString();
6550
6551
6552 }
6553 catch (Exception e)
6554 {
6555 Console.WriteLine(e.Message);
6556 if (!def)
6557 break;
6558 }
6559 i++;
6560 }
6561 try
6562 {
6563 if (b.meta.getObjectiveNominalMagnification(serie, 0) != null)
6564 {
6565 b.Magnification = b.meta.getObjectiveNominalMagnification(serie, 0).intValue();
6566 }
6567 }
6568 catch (Exception e)
6569 {
6570 Console.WriteLine(e.Message);
6571 }
6572
6573 //If the file doens't have channels we initialize them.
6574 if (b.Channels.Count == 0)
6575 {
6576 b.Channels.Add(new Channel(0, b.bitsPerPixel, RGBChannelCount));
6577 }
6578 try
6579 {
6580 Status = "Reading wells.";
6581 int wells = b.meta.getWellCount(0);
6582 if (wells > 0)
6583 {
6584 b.Type = ImageType.well;
6585 b.Plate = new WellPlate(b);
6586 tile = false;
6587 }
6588 }
6589 catch (Exception e)
6590 {
6591 //This file is not a well plate.
6592 Console.WriteLine(e.Message);
6593 }
6594 if (reader.getResolutionCount() > 0)
6595 ress.AddRange(GetResolutions(b));
6596 Console.WriteLine("Done reading resolutions.");
6597 reader.setSeries(serie);
6598
6599 int pyramidCount = 0;
6600 int pyramidResolutions = 0;
6601 List<Tuple<int, int>> prs = new List<Tuple<int, int>>();
6602 Console.WriteLine("Determining pyramidal levels.");
6603 //We need to determine if this image is pyramidal or not.
6604 //We do this by seeing if the resolutions are downsampled or not.
6605 if (ress.Count > 1 && b.Type != ImageType.well)
6606 {
6607 if (ress[0].SizeX > ress[1].SizeX)
6608 {
6609 b.Type = ImageType.pyramidal;
6610 tile = true;
6611 //We need to determine number of pyramids in this image and which belong to the series we are opening.
6612 int? sr = null;
6613 for (int r = 0; r < ress.Count - 1; r++)
6614 {
6615 if (ress[r].SizeX > ress[r + 1].SizeX && ress[r].PixelFormat == ress[r + 1].PixelFormat)
6616 {
6617 if (sr == null)
6618 {
6619 sr = r;
6620 prs.Add(new Tuple<int, int>(r, 0));
6621 }
6622 }
6623 else
6624 {
6625 if (ress[prs[prs.Count - 1].Item1].PixelFormat == ress[r].PixelFormat)
6626 prs[prs.Count - 1] = new Tuple<int, int>(prs[prs.Count - 1].Item1, r);
6627 sr = null;
6628 }
6629 }
6630 pyramidCount = prs.Count;
6631 for (int p = 0; p < prs.Count; p++)
6632 {
6633 pyramidResolutions += (prs[p].Item2 - prs[p].Item1) + 1;
6634 }
6635 if (prs[serie].Item2 == 0)
6636 {
6637 prs[serie] = new Tuple<int, int>(prs[serie].Item1, b.seriesCount - 1);
6638 }
6639 }
6640 }
6641 if (b.Type == ImageType.pyramidal)
6642 {
6643 Console.WriteLine("Determining Label and Macro resolutions.");
6644 for (int p = 0; p < prs.Count; p++)
6645 {
6646 for (int r = prs[p].Item1; r < prs[p].Item2 + 1; r++)
6647 {
6648 b.Resolutions.Add(ress[r]);
6649 }
6650 }
6651 //If we have 2 resolutions that we're not added they are the label & macro resolutions so we add them to the image.
6652 if (ress.Count > b.Resolutions.Count)
6653 {
6654 b.LabelResolution = ress.Count - 1;
6655 b.Resolutions.Add(ress[ress.Count - 1]);
6656 b.MacroResolution = ress.Count - 2;
6657 b.Resolutions.Add(ress[ress.Count - 2]);
6658 }
6659 }
6660 if (b.Resolutions.Count == 0)
6661 b.Resolutions.AddRange(ress);
6662 try
6663 {
6664 string s = b.meta.getStageLabelName(serie);
6665 if (s != null)
6666 {
6667 Resolution res = new Resolution(b.SizeX, b.SizeY, PixelFormat, b.PhysicalSizeX, b.PhysicalSizeY, b.PhysicalSizeZ,
6668 b.meta.getStageLabelX(serie).value().doubleValue(),
6669 b.meta.getStageLabelY(serie).value().doubleValue(),
6670 b.meta.getStageLabelZ(serie).value().doubleValue());
6671 }
6672 }
6673 catch (Exception e)
6674 {
6675 Console.WriteLine("No Stage Cooordinates");
6676 }
6677
6678 b.Volume = new VolumeD(new Point3D(b.StageSizeX, b.StageSizeY, b.StageSizeZ), new Point3D(b.PhysicalSizeX * SizeX, b.PhysicalSizeY * SizeY, b.PhysicalSizeZ * SizeZ));
6679 int rc = b.meta.getROICount();
6680 for (int im = 0; im < rc; im++)
6681 {
6682 string roiID = b.meta.getROIID(im);
6683 string roiName = b.meta.getROIName(im);
6684 ZCT co = new ZCT(0, 0, 0);
6685 int scount = 1;
6686 try
6687 {
6688 scount = b.meta.getShapeCount(im);
6689 }
6690 catch (Exception e)
6691 {
6692 Console.WriteLine(e.Message.ToString());
6693 }
6694 for (int sc = 0; sc < scount; sc++)
6695 {
6696 Status = "Reading ROI " + (sc + 1).ToString() + "/" + scount;
6697 string typ = b.meta.getShapeType(im, sc);
6698 ROI an = new ROI();
6699 an.roiID = roiID;
6700 an.roiName = roiName;
6701 an.shapeIndex = sc;
6702 if (typ == "Point")
6703 {
6704 an.type = ROI.Type.Point;
6705 an.id = b.meta.getPointID(im, sc);
6706 double dx = b.meta.getPointX(im, sc).doubleValue();
6707 double dy = b.meta.getPointY(im, sc).doubleValue();
6708 an.AddPoint(b.ToStageSpace(new PointD(dx, dy)));
6709 an.coord = new ZCT();
6710 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getPointTheZ(im, sc);
6711 if (nz != null)
6712 an.coord.Z = nz.getNumberValue().intValue();
6713 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getPointTheC(im, sc);
6714 if (nc != null)
6715 an.coord.C = nc.getNumberValue().intValue();
6716 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getPointTheT(im, sc);
6717 if (nt != null)
6718 an.coord.T = nt.getNumberValue().intValue();
6719 an.Text = b.meta.getPointText(im, sc);
6720 ome.units.quantity.Length fl = b.meta.getPointFontSize(im, sc);
6721 if (fl != null)
6722 an.fontSize = fl.value().intValue();
6723 ome.xml.model.enums.FontFamily ff = b.meta.getPointFontFamily(im, sc);
6724 if (ff != null)
6725 an.family = ff.name();
6726 ome.xml.model.primitives.Color col = b.meta.getPointStrokeColor(im, sc);
6727 if (col != null)
6728 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
6729 ome.units.quantity.Length fw = b.meta.getPointStrokeWidth(im, sc);
6730 if (fw != null)
6731 an.strokeWidth = (float)fw.value().floatValue();
6732 ome.xml.model.primitives.Color colf = b.meta.getPointStrokeColor(im, sc);
6733 if (colf != null)
6734 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
6735 }
6736 else
6737 if (typ == "Line")
6738 {
6739 an.type = ROI.Type.Line;
6740 an.id = b.meta.getLineID(im, sc);
6741 double px1 = b.meta.getLineX1(im, sc).doubleValue();
6742 double py1 = b.meta.getLineY1(im, sc).doubleValue();
6743 double px2 = b.meta.getLineX2(im, sc).doubleValue();
6744 double py2 = b.meta.getLineY2(im, sc).doubleValue();
6745 List<PointD> pds = new List<PointD>();
6746 pds.Add(b.ToStageSpace(new PointD(px1, py1)));
6747 pds.Add(b.ToStageSpace(new PointD(px2, py2)));
6748 an.Points = pds;
6749 an.UpdateBoundingBox();
6750 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getLineTheZ(im, sc);
6751 if (nz != null)
6752 co.Z = nz.getNumberValue().intValue();
6753 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getLineTheC(im, sc);
6754 if (nc != null)
6755 co.C = nc.getNumberValue().intValue();
6756 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getLineTheT(im, sc);
6757 if (nt != null)
6758 co.T = nt.getNumberValue().intValue();
6759 an.coord = co;
6760 an.Text = b.meta.getLineText(im, sc);
6761 ome.units.quantity.Length fl = b.meta.getLineFontSize(im, sc);
6762 if (fl != null)
6763 an.fontSize = fl.value().intValue();
6764 ome.xml.model.enums.FontFamily ff = b.meta.getLineFontFamily(im, sc);
6765 if (ff != null)
6766 an.family = ff.name();
6767 ome.xml.model.primitives.Color col = b.meta.getLineStrokeColor(im, sc);
6768 if (col != null)
6769 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
6770 ome.units.quantity.Length fw = b.meta.getLineStrokeWidth(im, sc);
6771 if (fw != null)
6772 an.strokeWidth = (float)fw.value().floatValue();
6773 ome.xml.model.primitives.Color colf = b.meta.getLineFillColor(im, sc);
6774 if (colf != null)
6775 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
6776 }
6777 else
6778 if (typ == "Rectangle")
6779 {
6780 an.type = ROI.Type.Rectangle;
6781 an.id = b.meta.getRectangleID(im, sc);
6782 double px = b.meta.getRectangleX(im, sc).doubleValue();
6783 double py = b.meta.getRectangleY(im, sc).doubleValue();
6784 double pw = b.meta.getRectangleWidth(im, sc).doubleValue();
6785 double ph = b.meta.getRectangleHeight(im, sc).doubleValue();
6786 an.BoundingBox = b.ToStageSpace(new RectangleD(px, py, pw, ph));
6787 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getRectangleTheZ(im, sc);
6788 if (nz != null)
6789 co.Z = nz.getNumberValue().intValue();
6790 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getRectangleTheC(im, sc);
6791 if (nc != null)
6792 co.C = nc.getNumberValue().intValue();
6793 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getRectangleTheT(im, sc);
6794 if (nt != null)
6795 co.T = nt.getNumberValue().intValue();
6796 an.coord = co;
6797
6798 an.Text = b.meta.getRectangleText(im, sc);
6799 ome.units.quantity.Length fl = b.meta.getRectangleFontSize(im, sc);
6800 if (fl != null)
6801 an.fontSize = fl.value().intValue();
6802 ome.xml.model.enums.FontFamily ff = b.meta.getRectangleFontFamily(im, sc);
6803 if (ff != null)
6804 an.family = ff.name();
6805 ome.xml.model.primitives.Color col = b.meta.getRectangleStrokeColor(im, sc);
6806 if (col != null)
6807 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
6808 ome.units.quantity.Length fw = b.meta.getRectangleStrokeWidth(im, sc);
6809 if (fw != null)
6810 an.strokeWidth = (float)fw.value().floatValue();
6811 ome.xml.model.primitives.Color colf = b.meta.getRectangleFillColor(im, sc);
6812 if (colf != null)
6813 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
6814 ome.xml.model.enums.FillRule fr = b.meta.getRectangleFillRule(im, sc);
6815
6816 }
6817 else
6818 if (typ == "Ellipse")
6819 {
6820 an.type = ROI.Type.Ellipse;
6821 an.id = b.meta.getEllipseID(im, sc);
6822 double px = b.meta.getEllipseX(im, sc).doubleValue();
6823 double py = b.meta.getEllipseY(im, sc).doubleValue();
6824 double ew = b.meta.getEllipseRadiusX(im, sc).doubleValue();
6825 double eh = b.meta.getEllipseRadiusY(im, sc).doubleValue();
6826 //We convert the ellipse radius to Rectangle
6827 double w = ew * 2;
6828 double h = eh * 2;
6829 double x = px - ew;
6830 double y = py - eh;
6831 an.BoundingBox = b.ToStageSpace(new RectangleD(x, y, w, h));
6832 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getEllipseTheZ(im, sc);
6833 if (nz != null)
6834 co.Z = nz.getNumberValue().intValue();
6835 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getEllipseTheC(im, sc);
6836 if (nc != null)
6837 co.C = nc.getNumberValue().intValue();
6838 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getEllipseTheT(im, sc);
6839 if (nt != null)
6840 co.T = nt.getNumberValue().intValue();
6841 an.coord = co;
6842 an.Text = b.meta.getEllipseText(im, sc);
6843 ome.units.quantity.Length fl = b.meta.getEllipseFontSize(im, sc);
6844 if (fl != null)
6845 an.fontSize = fl.value().intValue();
6846 ome.xml.model.enums.FontFamily ff = b.meta.getEllipseFontFamily(im, sc);
6847 if (ff != null)
6848 an.family = ff.name();
6849 ome.xml.model.primitives.Color col = b.meta.getEllipseStrokeColor(im, sc);
6850 if (col != null)
6851 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
6852 ome.units.quantity.Length fw = b.meta.getEllipseStrokeWidth(im, sc);
6853 if (fw != null)
6854 an.strokeWidth = (float)fw.value().floatValue();
6855 ome.xml.model.primitives.Color colf = b.meta.getEllipseFillColor(im, sc);
6856 if (colf != null)
6857 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
6858 }
6859 else
6860 if (typ == "Polygon")
6861 {
6862 an.type = ROI.Type.Polygon;
6863 an.id = b.meta.getPolygonID(im, sc);
6864 an.closed = true;
6865 string pxs = b.meta.getPolygonPoints(im, sc);
6866 PointD[] pts = an.stringToPoints(pxs);
6867 pts = b.ToStageSpace(pts);
6868 if (pts.Length > 100)
6869 {
6870 an.type = ROI.Type.Freeform;
6871 }
6872 an.AddPoints(pts);
6873 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getPolygonTheZ(im, sc);
6874 if (nz != null)
6875 co.Z = nz.getNumberValue().intValue();
6876 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getPolygonTheC(im, sc);
6877 if (nc != null)
6878 co.C = nc.getNumberValue().intValue();
6879 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getPolygonTheT(im, sc);
6880 if (nt != null)
6881 co.T = nt.getNumberValue().intValue();
6882 an.coord = co;
6883 an.Text = b.meta.getPolygonText(im, sc);
6884 ome.units.quantity.Length fl = b.meta.getPolygonFontSize(im, sc);
6885 if (fl != null)
6886 an.fontSize = fl.value().intValue();
6887 ome.xml.model.enums.FontFamily ff = b.meta.getPolygonFontFamily(im, sc);
6888 if (ff != null)
6889 an.family = ff.name();
6890 ome.xml.model.primitives.Color col = b.meta.getPolygonStrokeColor(im, sc);
6891 if (col != null)
6892 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
6893 ome.units.quantity.Length fw = b.meta.getPolygonStrokeWidth(im, sc);
6894 if (fw != null)
6895 an.strokeWidth = (float)fw.value().floatValue();
6896 ome.xml.model.primitives.Color colf = b.meta.getPolygonFillColor(im, sc);
6897 if (colf != null)
6898 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
6899 }
6900 else
6901 if (typ == "Polyline")
6902 {
6903 an.type = ROI.Type.Polyline;
6904 an.id = b.meta.getPolylineID(im, sc);
6905 string pxs = b.meta.getPolylinePoints(im, sc);
6906 PointD[] pts = an.stringToPoints(pxs);
6907 for (int pi = 0; pi < pts.Length; pi++)
6908 {
6909 pts[pi] = b.ToStageSpace(pts[pi]);
6910 }
6911 an.AddPoints(pts);
6912 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getPolylineTheZ(im, sc);
6913 if (nz != null)
6914 co.Z = nz.getNumberValue().intValue();
6915 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getPolylineTheC(im, sc);
6916 if (nc != null)
6917 co.C = nc.getNumberValue().intValue();
6918 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getPolylineTheT(im, sc);
6919 if (nt != null)
6920 co.T = nt.getNumberValue().intValue();
6921 an.coord = co;
6922 an.Text = b.meta.getPolylineText(im, sc);
6923 ome.units.quantity.Length fl = b.meta.getPolylineFontSize(im, sc);
6924 if (fl != null)
6925 an.fontSize = fl.value().intValue();
6926 ome.xml.model.enums.FontFamily ff = b.meta.getPolylineFontFamily(im, sc);
6927 if (ff != null)
6928 an.family = ff.name();
6929 ome.xml.model.primitives.Color col = b.meta.getPolylineStrokeColor(im, sc);
6930 if (col != null)
6931 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
6932 ome.units.quantity.Length fw = b.meta.getPolylineStrokeWidth(im, sc);
6933 if (fw != null)
6934 an.strokeWidth = (float)fw.value().floatValue();
6935 ome.xml.model.primitives.Color colf = b.meta.getPolylineFillColor(im, sc);
6936 if (colf != null)
6937 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
6938 }
6939 else
6940 if (typ == "Label")
6941 {
6942 an.type = ROI.Type.Label;
6943 an.id = b.meta.getLabelID(im, sc);
6944 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getLabelTheZ(im, sc);
6945 if (nz != null)
6946 co.Z = nz.getNumberValue().intValue();
6947 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getLabelTheC(im, sc);
6948 if (nc != null)
6949 co.C = nc.getNumberValue().intValue();
6950 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getLabelTheT(im, sc);
6951 if (nt != null)
6952 co.T = nt.getNumberValue().intValue();
6953 an.coord = co;
6954
6955 ome.units.quantity.Length fl = b.meta.getLabelFontSize(im, sc);
6956 if (fl != null)
6957 an.fontSize = fl.value().intValue();
6958 ome.xml.model.enums.FontFamily ff = b.meta.getLabelFontFamily(im, sc);
6959 if (ff != null)
6960 an.family = ff.name();
6961 ome.xml.model.primitives.Color col = b.meta.getLabelStrokeColor(im, sc);
6962 if (col != null)
6963 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
6964 ome.units.quantity.Length fw = b.meta.getLabelStrokeWidth(im, sc);
6965 if (fw != null)
6966 an.strokeWidth = (float)fw.value().floatValue();
6967 ome.xml.model.primitives.Color colf = b.meta.getLabelFillColor(im, sc);
6968 if (colf != null)
6969 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
6970 PointD p = new PointD(b.meta.getLabelX(im, sc).doubleValue(), b.meta.getLabelY(im, sc).doubleValue());
6971 an.UpdatePoint(b.ToStageSpace(p),0);
6972 an.Text = b.meta.getLabelText(im, sc);
6973 }
6974 else
6975 if (typ == "Mask")
6976 {
6977 byte[] bts = b.meta.getMaskBinData(im, sc);
6978 bool end = b.meta.getMaskBinDataBigEndian(im, sc).booleanValue();
6979 double h = b.meta.getMaskHeight(im, sc).doubleValue();
6980 double w = b.meta.getMaskWidth(im, sc).doubleValue();
6981 double x = b.meta.getMaskX(im, sc).doubleValue();
6982 double y = b.meta.getMaskY(im, sc).doubleValue();
6983 an = ROI.CreateMask(co, bts, (int)Math.Round(w / b.PhysicalSizeX), (int)Math.Round(h / b.PhysicalSizeY), new PointD(x * b.PhysicalSizeX, y * b.PhysicalSizeY), b.PhysicalSizeX, b.PhysicalSizeY);
6984 an.Text = b.meta.getMaskText(im, sc);
6985 an.id = b.meta.getMaskID(im, sc);
6986 an.BoundingBox = new RectangleD(an.X, an.Y, an.W, an.H);
6987 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getMaskTheZ(im, sc);
6988 if (nz != null)
6989 co.Z = nz.getNumberValue().intValue();
6990 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getMaskTheC(im, sc);
6991 if (nc != null)
6992 co.C = nc.getNumberValue().intValue();
6993 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getMaskTheT(im, sc);
6994 if (nt != null)
6995 co.T = nt.getNumberValue().intValue();
6996 an.coord = co;
6997
6998 ome.units.quantity.Length fl = b.meta.getMaskFontSize(im, sc);
6999 if (fl != null)
7000 an.fontSize = fl.value().intValue();
7001 ome.xml.model.enums.FontFamily ff = b.meta.getMaskFontFamily(im, sc);
7002 if (ff != null)
7003 an.family = ff.name();
7004 ome.xml.model.primitives.Color col = b.meta.getMaskStrokeColor(im, sc);
7005 if (col != null)
7006 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
7007 ome.units.quantity.Length fw = b.meta.getMaskStrokeWidth(im, sc);
7008 if (fw != null)
7009 an.strokeWidth = (float)fw.value().floatValue();
7010 ome.xml.model.primitives.Color colf = b.meta.getMaskFillColor(im, sc);
7011 if (colf != null)
7012 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
7013 }
7014 b.Annotations.Add(an);
7015 }
7016 }
7017
7018 List<string> serFiles = new List<string>();
7019 serFiles.AddRange(reader.getSeriesUsedFiles());
7020
7021 b.Buffers = new List<Bitmap>();
7022 if (b.Type == ImageType.pyramidal)
7023 {
7024
7025 try
7026 {
7027
7028 string st = OpenSlideImage.DetectVendor(file);
7029 if (st != null && !file.EndsWith("ome.tif") && useOpenSlide)
7030 {
7031 Status = "Opening file with OpenSlide.";
7032 b.openSlideImage = OpenSlideImage.Open(file);
7033 b.openslideBase = (OpenSlideBase)OpenSlideGTK.SlideSourceBase.Create(file, true);
7034 }
7035 else
7036 {
7037 Status = "Opening file with BioFormats.";
7038 b.slideBase = new SlideBase(b, SlideImage.Open(b));
7039 }
7040 }
7041 catch (Exception e)
7042 {
7043 Console.WriteLine(e.Message.ToString());
7044 b.slideBase = new SlideBase(b, SlideImage.Open(b));
7045 }
7046 tile = true;
7047 }
7048 // read the image data bytes
7049 int pages = reader.getImageCount();
7050 bool inter = reader.isInterleaved();
7051 int z = 0;
7052 int c = 0;
7053 int t = 0;
7054 if (!tile)
7055 {
7056 Status = "Reading image planes.";
7057 try
7058 {
7059 for (int p = 0; p < pages; p++)
7060 {
7061 Progress = ((float)p / (float)pages) * 100;
7062 Bitmap bf;
7063 byte[] bytes = reader.openBytes(p);
7064 bf = new Bitmap(file, SizeX, SizeY, PixelFormat, bytes, new ZCT(z, c, t), p, null, b.littleEndian, inter);
7065 b.Buffers.Add(bf);
7066 }
7067 }
7068 catch (Exception ex)
7069 {
7070 Console.WriteLine(ex.Message);
7071 }
7072
7073 }
7074 else
7075 {
7076 Status = "Reading tiles.";
7077 b.imRead = reader;
7078 for (int p = 0; p < pages; p++)
7079 {
7080 Progress = ((float)p / (float)pages) * 100;
7081 b.Buffers.Add(GetTile(b, p, b.Level, tilex, tiley, tileSizeX, tileSizeY));
7082 }
7083 }
7084 int pls;
7085 try
7086 {
7087 pls = b.meta.getPlaneCount(serie);
7088 }
7089 catch (Exception)
7090 {
7091 pls = 0;
7092 }
7093 if (pls == b.Buffers.Count)
7094 for (int bi = 0; bi < b.Buffers.Count; bi++)
7095 {
7096 Plane pl = new Plane();
7097 pl.Coordinate = new ZCT();
7098 double px = 0; double py = 0; double pz = 0;
7099 if (b.meta.getPlanePositionX(serie, bi) != null)
7100 px = b.meta.getPlanePositionX(serie, bi).value().doubleValue();
7101 if (b.meta.getPlanePositionY(serie, bi) != null)
7102 py = b.meta.getPlanePositionY(serie, bi).value().doubleValue();
7103 if (b.meta.getPlanePositionZ(serie, bi) != null)
7104 pz = b.meta.getPlanePositionZ(serie, bi).value().doubleValue();
7105 pl.Location = new AForge.Point3D(px, py, pz);
7106 int cc = 0; int zc = 0; int tc = 0;
7107 if (b.meta.getPlaneTheC(serie, bi) != null)
7108 cc = b.meta.getPlaneTheC(serie, bi).getNumberValue().intValue();
7109 if (b.meta.getPlaneTheZ(serie, bi) != null)
7110 zc = b.meta.getPlaneTheZ(serie, bi).getNumberValue().intValue();
7111 if (b.meta.getPlaneTheT(serie, bi) != null)
7112 tc = b.meta.getPlaneTheT(serie, bi).getNumberValue().intValue();
7113 pl.Coordinate = new ZCT(zc, cc, tc);
7114 if (b.meta.getPlaneDeltaT(serie, bi) != null)
7115 pl.Delta = b.meta.getPlaneDeltaT(serie, bi).value().doubleValue();
7116 if (b.meta.getPlaneExposureTime(serie, bi) != null)
7117 pl.Exposure = b.meta.getPlaneExposureTime(serie, bi).value().doubleValue();
7118 b.Buffers[bi].Plane = pl;
7119 }
7120 //Bioformats gives a size of 3 for C when saved in ImageJ as RGB. We need to correct for this as C should be 1 for RGB.
7121 if (RGBChannelCount >= 3)
7122 {
7123 b.sizeC = sumSamples / b.Channels[0].SamplesPerPixel;
7124 }
7125 string ord = reader.getDimensionOrder();
7126 if (ord == "XYZCT")
7127 b.UpdateCoords(b.SizeZ, b.SizeC, b.SizeT, Order.ZCT);
7128 else if (ord == "XYCZT")
7129 b.UpdateCoords(b.SizeZ, b.SizeC, b.SizeT, Order.CZT);
7130 else if (ord == "XYTCZ")
7131 b.UpdateCoords(b.SizeZ, b.SizeC, b.SizeT, Order.TCZ);
7132 AutoThreshold(b, true);
7133 if (b.bitsPerPixel > 8)
7134 b.StackThreshold(true);
7135 else
7136 b.StackThreshold(false);
7137 try
7138 {
7139 if (b.Type == ImageType.stack)
7140 reader.close();
7141 if (addToImages)
7142 Images.AddImage(b);
7143 }
7144 catch (Exception e)
7145 {
7146 Console.WriteLine(e.Message);
7147 }
7148 b.Loading = false;
7149 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, file, serie, tab, addToImages, tile, tilex, tiley, tileSizeX, tileSizeY);
7150 return b;
7151 }
PointD ToStageSpace(PointD p)
Definition Bio.cs:3388
void UpdateBoundingBox()
Definition ROI.cs:1427
PointD[] stringToPoints(string s)
Definition ROI.cs:1390
void AddPoint(PointD p)
Definition ROI.cs:1311
void UpdatePoint(PointD p, int i)
Definition ROI.cs:1270
void AddPoints(PointD[] p)
Definition ROI.cs:1321
openslide wrapper
Definition SlideImage.cs:19
static SlideImage Open(BioImage b)
Open.
Definition SlideImage.cs:73

◆ OpenOMEROIs()

static List< ROI > BioLib.BioImage.OpenOMEROIs ( string file,
int series )
static

It reads the OME-XML file and converts the ROIs to a list of ROI objects.

Parameters
filethe path to the OME-TIFF file
seriesthe series number of the image you want to open
Returns
A list of ROI objects.
7942 {
7943 List<ROI> Annotations = new List<ROI>();
7944 // create OME-XML metadata store
7945 ServiceFactory factory = new ServiceFactory();
7946 OMEXMLService service = (OMEXMLService)factory.getInstance(typeof(OMEXMLService));
7947 loci.formats.ome.OMEXMLMetadata meta = service.createOMEXMLMetadata();
7948 // create format reader
7949 ImageReader imageReader = new ImageReader();
7950 imageReader.setMetadataStore(meta);
7951 // initialize file
7952 file = file.Replace("\\", "/");
7953 imageReader.setId(file);
7954 int imageCount = imageReader.getImageCount();
7955 int seriesCount = imageReader.getSeriesCount();
7956 double physicalSizeX = 0;
7957 double physicalSizeY = 0;
7958 double physicalSizeZ = 0;
7959 double stageSizeX = 0;
7960 double stageSizeY = 0;
7961 double stageSizeZ = 0;
7962 int SizeX = imageReader.getSizeX();
7963 int SizeY = imageReader.getSizeY();
7964 int SizeZ = imageReader.getSizeY();
7965 try
7966 {
7967 bool hasPhysical = false;
7968 if (meta.getPixelsPhysicalSizeX(series) != null)
7969 {
7970 physicalSizeX = meta.getPixelsPhysicalSizeX(series).value().doubleValue();
7971 hasPhysical = true;
7972 }
7973 if (meta.getPixelsPhysicalSizeY(series) != null)
7974 {
7975 physicalSizeY = meta.getPixelsPhysicalSizeY(series).value().doubleValue();
7976 }
7977 if (meta.getPixelsPhysicalSizeZ(series) != null)
7978 {
7979 physicalSizeZ = meta.getPixelsPhysicalSizeZ(series).value().doubleValue();
7980 }
7981 else
7982 {
7983 physicalSizeZ = 1;
7984 }
7985 if (meta.getStageLabelX(series) != null)
7986 stageSizeX = meta.getStageLabelX(series).value().doubleValue();
7987 if (meta.getStageLabelY(series) != null)
7988 stageSizeY = meta.getStageLabelY(series).value().doubleValue();
7989 if (meta.getStageLabelZ(series) != null)
7990 stageSizeZ = meta.getStageLabelZ(series).value().doubleValue();
7991 else
7992 stageSizeZ = 1;
7993 }
7994 catch (Exception e)
7995 {
7996 stageSizeX = 0;
7997 stageSizeY = 0;
7998 stageSizeZ = 1;
7999 }
8000 VolumeD volume = new VolumeD(new Point3D(stageSizeX, stageSizeY, stageSizeZ), new Point3D(physicalSizeX * SizeX, physicalSizeY * SizeY, physicalSizeZ * SizeZ));
8001 int rc = meta.getROICount();
8002 for (int im = 0; im < rc; im++)
8003 {
8004 string roiID = meta.getROIID(im);
8005 string roiName = meta.getROIName(im);
8006 ZCT co = new ZCT(0, 0, 0);
8007 int scount = 1;
8008 try
8009 {
8010 scount = meta.getShapeCount(im);
8011 }
8012 catch (Exception e)
8013 {
8014 Console.WriteLine(e.Message.ToString());
8015 }
8016 for (int sc = 0; sc < scount; sc++)
8017 {
8018 string type = meta.getShapeType(im, sc);
8019 ROI an = new ROI();
8020 an.roiID = roiID;
8021 an.roiName = roiName;
8022 an.shapeIndex = sc;
8023 if (type == "Point")
8024 {
8025 an.type = ROI.Type.Point;
8026 an.id = meta.getPointID(im, sc);
8027 double dx = meta.getPointX(im, sc).doubleValue();
8028 double dy = meta.getPointY(im, sc).doubleValue();
8029 an.AddPoint(ToStageSpace(new PointD(dx, dy), physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y));
8030 an.coord = new ZCT();
8031 ome.xml.model.primitives.NonNegativeInteger nz = meta.getPointTheZ(im, sc);
8032 if (nz != null)
8033 an.coord.Z = nz.getNumberValue().intValue();
8034 ome.xml.model.primitives.NonNegativeInteger nc = meta.getPointTheC(im, sc);
8035 if (nc != null)
8036 an.coord.C = nc.getNumberValue().intValue();
8037 ome.xml.model.primitives.NonNegativeInteger nt = meta.getPointTheT(im, sc);
8038 if (nt != null)
8039 an.coord.T = nt.getNumberValue().intValue();
8040 an.Text = meta.getPointText(im, sc);
8041 ome.units.quantity.Length fl = meta.getPointFontSize(im, sc);
8042 if (fl != null)
8043 an.fontSize = fl.value().intValue();
8044 an.family = meta.getPointFontFamily(im, sc).name();
8045 ome.xml.model.primitives.Color col = meta.getPointStrokeColor(im, sc);
8046 if (col != null)
8047 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8048 ome.units.quantity.Length fw = meta.getPointStrokeWidth(im, sc);
8049 if (fw != null)
8050 an.strokeWidth = (float)fw.value().floatValue();
8051 ome.xml.model.primitives.Color colf = meta.getPointStrokeColor(im, sc);
8052 if (colf != null)
8053 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8054 }
8055 else
8056 if (type == "Line")
8057 {
8058 an.type = ROI.Type.Line;
8059 an.id = meta.getLineID(im, sc);
8060 double px1 = meta.getLineX1(im, sc).doubleValue();
8061 double py1 = meta.getLineY1(im, sc).doubleValue();
8062 double px2 = meta.getLineX2(im, sc).doubleValue();
8063 double py2 = meta.getLineY2(im, sc).doubleValue();
8064 an.AddPoint(ToStageSpace(new PointD(px1, py1), physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y));
8065 an.AddPoint(ToStageSpace(new PointD(px2, py2), physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y));
8066 ome.xml.model.primitives.NonNegativeInteger nz = meta.getLineTheZ(im, sc);
8067 if (nz != null)
8068 co.Z = nz.getNumberValue().intValue();
8069 ome.xml.model.primitives.NonNegativeInteger nc = meta.getLineTheC(im, sc);
8070 if (nc != null)
8071 co.C = nc.getNumberValue().intValue();
8072 ome.xml.model.primitives.NonNegativeInteger nt = meta.getLineTheT(im, sc);
8073 if (nt != null)
8074 co.T = nt.getNumberValue().intValue();
8075 an.coord = co;
8076 an.Text = meta.getLineText(im, sc);
8077 ome.units.quantity.Length fl = meta.getLineFontSize(im, sc);
8078 if (fl != null)
8079 an.fontSize = fl.value().intValue();
8080 an.family = meta.getPointFontFamily(im, sc).name();
8081 ome.xml.model.primitives.Color col = meta.getLineStrokeColor(im, sc);
8082 if (col != null)
8083 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8084 ome.units.quantity.Length fw = meta.getLineStrokeWidth(im, sc);
8085 if (fw != null)
8086 an.strokeWidth = (float)fw.value().floatValue();
8087 ome.xml.model.primitives.Color colf = meta.getLineFillColor(im, sc);
8088 if (colf != null)
8089 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8090 }
8091 else
8092 if (type == "Rectangle")
8093 {
8094 an.type = ROI.Type.Rectangle;
8095 an.id = meta.getRectangleID(im, sc);
8096 double px = meta.getRectangleX(im, sc).doubleValue();
8097 double py = meta.getRectangleY(im, sc).doubleValue();
8098 double pw = meta.getRectangleWidth(im, sc).doubleValue();
8099 double ph = meta.getRectangleHeight(im, sc).doubleValue();
8100 an.BoundingBox = ToStageSpace(new RectangleD(px, py, pw, ph), physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y);
8101 ome.xml.model.primitives.NonNegativeInteger nz = meta.getRectangleTheZ(im, sc);
8102 if (nz != null)
8103 co.Z = nz.getNumberValue().intValue();
8104 ome.xml.model.primitives.NonNegativeInteger nc = meta.getRectangleTheC(im, sc);
8105 if (nc != null)
8106 co.C = nc.getNumberValue().intValue();
8107 ome.xml.model.primitives.NonNegativeInteger nt = meta.getRectangleTheT(im, sc);
8108 if (nt != null)
8109 co.T = nt.getNumberValue().intValue();
8110 an.coord = co;
8111
8112 an.Text = meta.getRectangleText(im, sc);
8113 ome.units.quantity.Length fl = meta.getRectangleFontSize(im, sc);
8114 if (fl != null)
8115 an.fontSize = fl.value().intValue();
8116 an.family = meta.getPointFontFamily(im, sc).name();
8117 ome.xml.model.primitives.Color col = meta.getRectangleStrokeColor(im, sc);
8118 if (col != null)
8119 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8120 ome.units.quantity.Length fw = meta.getRectangleStrokeWidth(im, sc);
8121 if (fw != null)
8122 an.strokeWidth = (float)fw.value().floatValue();
8123 ome.xml.model.primitives.Color colf = meta.getRectangleFillColor(im, sc);
8124 if (colf != null)
8125 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8126 ome.xml.model.enums.FillRule fr = meta.getRectangleFillRule(im, sc);
8127 }
8128 else
8129 if (type == "Ellipse")
8130 {
8131 an.type = ROI.Type.Ellipse;
8132 an.id = meta.getEllipseID(im, sc);
8133 double px = meta.getEllipseX(im, sc).doubleValue();
8134 double py = meta.getEllipseY(im, sc).doubleValue();
8135 double ew = meta.getEllipseRadiusX(im, sc).doubleValue();
8136 double eh = meta.getEllipseRadiusY(im, sc).doubleValue();
8137 //We convert the ellipse radius to Rectangle
8138 double w = ew * 2;
8139 double h = eh * 2;
8140 double x = px - ew;
8141 double y = py - eh;
8142 an.BoundingBox = ToStageSpace(new RectangleD(px, py, w, h), physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y);
8143 ome.xml.model.primitives.NonNegativeInteger nz = meta.getEllipseTheZ(im, sc);
8144 if (nz != null)
8145 co.Z = nz.getNumberValue().intValue();
8146 ome.xml.model.primitives.NonNegativeInteger nc = meta.getEllipseTheC(im, sc);
8147 if (nc != null)
8148 co.C = nc.getNumberValue().intValue();
8149 ome.xml.model.primitives.NonNegativeInteger nt = meta.getEllipseTheT(im, sc);
8150 if (nt != null)
8151 co.T = nt.getNumberValue().intValue();
8152 an.coord = co;
8153 an.Text = meta.getEllipseText(im, sc);
8154 ome.units.quantity.Length fl = meta.getEllipseFontSize(im, sc);
8155 if (fl != null)
8156 an.fontSize = fl.value().intValue();
8157 an.family = meta.getPointFontFamily(im, sc).name();
8158 ome.xml.model.primitives.Color col = meta.getEllipseStrokeColor(im, sc);
8159 if (col != null)
8160 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8161 ome.units.quantity.Length fw = meta.getEllipseStrokeWidth(im, sc);
8162 if (fw != null)
8163 an.strokeWidth = (float)fw.value().floatValue();
8164 ome.xml.model.primitives.Color colf = meta.getEllipseFillColor(im, sc);
8165 if (colf != null)
8166 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8167 }
8168 else
8169 if (type == "Polygon")
8170 {
8171 an.type = ROI.Type.Polygon;
8172 an.id = meta.getPolygonID(im, sc);
8173 an.closed = true;
8174 string pxs = meta.getPolygonPoints(im, sc);
8175 PointD[] pts = an.stringToPoints(pxs);
8176 pts = ToStageSpace(pts, physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y);
8177 if (pts.Length > 100)
8178 {
8179 an.type = ROI.Type.Freeform;
8180 }
8181 an.AddPoints(pts);
8182 ome.xml.model.primitives.NonNegativeInteger nz = meta.getPolygonTheZ(im, sc);
8183 if (nz != null)
8184 co.Z = nz.getNumberValue().intValue();
8185 ome.xml.model.primitives.NonNegativeInteger nc = meta.getPolygonTheC(im, sc);
8186 if (nc != null)
8187 co.C = nc.getNumberValue().intValue();
8188 ome.xml.model.primitives.NonNegativeInteger nt = meta.getPolygonTheT(im, sc);
8189 if (nt != null)
8190 co.T = nt.getNumberValue().intValue();
8191 an.coord = co;
8192 an.Text = meta.getPolygonText(im, sc);
8193 ome.units.quantity.Length fl = meta.getPolygonFontSize(im, sc);
8194 if (fl != null)
8195 an.fontSize = fl.value().intValue();
8196 an.family = meta.getPointFontFamily(im, sc).name();
8197 ome.xml.model.primitives.Color col = meta.getPolygonStrokeColor(im, sc);
8198 if (col != null)
8199 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8200 ome.units.quantity.Length fw = meta.getPolygonStrokeWidth(im, sc);
8201 if (fw != null)
8202 an.strokeWidth = (float)fw.value().floatValue();
8203 ome.xml.model.primitives.Color colf = meta.getPolygonFillColor(im, sc);
8204 if (colf != null)
8205 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8206 }
8207 else
8208 if (type == "Polyline")
8209 {
8210 an.type = ROI.Type.Polyline;
8211 an.id = meta.getPolylineID(im, sc);
8212 string pxs = meta.getPolylinePoints(im, sc);
8213 PointD[] pts = an.stringToPoints(pxs);
8214 for (int pi = 0; pi < pts.Length; pi++)
8215 {
8216 pts[pi] = ToStageSpace(pts[pi], physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y);
8217 }
8218 an.AddPoints(an.stringToPoints(pxs));
8219 ome.xml.model.primitives.NonNegativeInteger nz = meta.getPolylineTheZ(im, sc);
8220 if (nz != null)
8221 co.Z = nz.getNumberValue().intValue();
8222 ome.xml.model.primitives.NonNegativeInteger nc = meta.getPolylineTheC(im, sc);
8223 if (nc != null)
8224 co.C = nc.getNumberValue().intValue();
8225 ome.xml.model.primitives.NonNegativeInteger nt = meta.getPolylineTheT(im, sc);
8226 if (nt != null)
8227 co.T = nt.getNumberValue().intValue();
8228 an.coord = co;
8229 an.Text = meta.getPolylineText(im, sc);
8230 ome.units.quantity.Length fl = meta.getPolylineFontSize(im, sc);
8231 if (fl != null)
8232 an.fontSize = fl.value().intValue();
8233 an.family = meta.getPointFontFamily(im, sc).name();
8234 ome.xml.model.primitives.Color col = meta.getPolylineStrokeColor(im, sc);
8235 if (col != null)
8236 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8237 ome.units.quantity.Length fw = meta.getPolylineStrokeWidth(im, sc);
8238 if (fw != null)
8239 an.strokeWidth = (float)fw.value().floatValue();
8240 ome.xml.model.primitives.Color colf = meta.getPolylineFillColor(im, sc);
8241 if (colf != null)
8242 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8243 }
8244 else
8245 if (type == "Label")
8246 {
8247 an.type = ROI.Type.Label;
8248 an.id = meta.getLabelID(im, sc);
8249
8250 ome.xml.model.primitives.NonNegativeInteger nz = meta.getLabelTheZ(im, sc);
8251 if (nz != null)
8252 co.Z = nz.getNumberValue().intValue();
8253 ome.xml.model.primitives.NonNegativeInteger nc = meta.getLabelTheC(im, sc);
8254 if (nc != null)
8255 co.C = nc.getNumberValue().intValue();
8256 ome.xml.model.primitives.NonNegativeInteger nt = meta.getLabelTheT(im, sc);
8257 if (nt != null)
8258 co.T = nt.getNumberValue().intValue();
8259 an.coord = co;
8260
8261 ome.units.quantity.Length fl = meta.getLabelFontSize(im, sc);
8262 if (fl != null)
8263 an.fontSize = fl.value().intValue();
8264 an.family = meta.getPointFontFamily(im, sc).name();
8265 ome.xml.model.primitives.Color col = meta.getLabelStrokeColor(im, sc);
8266 if (col != null)
8267 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8268 ome.units.quantity.Length fw = meta.getLabelStrokeWidth(im, sc);
8269 if (fw != null)
8270 an.strokeWidth = (float)fw.value().floatValue();
8271 ome.xml.model.primitives.Color colf = meta.getLabelFillColor(im, sc);
8272 if (colf != null)
8273 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8274 PointD p = new PointD(meta.getLabelX(im, sc).doubleValue(), meta.getLabelY(im, sc).doubleValue());
8275 an.AddPoint(ToStageSpace(p, physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y));
8276 an.Text = meta.getLabelText(im, sc);
8277 }
8278 else
8279 if (type == "Mask")
8280 {
8281 byte[] bts = meta.getMaskBinData(im, sc);
8282 bool end = meta.getMaskBinDataBigEndian(im, sc).booleanValue();
8283 an = ROI.CreateMask(co, bts, (int)(an.W * physicalSizeX), (int)(an.H * physicalSizeY), new PointD(stageSizeX, stageSizeY), physicalSizeX, physicalSizeY);
8284 an.Text = meta.getMaskText(im, sc);
8285 an.id = meta.getMaskID(im, sc);
8286 ome.xml.model.primitives.NonNegativeInteger nz = meta.getMaskTheZ(im, sc);
8287 if (nz != null)
8288 co.Z = nz.getNumberValue().intValue();
8289 ome.xml.model.primitives.NonNegativeInteger nc = meta.getMaskTheC(im, sc);
8290 if (nc != null)
8291 co.C = nc.getNumberValue().intValue();
8292 ome.xml.model.primitives.NonNegativeInteger nt = meta.getMaskTheT(im, sc);
8293 if (nt != null)
8294 co.T = nt.getNumberValue().intValue();
8295 an.coord = co;
8296
8297 ome.units.quantity.Length fl = meta.getMaskFontSize(im, sc);
8298 if (fl != null)
8299 an.fontSize = fl.value().intValue();
8300 ome.xml.model.enums.FontFamily ff = meta.getMaskFontFamily(im, sc);
8301 if (ff != null)
8302 an.family = ff.name();
8303 ome.xml.model.primitives.Color col = meta.getMaskStrokeColor(im, sc);
8304 if (col != null)
8305 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8306 ome.units.quantity.Length fw = meta.getMaskStrokeWidth(im, sc);
8307 if (fw != null)
8308 an.strokeWidth = (float)fw.value().floatValue();
8309 ome.xml.model.primitives.Color colf = meta.getMaskFillColor(im, sc);
8310 if (colf != null)
8311 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8312 }
8313 }
8314 }
8315
8316 imageReader.close();
8317 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, file, series);
8318 return Annotations;
8319 }

◆ OpenOMESeries()

static BioImage[] BioLib.BioImage.OpenOMESeries ( string file,
bool tab,
bool addToImages )
static

It opens a file, checks if it's tiled, if it is, it opens it as a tiled image, if not, it opens it as a normal image.

Parameters
filethe file path
tabopen in new tab
addToImagesadd to images list.
Returns
An array of BioImage objects.
7497 {
7498 //We wait incase OME has not initialized yet.
7499 if (!initialized)
7500 do
7501 {
7502 Thread.Sleep(100);
7503 //Application.DoEvents();
7504 } while (!Initialized);
7505 var meta = (IMetadata)((OMEXMLService)new ServiceFactory().getInstance(typeof(OMEXMLService))).createOMEXMLMetadata();
7506 reader.setMetadataStore((MetadataStore)meta);
7507 file = file.Replace("\\", "/");
7508 try
7509 {
7510 if (reader.getCurrentFile() != file)
7511 {
7512 Status = "Opening OME Image: " + file;
7513 file = file.Replace("\\", "/");
7514 reader.setId(file);
7515 }
7516 }
7517 catch (Exception e)
7518 {
7519 return null;
7520 }
7521 int count = reader.getSeriesCount();
7522 BioImage[] bs = new BioImage[count];
7523 for (int i = 0; i < count; i++)
7524 {
7525 bs[i] = OpenOME(file, i, tab, addToImages, false, 0, 0, 0, 0);
7526 if (bs[i] == null)
7527 return null;
7528 }
7529 return bs;
7530 }

◆ OpenSeries()

static BioImage[] BioLib.BioImage.OpenSeries ( string file,
bool tab )
static

It opens a tiff file, reads the number of pages, reads the number of channels, and then reads each page into a BioImage object.

Parameters
filethe path to the file
tabopen image in new tab.
Returns
An array of BioImage objects.
4768 {
4769 Tiff image = Tiff.Open(file, "r");
4770 int pages = image.NumberOfDirectories();
4771 FieldValue[] f = image.GetField(TiffTag.IMAGEDESCRIPTION);
4772 int sp = image.GetField(TiffTag.SAMPLESPERPIXEL)[0].ToInt();
4773 ImageJDesc imDesc = new ImageJDesc();
4774 int count = 1;
4775 if (f != null)
4776 {
4777 string desc = f[0].ToString();
4778 if (desc.StartsWith("ImageJ"))
4779 {
4780 imDesc.SetString(desc);
4781 if (imDesc.channels != 0)
4782 count = imDesc.channels;
4783 }
4784 }
4785 int scount = (pages * sp) / count;
4786 BioImage[] bs = new BioImage[pages];
4787 image.Close();
4788 for (int i = 0; i < pages; i++)
4789 {
4790 bs[i] = OpenFile(file, i, tab, true);
4791 }
4792 return bs;
4793 }

◆ OpenVips()

static void BioLib.BioImage.OpenVips ( BioImage b)
static

The function "OpenVips" takes a BioImage object and an integer representing the number of pages, and adds each page of the image file to the BioImage's vipPages list using the NetVips library.

Parameters
BioImageThe BioImage parameter is an object that represents a bio image. It likely contains information about the image file, such as the file path and other metadata.
pagecountThe parameter "pagecount" represents the number of pages in the TIFF file that needs to be loaded into the "vipPages" list of the "BioImage" object.
6255 {
6256 try
6257 {
6258 List<NetVips.Image> ims = new List<NetVips.Image>();
6259 for (int i = 0; i < b.seriesCount; i++)
6260 {
6261 b.vipPages.Add(NetVips.Image.Tiffload(b.file, i));
6262 }
6263 b.vipPages = SortImagesBySizeDescending(b.vipPages.ToArray()).ToList();
6264 }
6265 catch (Exception e)
6266 {
6267 Console.WriteLine(e.Message);
6268 }
6269
6270 }

◆ OpenXML()

static string BioLib.BioImage.OpenXML ( string file)
static

‍Open the file, get the image description field, and return it as a string

Parameters
filethe path to the file
Returns
The image description of the tiff file.
7927 {
7928 if (!file.EndsWith(".tif"))
7929 return null;
7930 Tiff image = Tiff.Open(file, "r");
7931 FieldValue[] f = image.GetField(TiffTag.IMAGEDESCRIPTION);
7932 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, file);
7933 return f[0].ToString();
7934 }

◆ operator*() [1/2]

static BioImage BioLib.BioImage.operator* ( BioImage a,
ColorS b )
static

This function takes a BioImage object and a ColorS object and returns a BioImage object.

Parameters
BioImagea class that contains a list of ColorS objects.
ColorSa struct that contains a byte for each color channel (R, G, B, A)
Returns
A BioImage object
8859 {
8860 for (int i = 0; i < a.Buffers.Count; i++)
8861 {
8862 a.Buffers[i] = a.Buffers[i] * b;
8863 }
8864 return a;
8865 }

◆ operator*() [2/2]

static BioImage BioLib.BioImage.operator* ( BioImage a,
float b )
static
8801 {
8802 for (int i = 0; i < a.Buffers.Count; i++)
8803 {
8804 a.Buffers[i] = a.Buffers[i] / b;
8805 }
8806 return a;
8807 }

◆ operator+() [1/2]

static BioImage BioLib.BioImage.operator+ ( BioImage a,
ColorS b )
static

It takes a BioImage object and a ColorS object and adds the ColorS object to each buffer in the BioImage object.

Parameters
BioImagea class that contains a list of ColorS objects.
ColorSa struct that contains a byte for each color channel (R, G, B, A)
Returns
A BioImage object
8874 {
8875 for (int i = 0; i < a.Buffers.Count; i++)
8876 {
8877 a.Buffers[i] = a.Buffers[i] + b;
8878 }
8879 return a;
8880 }

◆ operator+() [2/2]

static BioImage BioLib.BioImage.operator+ ( BioImage a,
float b )
static

This function adds a constant value to each pixel in the image.

Parameters
BioImagea class that contains a list of buffers (float[])
bthe value to add to the image
Returns
The image itself.
8815 {
8816 for (int i = 0; i < a.Buffers.Count; i++)
8817 {
8818 a.Buffers[i] = a.Buffers[i] + b;
8819 }
8820 return a;
8821 }

◆ operator-() [1/2]

static BioImage BioLib.BioImage.operator- ( BioImage a,
ColorS b )
static

The function subtracts a color from each pixel in the image.

Parameters
BioImagea class that contains a list of ColorS objects.
ColorSa struct that contains a byte for each color channel (R, G, B, A)
Returns
The image itself.
8888 {
8889 for (int i = 0; i < a.Buffers.Count; i++)
8890 {
8891 a.Buffers[i] = a.Buffers[i] - b;
8892 }
8893 return a;
8894 }

◆ operator-() [2/2]

static BioImage BioLib.BioImage.operator- ( BioImage a,
float b )
static

Subtracts a scalar value from each pixel in the image.

Parameters
BioImagea class that contains a list of buffers (which are 2D arrays of floats)
bthe value to subtract from the image
Returns
The BioImage object is being returned.
8829 {
8830 for (int i = 0; i < a.Buffers.Count; i++)
8831 {
8832 a.Buffers[i] = a.Buffers[i] - b;
8833 }
8834 return a;
8835 }

◆ operator/() [1/2]

static BioImage BioLib.BioImage.operator/ ( BioImage a,
ColorS b )
static

This function divides each pixel in the image by the value of the color.

Parameters
BioImagea class that contains a list of ColorS objects.
ColorSa struct that contains a byte for each color channel (R, G, B, A)
Returns
A BioImage object.
8845 {
8846 for (int i = 0; i < a.Buffers.Count; i++)
8847 {
8848 a.Buffers[i] = a.Buffers[i] / b;
8849 }
8850 return a;
8851 }

◆ operator/() [2/2]

static BioImage BioLib.BioImage.operator/ ( BioImage a,
float b )
static

This function divides each pixel in the image by a constant value.

Parameters
BioImagea class that contains a list of buffers (which are 2D arrays of floats)
bthe value to divide by
Returns
The image is being returned.
8793 {
8794 for (int i = 0; i < a.Buffers.Count; i++)
8795 {
8796 a.Buffers[i] = a.Buffers[i] / b;
8797 }
8798 return a;
8799 }

◆ Rename()

void BioLib.BioImage.Rename ( string name)
7760 {
7761 this.Filename = Path.GetFileName(name);
7762 this.ID = name;
7763 }

◆ ROIsToString()

static string BioLib.BioImage.ROIsToString ( List< ROI > Annotations)
static

It takes a list of ROI objects and returns a string of all the ROI objects in the list.

Parameters
AnnotationsList of ROI objects
Returns
A string of the ROI's
8326 {
8327 string s = "";
8328 for (int i = 0; i < Annotations.Count; i++)
8329 {
8330 s += ROIToString(Annotations[i]);
8331 }
8332 return s;
8333 }
static string ROIToString(ROI an)
This function takes an ROI object and returns a string that contains all the information about the RO...
Definition Bio.cs:8340

◆ ROIToString()

static string BioLib.BioImage.ROIToString ( ROI an)
static

This function takes an ROI object and returns a string that contains all the information about the ROI.

Parameters
ROIThe ROI object
Returns
A string
8341 {
8342 PointD[] points = an.GetPoints();
8343 string pts = "";
8344 for (int j = 0; j < points.Length; j++)
8345 {
8346 if (j == points.Length - 1)
8347 pts += points[j].X.ToString(CultureInfo.InvariantCulture) + "," + points[j].Y.ToString(CultureInfo.InvariantCulture);
8348 else
8349 pts += points[j].X.ToString(CultureInfo.InvariantCulture) + "," + points[j].Y.ToString(CultureInfo.InvariantCulture) + " ";
8350 }
8351 char sep = (char)34;
8352 string sColor = sep.ToString() + an.strokeColor.A.ToString() + ',' + an.strokeColor.R.ToString() + ',' + an.strokeColor.G.ToString() + ',' + an.strokeColor.B.ToString() + sep.ToString();
8353 string bColor = sep.ToString() + an.fillColor.A.ToString() + ',' + an.fillColor.R.ToString() + ',' + an.fillColor.G.ToString() + ',' + an.fillColor.B.ToString() + sep.ToString();
8354
8355 string line = an.roiID + ',' + an.roiName + ',' + an.type.ToString() + ',' + an.id + ',' + an.shapeIndex.ToString() + ',' +
8356 an.Text + ',' + an.serie + ',' + an.coord.Z.ToString() + ',' + an.coord.C.ToString() + ',' + an.coord.T.ToString() + ',' + an.X.ToString(CultureInfo.InvariantCulture) + ',' + an.Y.ToString(CultureInfo.InvariantCulture) + ',' +
8357 an.W.ToString(CultureInfo.InvariantCulture) + ',' + an.H.ToString(CultureInfo.InvariantCulture) + ',' + sep.ToString() + pts + sep.ToString() + ',' + sColor + ',' + an.strokeWidth.ToString(CultureInfo.InvariantCulture) + ',' + bColor + ',' + an.fontSize.ToString(CultureInfo.InvariantCulture) + ',' + NewLine;
8358 return line;
8359 }
PointD[] GetPoints()
Definition ROI.cs:1291

◆ RotateFlip()

void BioLib.BioImage.RotateFlip ( AForge.RotateFlipType rot)
3071 {
3072 for (int i = 0; i < Buffers.Count; i++)
3073 {
3074 Buffers[i].RotateFlip(rot);
3075 }
3076 Volume = new VolumeD(new Point3D(StageSizeX, StageSizeY, StageSizeZ), new Point3D(PhysicalSizeX * SizeX, PhysicalSizeY * SizeY, PhysicalSizeZ * SizeZ));
3077 }

◆ SaveAsync()

static async Task BioLib.BioImage.SaveAsync ( string file,
string id,
int serie,
bool ome )
static

The SaveAsync function saves data to a file asynchronously.

Parameters
fileThe file parameter is a string that represents the file path or name where the data will be saved.
idThe "id" parameter is a string that represents an identifier for the save operation. It could be used to uniquely identify the saved data or to specify a specific location or format for the saved file.
serieThe "serie" parameter is an integer that represents a series or sequence number. It is used as a parameter in the SaveAsync method.
omeThe "ome" parameter is a boolean value that determines whether or not to perform a specific action in the saving process.
7797 {
7798 savefile = file;
7799 saveid = id;
7800 some = ome;
7801 await Task.Run(SaveThread);
7802 }

◆ SaveFile()

static void BioLib.BioImage.SaveFile ( string file,
string ID )
static

This function takes a string array of file names and a string ID and saves the files to the database.

Parameters
fileThe file path to the file you want to save.
IDThe ID of the series you want to save.
4656 {
4657 string[] sts = new string[1];
4658 sts[0] = ID;
4659 SaveSeries(sts, file);
4660 }
static void SaveSeries(string[] IDs, string file)
It takes a list of image IDs, and saves them as a single multi-page TIFF file.
Definition Bio.cs:4665

◆ SaveOME() [1/2]

static void BioLib.BioImage.SaveOME ( BioImage image,
string file )
static
5334 {
5335 BioImage[] sts = new BioImage[1];
5336 sts[0] = image;
5337 SaveOMESeries(sts, file, BioImage.Planes);
5338 }
static void SaveOMESeries(BioImage[] files, string f, bool planes)
This function takes a list of image files and saves them as a single OME-TIFF file.
Definition Bio.cs:5356

◆ SaveOME() [2/2]

static void BioLib.BioImage.SaveOME ( string file,
string ID )
static
5327 {
5328 BioImage[] sts = new BioImage[1];
5329 sts[0] = Images.GetImage(ID);
5330 SaveOMESeries(sts, file, BioImage.Planes);
5331 }

◆ SaveOMEPyramidal()

static void BioLib.BioImage.SaveOMEPyramidal ( BioImage[] bms,
string file,
Enums.ForeignTiffCompression compression,
int compressionLevel )
static

The function SaveOMEPyramidal saves a collection of BioImages as a pyramidal OME-TIFF file.

Parameters
bmsAn array of BioImage objects representing the images to be saved.
fileThe file parameter is a string that represents the file path where the OME Pyramidal TIFF file will be saved.
compressionThe compression parameter is of type Enums.ForeignTiffCompression and it specifies the compression method to be used when saving the TIFF file.
5809 {
5810 if (File.Exists(file))
5811 File.Delete(file);
5812 Status = "Saving OME Pyramidal";
5813 //We need to go through the images and find the ones belonging to each resolution.
5814 //As well we need to determine the dimensions of the tiles.
5815 Dictionary<double, List<BioImage>> bis = new Dictionary<double, List<BioImage>>();
5816 Dictionary<double, Point3D> min = new Dictionary<double, Point3D>();
5817 Dictionary<double, Point3D> max = new Dictionary<double, Point3D>();
5818 for (int i = 0; i < bms.Length; i++)
5819 {
5820 Resolution res = bms[i].Resolutions[bms[i].Level];
5821 if (bis.ContainsKey(res.PhysicalSizeX))
5822 {
5823 bis[res.PhysicalSizeX].Add(bms[i]);
5824 if (bms[i].StageSizeX < min[res.PhysicalSizeX].X || bms[i].StageSizeY < min[res.PhysicalSizeX].Y)
5825 {
5826 min[res.PhysicalSizeX] = bms[i].Volume.Location;
5827 }
5828 if (bms[i].StageSizeX > max[res.PhysicalSizeX].X || bms[i].StageSizeY > max[res.PhysicalSizeX].Y)
5829 {
5830 max[res.PhysicalSizeX] = bms[i].Volume.Location;
5831 }
5832 }
5833 else
5834 {
5835 bis.Add(res.PhysicalSizeX, new List<BioImage>());
5836 min.Add(res.PhysicalSizeX, new Point3D(double.MaxValue, double.MaxValue, double.MaxValue));
5837 max.Add(res.PhysicalSizeX, new Point3D(double.MinValue, double.MinValue, double.MinValue));
5838 if (bms[i].StageSizeX < min[res.PhysicalSizeX].X || bms[i].StageSizeY < min[res.PhysicalSizeX].Y)
5839 {
5840 min[res.PhysicalSizeX] = bms[i].Volume.Location;
5841 }
5842 if (bms[i].StageSizeX > max[res.PhysicalSizeX].X || bms[i].StageSizeY > max[res.PhysicalSizeX].Y)
5843 {
5844 max[res.PhysicalSizeX] = bms[i].Volume.Location;
5845 }
5846 bis[res.PhysicalSizeX].Add(bms[i]);
5847 }
5848 }
5849 int s = 0;
5850 //We determine the sizes of each resolution.
5851 Dictionary<double, AForge.Size> ss = new Dictionary<double, AForge.Size>();
5852 int minx = int.MaxValue;
5853 int miny = int.MaxValue;
5854 double last = 0;
5855 foreach (double px in bis.Keys)
5856 {
5857 int xs = (1 + (int)Math.Ceiling((max[px].X - min[px].X) / bis[px][0].Resolutions[0].VolumeWidth)) * bis[px][0].SizeX;
5858 int ys = (1 + (int)Math.Ceiling((max[px].Y - min[px].Y) / bis[px][0].Resolutions[0].VolumeHeight)) * bis[px][0].SizeY;
5859 if (minx > xs)
5860 minx = xs;
5861 if (miny > ys)
5862 miny = ys;
5863 ss.Add(px, new AForge.Size(xs, ys));
5864 last = px;
5865 }
5866 s = 0;
5867 string met = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +
5868 "<OME xmlns=\"http://www.openmicroscopy.org/Schemas/OME/2016-06\" " +
5869 "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
5870 "xsi:schemaLocation=\"http://www.openmicroscopy.org/Schemas/OME/2016-06 http://www.openmicroscopy.org/Schemas/OME/2016-06/ome.xsd\">";
5871 NetVips.Image img = null;
5872 int ib = 0;
5873
5874 foreach (double px in bis.Keys)
5875 {
5876 int c = bis[px][s].SizeC;
5877 if (bis[px][s].Buffers[0].isRGB)
5878 c = 3;
5879 string endian = (bis[px][s].Buffers[0].LittleEndian).ToString().ToLower();
5880 met +=
5881 "<Image ID=\"Image:" + ib + "\">" +
5882 "<Pixels BigEndian=\"" + endian + "\" DimensionOrder= \"XYCZT\" ID= \"Pixels:0\" Interleaved=\"true\" " +
5883 "PhysicalSizeX=\"" + bis[px][s].PhysicalSizeX + "\" PhysicalSizeXUnit=\"µm\" PhysicalSizeY=\"" + bis[px][s].PhysicalSizeY + "\" PhysicalSizeYUnit=\"µm\" SignificantBits=\"" + bis[px][s].bitsPerPixel + "\" " +
5884 "SizeC = \"" + c + "\" SizeT = \"" + bis[px][s].SizeT + "\" SizeX =\"" + ss[px].Width +
5885 "\" SizeY= \"" + ss[px].Height + "\" SizeZ=\"" + bis[px][s].SizeZ;
5886 if (bis[px][s].bitsPerPixel > 8) met += "\" Type= \"uint16\">";
5887 else met += "\" Type= \"uint8\">";
5888 int i = 0;
5889 foreach (Channel ch in bis[px][s].Channels)
5890 {
5891 met += "<Channel ID=\"Channel:" + ib + ":" + i + "\" SamplesPerPixel=\"1\"></Channel>";
5892 i++;
5893 }
5894 met += "</Pixels></Image>";
5895 ib++;
5896 }
5897 met += "</OME>";
5898 foreach (double px in bis.Keys)
5899 {
5900 PixelFormat pf = bis[px][0].Buffers[0].PixelFormat;
5901 Bitmap level = new Bitmap(ss[px].Width, ss[px].Height, pf);
5902 int bands = GetBands(pf);
5903 if (bis[px][0].bitsPerPixel > 8)
5904 img = NetVips.Image.NewFromMemory(level.Data, (ulong)level.Length, level.Width, level.Height, bands, Enums.BandFormat.Ushort);
5905 else
5906 img = NetVips.Image.NewFromMemory(level.Data, (ulong)level.Length, level.Width, level.Height, bands, Enums.BandFormat.Uchar);
5907 int i = 0;
5908 foreach (BioImage b in bis[px])
5909 {
5910 Progress = ((float)i / (float)bis[px].Count) * 100;
5911 AForge.Size si = ss[px];
5912 double xs = (-(min[px].X - bis[px][i].Volume.Location.X) / bis[px][i].Resolutions[0].VolumeWidth) * bis[px][i].SizeX;
5913 double ys = (-(min[px].Y - bis[px][i].Volume.Location.Y) / bis[px][i].Resolutions[0].VolumeHeight) * bis[px][i].SizeY;
5914 NetVips.Image tile;
5915 if (b.bitsPerPixel > 8)
5916 tile = NetVips.Image.NewFromMemory(bis[px][i].Buffers[0].Data, (ulong)bis[px][i].Buffers[0].Length, bis[px][i].Buffers[0].Width, bis[px][i].Buffers[0].Height, bands, Enums.BandFormat.Ushort);
5917 else
5918 tile = NetVips.Image.NewFromMemory(bis[px][i].Buffers[0].Data, (ulong)bis[px][i].Buffers[0].Length, bis[px][i].Buffers[0].Width, bis[px][i].Buffers[0].Height, bands, Enums.BandFormat.Uchar);
5919 img = img.Insert(tile, (int)xs, (int)ys);
5920 i++;
5921 };
5922 using var mutated = img.Mutate(mutable =>
5923 {
5924 // Set the ImageDescription tag
5925 mutable.Set(GValue.GStrType, "image-description", met);
5926 mutable.Set(GValue.GIntType, "page-height", ss[last].Height);
5927 });
5928 if (bis[px][0].bitsPerPixel > 8)
5929 mutated.Tiffsave(file, compression, 1, Enums.ForeignTiffPredictor.None, true, ss[px].Width, ss[px].Height, true, false, 16,
5930 Enums.ForeignTiffResunit.Cm, 1000 * bis[px][0].PhysicalSizeX, 1000 * bis[px][0].PhysicalSizeY, true, null, Enums.RegionShrink.Nearest,
5931 compressionLevel, true, Enums.ForeignDzDepth.One, true, false, null, null, ss[px].Height);
5932 else
5933 mutated.Tiffsave(file, compression, 1, Enums.ForeignTiffPredictor.None, true, ss[px].Width, ss[px].Height, true, false, 8,
5934 Enums.ForeignTiffResunit.Cm, 1000 * bis[px][0].PhysicalSizeX, 1000 * bis[px][0].PhysicalSizeY, true, null, Enums.RegionShrink.Nearest,
5935 compressionLevel, true, Enums.ForeignDzDepth.One, true, false, null, null, ss[px].Height);
5936 s++;
5937 }
5938
5939 }
static int GetBands(PixelFormat format)
The function "GetBands" returns the number of color bands for a given pixel format in the AForge libr...
Definition Bio.cs:5781

◆ SaveOMESeries()

static void BioLib.BioImage.SaveOMESeries ( BioImage[] files,
string f,
bool planes )
static

This function takes a list of image files and saves them as a single OME-TIFF file.

Parameters
filesan array of file paths to the images to be saved
fthe file name to save to
planesif true, the planes will be saved as well.
5357 {
5358 if (File.Exists(f))
5359 File.Delete(f);
5360
5361 // helper to ensure strictly positive physical lengths
5362 double SafePositive(double v) => (v > 0.0 && !double.IsNaN(v)) ? v : 1.0;
5363
5364 // Create a single metadata store for all series
5365 loci.formats.meta.IMetadata omexml = service.createOMEXMLMetadata();
5366 Status = "Saving OME Image Metadata.";
5367
5368 // Create one Instrument + one LightSource (must exist and have IDs)
5369 string instrumentID = "Instrument:0";
5370 string lightSourceID = "LightSource:0";
5371 omexml.setInstrumentID(instrumentID, 0);
5372 omexml.setLightEmittingDiodeID(lightSourceID, 0, 0); // Fixed: use 0 instead of undefined 'serie'
5373 omexml.setLightEmittingDiodeModel("ModelName", 0, 0); // Fixed: use 0 instead of undefined 'serie'
5374
5375 // Build metadata for each series
5376 for (int serie = 0; serie < files.Length; serie++)
5377 {
5378 BioImage b = files[serie];
5379
5380 // Required Image / Pixels IDs
5381 omexml.setImageID($"Image:{serie}", serie);
5382 omexml.setPixelsID($"Pixels:{serie}", serie);
5383
5384 // Pixel layout and type
5385 omexml.setPixelsDimensionOrder(ome.xml.model.enums.DimensionOrder.XYCZT, serie);
5386 omexml.setPixelsInterleaved(java.lang.Boolean.TRUE, serie);
5387 if (b.bitsPerPixel > 8)
5388 omexml.setPixelsType(ome.xml.model.enums.PixelType.UINT16, serie);
5389 else
5390 omexml.setPixelsType(ome.xml.model.enums.PixelType.UINT8, serie);
5391
5392 // Sizes (must be PositiveInteger)
5393 omexml.setPixelsSizeX(new ome.xml.model.primitives.PositiveInteger(java.lang.Integer.valueOf(b.SizeX)), serie);
5394 omexml.setPixelsSizeY(new ome.xml.model.primitives.PositiveInteger(java.lang.Integer.valueOf(b.SizeY)), serie);
5395 omexml.setPixelsSizeZ(new ome.xml.model.primitives.PositiveInteger(java.lang.Integer.valueOf(b.SizeZ)), serie);
5396 omexml.setPixelsSizeC(new ome.xml.model.primitives.PositiveInteger(java.lang.Integer.valueOf(b.SizeC)), serie);
5397 omexml.setPixelsSizeT(new ome.xml.model.primitives.PositiveInteger(java.lang.Integer.valueOf(b.SizeT)), serie);
5398
5399 // Endianness
5400 omexml.setPixelsBigEndian(java.lang.Boolean.valueOf(!BitConverter.IsLittleEndian), serie);
5401
5402 // Physical sizes (must be > 0)
5403 omexml.setPixelsPhysicalSizeX(new ome.units.quantity.Length(java.lang.Double.valueOf(SafePositive(b.PhysicalSizeX)), ome.units.UNITS.MICROMETER), serie);
5404 omexml.setPixelsPhysicalSizeY(new ome.units.quantity.Length(java.lang.Double.valueOf(SafePositive(b.PhysicalSizeY)), ome.units.UNITS.MICROMETER), serie);
5405 double psz = (b.PhysicalSizeZ == 0.0 ? 1.0 : b.PhysicalSizeZ);
5406 omexml.setPixelsPhysicalSizeZ(new ome.units.quantity.Length(java.lang.Double.valueOf(SafePositive(psz)), ome.units.UNITS.MICROMETER), serie);
5407
5408 // Stage label / positions
5409 omexml.setStageLabelName($"StageLabel:{serie}", serie);
5410 omexml.setStageLabelX(new ome.units.quantity.Length(java.lang.Double.valueOf(b.Volume.Location.X), ome.units.UNITS.MICROMETER), serie);
5411 omexml.setStageLabelY(new ome.units.quantity.Length(java.lang.Double.valueOf(b.Volume.Location.Y), ome.units.UNITS.MICROMETER), serie);
5412 omexml.setStageLabelZ(new ome.units.quantity.Length(java.lang.Double.valueOf(b.Volume.Location.Z), ome.units.UNITS.MICROMETER), serie);
5413
5414 // Ensure Image references the Instrument - MOVED INSIDE LOOP
5415 omexml.setImageInstrumentRef(instrumentID, serie);
5416
5417 // Build channel list (split RGB-packed channel into three if needed)
5418 List<Channel> chs = new List<Channel>();
5419 if (b.Channels.Count == 1 && b.Channels[0].range.Length == 3)
5420 {
5421 for (int cind = 0; cind < 3; cind++)
5422 {
5423 Channel ch = b.Channels[0].Copy();
5424 ch.SamplesPerPixel = 1;
5425 ch.range = new IntRange[] { b.Channels[0].range[cind] };
5426 chs.Add(ch);
5427 }
5428 }
5429 else
5430 {
5431 chs.AddRange(b.Channels);
5432 }
5433
5434 // Channels metadata — channel index is c, image index is serie
5435 for (int c = 0; c < chs.Count; c++)
5436 {
5437 Channel ch = chs[c];
5438
5439 string channelId = $"Channel:{c}:{serie}";
5440 omexml.setChannelID(channelId, serie, c); // Fixed: swapped parameters - should be (id, imageIndex, channelIndex)
5441
5442 // Samples per pixel: if unknown default to 1
5443 int spp = (ch.range != null && ch.range.Length > 0) ? ch.range.Length : 1;
5444 omexml.setChannelSamplesPerPixel(new ome.xml.model.primitives.PositiveInteger(java.lang.Integer.valueOf(spp)), serie, c);
5445
5446 omexml.setChannelName(ch.Name ?? channelId, serie, c);
5447
5448 // Channel color (nullable)
5449 if (ch.Color != null)
5450 omexml.setChannelColor(new ome.xml.model.primitives.Color(ch.Color.Value.R, ch.Color.Value.G, ch.Color.Value.B, ch.Color.Value.A), serie, c);
5451 else
5452 omexml.setChannelColor(null, serie, c);
5453
5454 // Emission/excitation must be null if zero or absent (can't be 0.0)
5455 if (ch.Emission != 0.0)
5456 omexml.setChannelEmissionWavelength(new ome.units.quantity.Length(java.lang.Double.valueOf(ch.Emission), ome.units.UNITS.NANOMETER), serie, c);
5457 else
5458 omexml.setChannelEmissionWavelength(null, serie, c);
5459
5460 if (ch.Excitation != 0.0)
5461 omexml.setChannelExcitationWavelength(new ome.units.quantity.Length(java.lang.Double.valueOf(ch.Excitation), ome.units.UNITS.NANOMETER), serie, c);
5462 else
5463 omexml.setChannelExcitationWavelength(null, serie, c);
5464
5465 // Fluor
5466 omexml.setChannelFluor(ch.Fluor, serie, c);
5467
5468 // Light source settings
5469 string lightSourceSettingsID = $"LightSourceSettings:{c}:{serie}";
5470 omexml.setChannelLightSourceSettingsID(lightSourceSettingsID, serie, c);
5471 }
5472 int i = 0;
5473 int shapeIndex = 0; // Single unified counter for all shapes
5474 ROI[] d = SortByType(b.Annotations.ToArray());
5475
5476 foreach (ROI an in d)
5477 {
5478 if (an.roiID == "")
5479 omexml.setROIID("ROI:" + i.ToString() + ":" + serie, i);
5480 else
5481 omexml.setROIID(an.roiID, i);
5482 if (an.roiName != "")
5483 omexml.setROIName(an.roiName, i);
5484 else
5485 omexml.setROIName("ROI:" + i.ToString() + ":" + serie, i);
5486 if (an.type == ROI.Type.Point)
5487 {
5488 if (an.id != "")
5489 omexml.setPointID(an.id, shapeIndex, serie);
5490 else
5491 omexml.setPointID("Shape:" + shapeIndex + ":" + serie, shapeIndex, serie);
5492 omexml.setPointX(java.lang.Double.valueOf(b.ToImageSpaceX(an.X)), shapeIndex, serie);
5493 omexml.setPointY(java.lang.Double.valueOf(b.ToImageSpaceY(an.Y)), shapeIndex, serie);
5494 omexml.setPointTheZ(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.Z)), shapeIndex, serie);
5495 omexml.setPointTheC(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.C)), shapeIndex, serie);
5496 omexml.setPointTheT(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.T)), shapeIndex, serie);
5497 if (an.Text != "")
5498 omexml.setPointText(an.Text, shapeIndex, serie);
5499 else
5500 omexml.setPointText(i.ToString(), shapeIndex, serie);
5501 ome.units.quantity.Length fl = new ome.units.quantity.Length(java.lang.Double.valueOf(an.fontSize), ome.units.UNITS.PIXEL);
5502 omexml.setPointFontSize(fl, shapeIndex, serie);
5503 ome.xml.model.primitives.Color col = new ome.xml.model.primitives.Color(an.strokeColor.R, an.strokeColor.G, an.strokeColor.B, an.strokeColor.A);
5504 omexml.setPointStrokeColor(col, shapeIndex, serie);
5505 ome.units.quantity.Length sw = new ome.units.quantity.Length(java.lang.Double.valueOf(an.strokeWidth), ome.units.UNITS.PIXEL);
5506 omexml.setPointStrokeWidth(sw, shapeIndex, serie);
5507 ome.xml.model.primitives.Color colf = new ome.xml.model.primitives.Color(an.fillColor.R, an.fillColor.G, an.fillColor.B, an.fillColor.A);
5508 omexml.setPointFillColor(colf, shapeIndex, serie);
5509 shapeIndex++;
5510 }
5511 else
5512 if (an.type == ROI.Type.Polygon || an.type == ROI.Type.Freeform)
5513 {
5514 if (an.id != "")
5515 omexml.setPolygonID(an.id, shapeIndex, serie);
5516 else
5517 omexml.setPolygonID("Shape:" + shapeIndex + ":" + serie, shapeIndex, serie);
5518 omexml.setPolygonPoints(an.PointsToString(b), shapeIndex, serie);
5519 omexml.setPolygonTheZ(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.Z)), shapeIndex, serie);
5520 omexml.setPolygonTheC(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.C)), shapeIndex, serie);
5521 omexml.setPolygonTheT(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.T)), shapeIndex, serie);
5522 if (an.Text != "")
5523 omexml.setPolygonText(an.Text, shapeIndex, serie);
5524 else
5525 omexml.setPolygonText(shapeIndex.ToString(), shapeIndex, serie);
5526 ome.units.quantity.Length fl = new ome.units.quantity.Length(java.lang.Double.valueOf(an.fontSize), ome.units.UNITS.PIXEL);
5527 omexml.setPolygonFontSize(fl, shapeIndex, serie);
5528 ome.xml.model.primitives.Color col = new ome.xml.model.primitives.Color(an.strokeColor.R, an.strokeColor.G, an.strokeColor.B, an.strokeColor.A);
5529 omexml.setPolygonStrokeColor(col, shapeIndex, serie);
5530 ome.units.quantity.Length sw = new ome.units.quantity.Length(java.lang.Double.valueOf(an.strokeWidth), ome.units.UNITS.PIXEL);
5531 omexml.setPolygonStrokeWidth(sw, shapeIndex, serie);
5532 ome.xml.model.primitives.Color colf = new ome.xml.model.primitives.Color(an.fillColor.R, an.fillColor.G, an.fillColor.B, an.fillColor.A);
5533 omexml.setPolygonFillColor(colf, shapeIndex, serie);
5534 shapeIndex++;
5535 }
5536 else
5537 if (an.type == ROI.Type.Polyline)
5538 {
5539 if (an.id != "")
5540 omexml.setPolylineID(an.id, shapeIndex, serie);
5541 else
5542 omexml.setPolylineID("Shape:" + shapeIndex + ":" + serie, shapeIndex, serie);
5543 omexml.setPolylinePoints(an.PointsToString(b), shapeIndex, serie);
5544 omexml.setPolylineTheZ(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.Z)), shapeIndex, serie);
5545 omexml.setPolylineTheC(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.C)), shapeIndex, serie);
5546 omexml.setPolylineTheT(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.T)), shapeIndex, serie);
5547 if (an.Text != "")
5548 omexml.setPolylineText(an.Text, shapeIndex, serie);
5549 else
5550 omexml.setPolylineText(i.ToString(), shapeIndex, serie);
5551 ome.units.quantity.Length fl = new ome.units.quantity.Length(java.lang.Double.valueOf(an.fontSize), ome.units.UNITS.PIXEL);
5552 omexml.setPolylineFontSize(fl, shapeIndex, serie);
5553 ome.xml.model.primitives.Color col = new ome.xml.model.primitives.Color(an.strokeColor.R, an.strokeColor.G, an.strokeColor.B, an.strokeColor.A);
5554 omexml.setPolylineStrokeColor(col, shapeIndex, serie);
5555 ome.units.quantity.Length sw = new ome.units.quantity.Length(java.lang.Double.valueOf(an.strokeWidth), ome.units.UNITS.PIXEL);
5556 omexml.setPolylineStrokeWidth(sw, shapeIndex, serie);
5557 ome.xml.model.primitives.Color colf = new ome.xml.model.primitives.Color(an.fillColor.R, an.fillColor.G, an.fillColor.B, an.fillColor.A);
5558 omexml.setPolylineFillColor(colf, shapeIndex, serie);
5559 shapeIndex++;
5560 }
5561 else
5562 if (an.type == ROI.Type.Rectangle)
5563 {
5564 if (an.id != "")
5565 omexml.setRectangleID(an.id, shapeIndex, serie);
5566 else
5567 omexml.setRectangleID("Shape:" + shapeIndex + ":" + serie, shapeIndex, serie);
5568 omexml.setRectangleWidth(java.lang.Double.valueOf(b.ToImageSizeX(an.W)), shapeIndex, serie);
5569 omexml.setRectangleHeight(java.lang.Double.valueOf(b.ToImageSizeY(an.H)), shapeIndex, serie);
5570 omexml.setRectangleX(java.lang.Double.valueOf(b.ToImageSpaceX(an.BoundingBox.X)), shapeIndex, serie);
5571 omexml.setRectangleY(java.lang.Double.valueOf(b.ToImageSpaceY(an.BoundingBox.Y)), shapeIndex, serie);
5572 omexml.setRectangleTheZ(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.Z)), shapeIndex, serie);
5573 omexml.setRectangleTheC(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.C)), shapeIndex, serie);
5574 omexml.setRectangleTheT(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.T)), shapeIndex, serie);
5575 if (an.Text != "")
5576 omexml.setRectangleText(an.Text, shapeIndex, serie);
5577 else
5578 omexml.setRectangleText(shapeIndex.ToString(), shapeIndex, serie);
5579 ome.units.quantity.Length fl = new ome.units.quantity.Length(java.lang.Double.valueOf(an.fontSize), ome.units.UNITS.PIXEL);
5580 omexml.setRectangleFontSize(fl, shapeIndex, serie);
5581 ome.xml.model.primitives.Color col = new ome.xml.model.primitives.Color(an.strokeColor.R, an.strokeColor.G, an.strokeColor.B, an.strokeColor.A);
5582 omexml.setRectangleStrokeColor(col, shapeIndex, serie);
5583 ome.units.quantity.Length sw = new ome.units.quantity.Length(java.lang.Double.valueOf(an.strokeWidth), ome.units.UNITS.PIXEL);
5584 omexml.setRectangleStrokeWidth(sw, shapeIndex, serie);
5585 ome.xml.model.primitives.Color colf = new ome.xml.model.primitives.Color(an.fillColor.R, an.fillColor.G, an.fillColor.B, an.fillColor.A);
5586 omexml.setRectangleFillColor(colf, shapeIndex, serie);
5587 shapeIndex++;
5588 }
5589 else
5590 if (an.type == ROI.Type.Line)
5591 {
5592 if (an.id != "")
5593 omexml.setLineID(an.id, shapeIndex, serie);
5594 else
5595 omexml.setLineID("Shape:" + shapeIndex + ":" + serie, shapeIndex, serie);
5596 omexml.setLineX1(java.lang.Double.valueOf(b.ToImageSpaceX(an.GetPoint(0).X)), shapeIndex, serie);
5597 omexml.setLineY1(java.lang.Double.valueOf(b.ToImageSpaceY(an.GetPoint(0).Y)), shapeIndex, serie);
5598 omexml.setLineX2(java.lang.Double.valueOf(b.ToImageSpaceX(an.GetPoint(1).X)), shapeIndex, serie);
5599 omexml.setLineY2(java.lang.Double.valueOf(b.ToImageSpaceY(an.GetPoint(1).Y)), shapeIndex, serie);
5600 omexml.setLineTheZ(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.Z)), shapeIndex, serie);
5601 omexml.setLineTheC(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.C)), shapeIndex, serie);
5602 omexml.setLineTheT(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.T)), shapeIndex, serie);
5603 if (an.Text != "")
5604 omexml.setLineText(an.Text, shapeIndex, serie);
5605 else
5606 omexml.setLineText(shapeIndex.ToString(), shapeIndex, serie);
5607 ome.units.quantity.Length fl = new ome.units.quantity.Length(java.lang.Double.valueOf(an.fontSize), ome.units.UNITS.PIXEL);
5608 omexml.setLineFontSize(fl, shapeIndex, serie);
5609 ome.xml.model.primitives.Color col = new ome.xml.model.primitives.Color(an.strokeColor.R, an.strokeColor.G, an.strokeColor.B, an.strokeColor.A);
5610 omexml.setLineStrokeColor(col, shapeIndex, serie);
5611 ome.units.quantity.Length sw = new ome.units.quantity.Length(java.lang.Double.valueOf(an.strokeWidth), ome.units.UNITS.PIXEL);
5612 omexml.setLineStrokeWidth(sw, shapeIndex, serie);
5613 ome.xml.model.primitives.Color colf = new ome.xml.model.primitives.Color(an.fillColor.R, an.fillColor.G, an.fillColor.B, an.fillColor.A);
5614 omexml.setLineFillColor(colf, shapeIndex, serie);
5615 shapeIndex++;
5616 }
5617 else
5618 if (an.type == ROI.Type.Ellipse)
5619 {
5620
5621 //We need to change System.Drawing.Rectangle to ellipse radius;
5622 double w = (double)an.W / 2;
5623 double h = (double)an.H / 2;
5624 if (an.id != "")
5625 omexml.setEllipseID(an.id, shapeIndex, serie);
5626 else
5627 omexml.setEllipseID("Shape:" + shapeIndex + ":" + serie, shapeIndex, serie);
5628 omexml.setEllipseRadiusX(java.lang.Double.valueOf(b.ToImageSizeX(w)), shapeIndex, serie);
5629 omexml.setEllipseRadiusY(java.lang.Double.valueOf(b.ToImageSizeY(h)), shapeIndex, serie);
5630
5631 double x = an.Points[0].X + w;
5632 double y = an.Points[0].Y + h;
5633 omexml.setEllipseX(java.lang.Double.valueOf(b.ToImageSpaceX(x)), shapeIndex, serie);
5634 omexml.setEllipseY(java.lang.Double.valueOf(b.ToImageSpaceY(y)), shapeIndex, serie);
5635 omexml.setEllipseTheZ(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.Z)), shapeIndex, serie);
5636 omexml.setEllipseTheC(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.C)), shapeIndex, serie);
5637 omexml.setEllipseTheT(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.T)), shapeIndex, serie);
5638 if (an.Text != "")
5639 omexml.setEllipseText(an.Text, shapeIndex, serie);
5640 else
5641 omexml.setEllipseText(i.ToString(), shapeIndex, serie);
5642 ome.units.quantity.Length fl = new ome.units.quantity.Length(java.lang.Double.valueOf(an.fontSize), ome.units.UNITS.PIXEL);
5643 omexml.setEllipseFontSize(fl, shapeIndex, serie);
5644 ome.xml.model.primitives.Color col = new ome.xml.model.primitives.Color(an.strokeColor.R, an.strokeColor.G, an.strokeColor.B, an.strokeColor.A);
5645 omexml.setEllipseStrokeColor(col, shapeIndex, serie);
5646 ome.units.quantity.Length sw = new ome.units.quantity.Length(java.lang.Double.valueOf(an.strokeWidth), ome.units.UNITS.PIXEL);
5647 omexml.setEllipseStrokeWidth(sw, shapeIndex, serie);
5648 ome.xml.model.primitives.Color colf = new ome.xml.model.primitives.Color(an.fillColor.R, an.fillColor.G, an.fillColor.B, an.fillColor.A);
5649 omexml.setEllipseFillColor(colf, shapeIndex, serie);
5650 shapeIndex++;
5651 }
5652 else
5653 if (an.type == ROI.Type.Label)
5654 {
5655 if (an.id != "")
5656 omexml.setLabelID(an.id, shapeIndex, serie);
5657 else
5658 omexml.setLabelID("Shape:" + shapeIndex + ":" + serie, shapeIndex, serie);
5659 omexml.setLabelX(java.lang.Double.valueOf(b.ToImageSpaceX(an.BoundingBox.X)), shapeIndex, serie);
5660 omexml.setLabelY(java.lang.Double.valueOf(b.ToImageSpaceY(an.BoundingBox.Y)), shapeIndex, serie);
5661 omexml.setLabelTheZ(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.Z)), shapeIndex, serie);
5662 omexml.setLabelTheC(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.C)), shapeIndex, serie);
5663 omexml.setLabelTheT(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.T)), shapeIndex, serie);
5664 if (an.Text != "")
5665 omexml.setLabelText(an.Text, shapeIndex, serie);
5666 else
5667 omexml.setLabelText(shapeIndex.ToString(), shapeIndex, serie);
5668 ome.units.quantity.Length fl = new ome.units.quantity.Length(java.lang.Double.valueOf(an.fontSize), ome.units.UNITS.PIXEL);
5669 omexml.setLabelFontSize(fl, shapeIndex, serie);
5670 ome.xml.model.primitives.Color col = new ome.xml.model.primitives.Color(an.strokeColor.R, an.strokeColor.G, an.strokeColor.B, an.strokeColor.A);
5671 omexml.setLabelStrokeColor(col, shapeIndex, serie);
5672 ome.units.quantity.Length sw = new ome.units.quantity.Length(java.lang.Double.valueOf(an.strokeWidth), ome.units.UNITS.PIXEL);
5673 omexml.setLabelStrokeWidth(sw, shapeIndex, serie);
5674 ome.xml.model.primitives.Color colf = new ome.xml.model.primitives.Color(an.fillColor.R, an.fillColor.G, an.fillColor.B, an.fillColor.A);
5675 omexml.setLabelFillColor(colf, shapeIndex, serie);
5676 shapeIndex++;
5677 }
5678 else
5679 if (an.type == ROI.Type.Mask || an.roiMask != null)
5680 {
5681 if (an.id != "")
5682 omexml.setMaskID(an.id, shapeIndex, serie);
5683 else
5684 omexml.setMaskID("Shape:" + shapeIndex + ":" + serie, shapeIndex, serie);
5685 omexml.setMaskX(java.lang.Double.valueOf(b.ToImageSpaceX(b.StageSizeX + (an.roiMask.X * an.roiMask.PhysicalSizeX))), shapeIndex, serie);
5686 omexml.setMaskY(java.lang.Double.valueOf(b.ToImageSpaceY(b.StageSizeY + (an.roiMask.Y * an.roiMask.PhysicalSizeY))), shapeIndex, serie);
5687 omexml.setMaskTheZ(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.Z)), shapeIndex, serie);
5688 omexml.setMaskTheC(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.C)), shapeIndex, serie);
5689 omexml.setMaskTheT(new NonNegativeInteger(java.lang.Integer.valueOf(an.coord.T)), shapeIndex, serie);
5690 omexml.setMaskWidth(new java.lang.Double(an.roiMask.Width * an.roiMask.PhysicalSizeX), shapeIndex, serie);
5691 omexml.setMaskHeight(new java.lang.Double(an.roiMask.Height * an.roiMask.PhysicalSizeY), shapeIndex, serie);
5692 if (an.Text != "")
5693 omexml.setMaskText(an.Text, shapeIndex, serie);
5694 else
5695 omexml.setMaskText(shapeIndex.ToString(), shapeIndex, serie);
5696
5697 ome.units.quantity.Length fl = new ome.units.quantity.Length(java.lang.Double.valueOf(an.fontSize), ome.units.UNITS.PIXEL);
5698 omexml.setMaskFontSize(fl, shapeIndex, serie);
5699 ome.xml.model.primitives.Color col = new ome.xml.model.primitives.Color(an.strokeColor.R, an.strokeColor.G, an.strokeColor.B, an.strokeColor.A);
5700 omexml.setMaskStrokeColor(col, shapeIndex, serie);
5701 ome.units.quantity.Length sw = new ome.units.quantity.Length(java.lang.Double.valueOf(an.strokeWidth), ome.units.UNITS.PIXEL);
5702 omexml.setMaskStrokeWidth(sw, shapeIndex, serie);
5703 ome.xml.model.primitives.Color colf = new ome.xml.model.primitives.Color(an.fillColor.R, an.fillColor.G, an.fillColor.B, an.fillColor.A);
5704 omexml.setMaskFillColor(colf, shapeIndex, serie);
5705 byte[] bts = an.roiMask.GetBytes();
5706 omexml.setMaskBinData(bts, shapeIndex, serie);
5707 omexml.setMaskBinDataBigEndian(new java.lang.Boolean(!BitConverter.IsLittleEndian), shapeIndex, serie);
5708 omexml.setMaskBinDataLength(new NonNegativeLong(new java.lang.Long(bts.Length)), shapeIndex, serie);
5709 omexml.setMaskBinDataCompression(ome.xml.model.enums.Compression.NONE, shapeIndex, serie);
5710 shapeIndex++;
5711 }
5712 i++;
5713 }
5714
5715 } // end metadata build loop
5716
5717 // ---------- Create writer once and attach the metadata ----------
5718 loci.formats.ImageWriter writer = null;
5719 try
5720 {
5721 writer = new loci.formats.ImageWriter();
5722 writer.setMetadataRetrieve(omexml);
5723
5724 // setId only once (initializes writer for this output file)
5725 writer.setId(f);
5726
5727 // Write every series / plane
5728 for (int serie = 0; serie < files.Length; serie++)
5729 {
5730 BioImage b = files[serie];
5731 writer.setSeries(serie);
5732
5733 for (int bu = 0; bu < b.Buffers.Count; bu++)
5734 {
5735 byte[] bts = b.Buffers[bu].GetSaveBytes(BitConverter.IsLittleEndian);
5736 writer.saveBytes(bu, bts);
5737 Progress = ((float)bu / (float)b.Buffers.Count) * 100f;
5738 }
5739 }
5740
5741 writer.close();
5742 }
5743 catch (Exception ex)
5744 {
5745 // Dump OME-XML for debugging
5746 try
5747 {
5748 string xmlDump = ((loci.formats.ome.OMEXMLMetadata)omexml).dumpXML();
5749 Console.WriteLine("OME-XML dump:\n" + xmlDump);
5750 }
5751 catch
5752 {
5753 // ignore dump failure
5754 }
5755
5756 Console.WriteLine("SaveOMESeries exception: " + ex.ToString());
5757 throw;
5758 }
5759 finally
5760 {
5761 if (writer != null)
5762 {
5763 try { writer.close(); } catch { }
5764 }
5765 }
5766
5767 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, files, f, planes);
5768 }
double ToImageSpaceY(double y)
Definition Bio.cs:3315
static ROI[] SortByType(ROI[] annotations)
Sorts an array of ROIs by their Type property (alphabetically by default).
Definition Bio.cs:5342
double ToImageSizeX(double d)
Convert a physical size to an image size.
Definition Bio.cs:3285
double ToImageSizeY(double d)
Convert a physical size in Y direction to an image size in Y direction.
Definition Bio.cs:3295
double ToImageSpaceX(double x)
Definition Bio.cs:3304
PointD GetPoint(int i)
Definition ROI.cs:1282
string PointsToString(BioImage b)
Definition ROI.cs:1412

◆ SavePyramidalAsync()

static async Task BioLib.BioImage.SavePyramidalAsync ( BioImage[] imgs,
string file,
Enums.ForeignTiffCompression com,
int compLevel )
static

The function SavePyramidalAsync saves an array of BioImage objects as a pyramidal TIFF file asynchronously.

Parameters
imgsimgs is an array of BioImage objects.
fileThe "file" parameter is a string that represents the file path where the pyramidal image will be saved.
comThe parameter "com" is of type Enums.ForeignTiffCompression, which is an enumeration representing different compression options for the TIFF file.
compLevelThe compLevel parameter is an integer that represents the compression level for the TIFF file. It is used to specify the level of compression to be applied to the image data when saving the pyramidal image. The higher the compression level, the smaller the file size but potentially lower image quality.
7861 {
7862 bms = imgs;
7863 savefile = file;
7864 comp = com;
7865 compLev = compLevel;
7866 await Task.Run(SavePyramidalThread);
7867 }

◆ SaveSeries()

static void BioLib.BioImage.SaveSeries ( string[] IDs,
string file )
static

It takes a list of image IDs, and saves them as a single multi-page TIFF file.

Parameters
Anarray of IDs of the images to save
Thepath to the file to save to.
4666 {
4667 string desc = "";
4668 int stride = 0;
4669 ImageJDesc j = new ImageJDesc();
4670 BioImage bi = Images.GetImage(IDs[0]);
4671 j.FromImage(bi);
4672 desc = j.GetString();
4673 for (int fi = 0; fi < IDs.Length; fi++)
4674 {
4675 string id = IDs[fi];
4676 BioImage b = Images.GetImage(id);
4677 string fn = Path.GetFileNameWithoutExtension(id);
4678 string dir = Path.GetDirectoryName(file);
4679 stride = b.Buffers[0].Stride;
4680
4681 //Save ROIs to CSV file.
4682 if (b.Annotations.Count > 0)
4683 {
4684 string f = dir + "//" + fn + ".csv";
4685 ExportROIsCSV(f, b.Annotations);
4686 }
4687
4688 //Embed ROI's to image description.
4689 for (int i = 0; i < b.Annotations.Count; i++)
4690 {
4691 desc += "-ROI:" + b.series + ":" + ROIToString(b.Annotations[i]) + NewLine;
4692 }
4693 foreach (Channel c in b.Channels)
4694 {
4695 string cj = JsonConvert.SerializeObject(c.info, Formatting.None);
4696 desc += "-Channel:" + fi + ":" + cj + NewLine;
4697 }
4698 string json = JsonConvert.SerializeObject(b.imageInfo, Formatting.None);
4699 desc += "-ImageInfo:" + fi + ":" + json + NewLine;
4700 }
4701
4702 Tiff image = Tiff.Open(file, "w");
4703 for (int fi = 0; fi < IDs.Length; fi++)
4704 {
4705 int im = 0;
4706 string id = IDs[fi];
4707 BioImage b = Images.GetImage(id);
4708 int sizec = 1;
4709 if (!b.isRGB)
4710 {
4711 sizec = b.SizeC;
4712 }
4713 byte[] buffer;
4714 for (int c = 0; c < sizec; c++)
4715 {
4716 for (int z = 0; z < b.SizeZ; z++)
4717 {
4718 for (int t = 0; t < b.SizeT; t++)
4719 {
4720 image.SetDirectory((short)(im + (b.Buffers.Count * fi)));
4721 image.SetField(TiffTag.IMAGEWIDTH, b.SizeX);
4722 image.SetField(TiffTag.IMAGEDESCRIPTION, desc);
4723 image.SetField(TiffTag.IMAGELENGTH, b.SizeY);
4724 image.SetField(TiffTag.BITSPERSAMPLE, b.bitsPerPixel);
4725 image.SetField(TiffTag.SAMPLESPERPIXEL, b.RGBChannelCount);
4726 image.SetField(TiffTag.ROWSPERSTRIP, b.SizeY);
4727 image.SetField(TiffTag.ORIENTATION, BitMiracle.LibTiff.Classic.Orientation.TOPLEFT);
4728 image.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
4729 image.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK);
4730 image.SetField(TiffTag.ROWSPERSTRIP, image.DefaultStripSize(0));
4731 if (b.PhysicalSizeX != -1 && b.PhysicalSizeY != -1)
4732 {
4733 image.SetField(TiffTag.XRESOLUTION, (b.PhysicalSizeX * b.SizeX) / ((b.PhysicalSizeX * b.SizeX) * b.PhysicalSizeX));
4734 image.SetField(TiffTag.YRESOLUTION, (b.PhysicalSizeY * b.SizeY) / ((b.PhysicalSizeY * b.SizeY) * b.PhysicalSizeY));
4735 image.SetField(TiffTag.RESOLUTIONUNIT, ResUnit.NONE);
4736 }
4737 else
4738 {
4739 image.SetField(TiffTag.XRESOLUTION, 100.0);
4740 image.SetField(TiffTag.YRESOLUTION, 100.0);
4741 image.SetField(TiffTag.RESOLUTIONUNIT, ResUnit.INCH);
4742 }
4743 // specify that it's a page within the multipage file
4744 image.SetField(TiffTag.SUBFILETYPE, FileType.PAGE);
4745 // specify the page number
4746 buffer = b.Buffers[im].GetSaveBytes(true);
4747 image.SetField(TiffTag.PAGENUMBER, im + (b.Buffers.Count * fi), b.Buffers.Count * IDs.Length);
4748 for (int i = 0, offset = 0; i < b.SizeY; i++)
4749 {
4750 image.WriteScanline(buffer, offset, i, 0);
4751 offset += stride;
4752 }
4753 image.WriteDirectory();
4754 im++;
4755 }
4756 }
4757 }
4758 }
4759 image.Dispose();
4760 }

◆ SaveSeriesAsync()

static async Task BioLib.BioImage.SaveSeriesAsync ( BioImage[] imgs,
string file,
bool ome )
static

The function SaveSeriesAsync saves a series of BioImage objects to a file asynchronously.

Parameters
imgsimgs is an array of BioImage objects.
fileThe "file" parameter is a string that represents the file path where the series of BioImages will be saved.
omeThe "ome" parameter is a boolean flag that indicates whether the images should be saved in OME-TIFF format or not. If "ome" is set to true, the images will be saved in OME-TIFF format. If "ome" is set to false, the images will be
7830 {
7831 sts.Clear();
7832 foreach (BioImage item in imgs)
7833 {
7834 sts.Add(item.ID);
7835 }
7836 savefile = file;
7837 some = ome;
7838 await Task.Run(SaveSeriesThread);
7839 }

◆ SetFrameIndex()

void BioLib.BioImage.SetFrameIndex ( int z,
int c,
int t,
int val )
7175 {
7176 Coords[z, c, t] = val;
7177 }

◆ SetValue() [1/3]

void BioLib.BioImage.SetValue ( int x,
int y,
int ind,
ushort value )

It sets the value of a pixel in a buffer.

Parameters
xThe x coordinate of the pixel to set.
yThe y coordinate of the pixel to set.
indThe index of the buffer to set the value in.
valueThe value to set the pixel to.
4035 {
4036 Buffers[ind].SetValue(x, y, value);
4037 }

◆ SetValue() [2/3]

void BioLib.BioImage.SetValue ( int x,
int y,
ZCT coord,
ushort value )

This function sets the value of a pixel at a given x,y coordinate in a given image plane.

Parameters
xx coordinate of the pixel
yThe y coordinate of the pixel to set.
ZCTa struct that contains the Z, C, and T coordinates of the pixel
valuethe value to set
4045 {
4046 SetValue(x, y, GetFrameIndex(coord.Z, coord.C, coord.T), value);
4047 }
void SetValue(ZCTXY coord, ushort value)
It takes a coordinate and a value, and sets the value at that coordinate.
Definition Bio.cs:4023

◆ SetValue() [3/3]

void BioLib.BioImage.SetValue ( ZCTXY coord,
ushort value )

It takes a coordinate and a value, and sets the value at that coordinate.

Parameters
ZCTXYa struct that contains the Z, C, T, X, and Y coordinates of the pixel
valuethe value to be set
4024 {
4025 int i = GetFrameIndex(coord.Z, coord.C, coord.T);
4026 Buffers[i].SetValue(coord.X, coord.Y, value);
4027 }

◆ SetValueRGB()

void BioLib.BioImage.SetValueRGB ( ZCTXY coord,
int RGBindex,
ushort value )

It takes a coordinate, an RGB index, and a value, and sets the value of the pixel at that coordinate to the value.

Parameters
ZCTXYa struct that contains the Z, C, T, X, and Y coordinates of the pixel
RGBindex0 = Red, 1 = Green, 2 = Blue
valuethe value to be set
4055 {
4056 int ind = GetFrameIndex(coord.Z, coord.C, coord.T);
4057 Buffers[ind].SetValue(coord.X, coord.Y, RGBindex, value);
4058 }

◆ SortByType()

static ROI[] BioLib.BioImage.SortByType ( ROI[] annotations)
static

Sorts an array of ROIs by their Type property (alphabetically by default).

5343 {
5344 if (annotations == null || annotations.Length == 0)
5345 return Array.Empty<ROI>();
5346
5347 return annotations
5348 .OrderBy<ROI, string>(r => r.type.ToString(), StringComparer.OrdinalIgnoreCase)
5349 .ToArray();
5350 }

◆ SplitChannels() [1/3]

BioImage[] BioLib.BioImage.SplitChannels ( )

It takes a single image and splits it into three images, one for each channel.

Returns
A list of BioImages
3748 {
3749 BioImage[] bms;
3750 if (isRGB)
3751 {
3752 bms = new BioImage[3];
3753 BioImage ri = new BioImage(System.IO.Path.GetFileNameWithoutExtension(ID) + "-1" + System.IO.Path.GetExtension(ID));
3754 BioImage gi = new BioImage(System.IO.Path.GetFileNameWithoutExtension(ID) + "-2" + System.IO.Path.GetExtension(ID));
3755 BioImage bi = new BioImage(System.IO.Path.GetFileNameWithoutExtension(ID) + "-3" + System.IO.Path.GetExtension(ID));
3756 ri.sizeC = 1;
3757 gi.sizeC = 1;
3758 bi.sizeC = 1;
3759 ri.sizeZ = SizeZ;
3760 gi.sizeZ = SizeZ;
3761 bi.sizeZ = SizeZ;
3762 ri.sizeT = SizeT;
3763 gi.sizeT = SizeT;
3764 bi.sizeT = SizeT;
3765
3766 ri.Coords = new int[SizeZ, 1, SizeT];
3767 gi.Coords = new int[SizeZ, 1, SizeT];
3768 bi.Coords = new int[SizeZ, 1, SizeT];
3769 int ind = 0;
3770 for (int i = 0; i < ImageCount; i++)
3771 {
3772 if (Buffers[i].PixelFormat == PixelFormat.Format48bppRgb)
3773 {
3774 //For 48bit images we need to use our own function as AForge won't give us a proper image.
3775 Bitmap[] bfs = Bitmap.RGB48To16(ID, SizeX, SizeY, Buffers[i].Stride, Buffers[i].Bytes, Buffers[i].Coordinate, ind, Buffers[i].Plane);
3776 ind += 3;
3777 ri.Buffers.Add(bfs[0]);
3778 gi.Buffers.Add(bfs[1]);
3779 bi.Buffers.Add(bfs[2]);
3780 bfs[0].Stats = Statistics.FromBytes(bfs[0]);
3781 bfs[1].Stats = Statistics.FromBytes(bfs[1]);
3782 bfs[2].Stats = Statistics.FromBytes(bfs[2]);
3783 ri.SetFrameIndex(Buffers[i].Coordinate.Z, Buffers[i].Coordinate.C, Buffers[i].Coordinate.T, i);
3784 gi.SetFrameIndex(Buffers[i].Coordinate.Z, Buffers[i].Coordinate.C, Buffers[i].Coordinate.T, i);
3785 bi.SetFrameIndex(Buffers[i].Coordinate.Z, Buffers[i].Coordinate.C, Buffers[i].Coordinate.T, i);
3786 }
3787 else
3788 {
3789
3790 Bitmap rImage = extractR.Apply(Buffers[i]);
3791 Bitmap rbf = new Bitmap(ri.ID, rImage, Buffers[i].Coordinate, ind++);
3792 rbf.Stats = Statistics.FromBytes(rbf);
3793 ri.Buffers.Add(rbf);
3794 ri.SetFrameIndex(Buffers[i].Coordinate.Z, Buffers[i].Coordinate.C, Buffers[i].Coordinate.T, i);
3795
3796 Bitmap gImage = extractG.Apply(Buffers[i]);
3797 Bitmap gbf = new Bitmap(gi.ID, gImage, Buffers[i].Coordinate, ind++);
3798 gbf.Stats = Statistics.FromBytes(gbf);
3799 gi.Buffers.Add(gbf);
3800 gi.SetFrameIndex(Buffers[i].Coordinate.Z, Buffers[i].Coordinate.C, Buffers[i].Coordinate.T, i);
3801
3802 Bitmap bImage = extractB.Apply(Buffers[i]);
3803 //Clipboard.SetImage(bImage);
3804 Bitmap bbf = new Bitmap(bi.ID, bImage, Buffers[i].Coordinate, ind++);
3805 bbf.Stats = Statistics.FromBytes(bbf);
3806 bi.Buffers.Add(bbf);
3807 bi.SetFrameIndex(Buffers[i].Coordinate.Z, Buffers[i].Coordinate.C, Buffers[i].Coordinate.T, i);
3808
3809 }
3810 }
3811 //We wait for threshold image statistics calculation
3812 do
3813 {
3814 Thread.Sleep(100);
3815 } while (bi.Buffers[bi.Buffers.Count - 1].Stats == null);
3816 ri.Resolutions.Add(new Resolution(Buffers[0].SizeX, Buffers[0].SizeY, Buffers[0].PixelFormat, PhysicalSizeX, PhysicalSizeY, PhysicalSizeZ, StageSizeX, StageSizeY, StageSizeZ));
3817 gi.Resolutions.Add(new Resolution(Buffers[0].SizeX, Buffers[0].SizeY, Buffers[0].PixelFormat, PhysicalSizeX, PhysicalSizeY, PhysicalSizeZ, StageSizeX, StageSizeY, StageSizeZ));
3818 bi.Resolutions.Add(new Resolution(Buffers[0].SizeX, Buffers[0].SizeY, Buffers[0].PixelFormat, PhysicalSizeX, PhysicalSizeY, PhysicalSizeZ, StageSizeX, StageSizeY, StageSizeZ));
3819 ri.Channels.Add(Channels[0].Copy());
3820 gi.Channels.Add(Channels[0].Copy());
3821 bi.Channels.Add(Channels[0].Copy());
3822 AutoThreshold(ri, false);
3823 AutoThreshold(gi, false);
3824 AutoThreshold(bi, false);
3825 Images.AddImage(ri);
3826 Images.AddImage(gi);
3827 Images.AddImage(bi);
3828 bms[0] = ri;
3829 bms[1] = gi;
3830 bms[2] = bi;
3831 }
3832 else
3833 {
3834 bms = new BioImage[SizeC];
3835 for (int c = 0; c < SizeC; c++)
3836 {
3837 BioImage b = BioImage.Substack(this, 0, 0, SizeZ, c, c + 1, 0, SizeT);
3838 bms[c] = b;
3839 }
3840 }
3841 return bms;
3842 }
static BioImage Substack(BioImage orig, int ser, int zs, int ze, int cs, int ce, int ts, int te)
It takes a BioImage object, and returns a new BioImage object that is a subset of the original.
Definition Bio.cs:3533

◆ SplitChannels() [2/3]

static BioImage[] BioLib.BioImage.SplitChannels ( BioImage bb)
static

‍SplitChannels splits a BioImage into its constituent channels

Parameters
BioImageThe image to split
Returns
An array of BioImages
3849 {
3850 return bb.SplitChannels();
3851 }
BioImage[] SplitChannels()
It takes a single image and splits it into three images, one for each channel.
Definition Bio.cs:3747

◆ SplitChannels() [3/3]

static BioImage[] BioLib.BioImage.SplitChannels ( string name)
static

This function takes an image and splits it into its individual channels.

Parameters
nameThe name of the image to split.
Returns
An array of BioImage objects.
3858 {
3859 return SplitChannels(Images.GetImage(name));
3860 }

◆ StackThreshold()

void BioLib.BioImage.StackThreshold ( bool bit16)

This function sets the minimum and maximum values of the image to the minimum and maximum values of the stack.

Parameters
bit16true = 16 bit, false = 8 bit
7317 {
7318 if (bit16)
7319 {
7320 for (int ch = 0; ch < Channels.Count; ch++)
7321 {
7322 for (int i = 0; i < Channels[ch].range.Length; i++)
7323 {
7324 Channels[ch].range[i].Min = (int)Channels[ch].stats[i].StackMin;
7325 Channels[ch].range[i].Max = (int)Channels[ch].stats[i].StackMax;
7326 }
7327 Channels[ch].BitsPerPixel = 16;
7328 }
7329 bitsPerPixel = 16;
7330 }
7331 else
7332 {
7333 for (int ch = 0; ch < Channels.Count; ch++)
7334 {
7335 for (int i = 0; i < Channels[ch].range.Length; i++)
7336 {
7337 Channels[ch].range[i].Min = (int)Channels[ch].stats[i].StackMin;
7338 Channels[ch].range[i].Max = (int)Channels[ch].stats[i].StackMax;
7339 }
7340 Channels[ch].BitsPerPixel = 8;
7341 }
7342 bitsPerPixel = 8;
7343 }
7344 Recorder.AddLine("BioLib.Images.GetImage(\"" + id + "\").StackThreshold(" + bit16.ToString().ToLower() + ");", true);
7345 }

◆ StringToROI()

static ROI BioLib.BioImage.StringToROI ( string sts)
static

It takes a string and returns an ROI object.

Parameters
ststhe string that contains the ROI data
Returns
A ROI object.
8366 {
8367 //Works with either comma or tab separated values.
8368 if (sts.StartsWith("<?xml") || sts.StartsWith("{"))
8369 return null;
8370 ROI an = new ROI();
8371 string val = "";
8372 bool inSep = false;
8373 int col = 0;
8374 double x = 0;
8375 double y = 0;
8376 double w = 0;
8377 double h = 0;
8378 string line = sts;
8379 bool points = false;
8380 char sep = '"';
8381 for (int i = 0; i < line.Length; i++)
8382 {
8383 char c = line[i];
8384 if (c == sep)
8385 {
8386 if (!inSep)
8387 {
8388 inSep = true;
8389 }
8390 else
8391 inSep = false;
8392 continue;
8393 }
8394
8395 if ((c == ',' || c == '\t') && (!inSep || points))
8396 {
8397 //ROIID,ROINAME,TYPE,ID,SHAPEINDEX,TEXT,C,Z,T,X,Y,W,H,POINTS,STROKECOLOR,STROKECOLORW,FILLCOLOR,FONTSIZE
8398 if (col == 0)
8399 {
8400 //ROIID
8401 an.roiID = val;
8402 }
8403 else
8404 if (col == 1)
8405 {
8406 //ROINAME
8407 an.roiName = val;
8408 }
8409 else
8410 if (col == 2)
8411 {
8412 //TYPE
8413 an.type = (ROI.Type)Enum.Parse(typeof(ROI.Type), val);
8414 if (an.type == ROI.Type.Freeform || an.type == ROI.Type.Polygon)
8415 an.closed = true;
8416 }
8417 else
8418 if (col == 3)
8419 {
8420 //ID
8421 an.id = val;
8422 }
8423 else
8424 if (col == 4)
8425 {
8426 //SHAPEINDEX/
8427 an.shapeIndex = int.Parse(val);
8428 }
8429 else
8430 if (col == 5)
8431 {
8432 //TEXT/
8433 an.Text = val;
8434 }
8435 else
8436 if (col == 6)
8437 {
8438 an.serie = int.Parse(val);
8439 }
8440 else
8441 if (col == 7)
8442 {
8443 an.coord.Z = int.Parse(val);
8444 }
8445 else
8446 if (col == 8)
8447 {
8448 an.coord.C = int.Parse(val);
8449 }
8450 else
8451 if (col == 9)
8452 {
8453 an.coord.T = int.Parse(val);
8454 }
8455 else
8456 if (col == 10)
8457 {
8458 x = double.Parse(val, CultureInfo.InvariantCulture);
8459 }
8460 else
8461 if (col == 11)
8462 {
8463 y = double.Parse(val, CultureInfo.InvariantCulture);
8464 }
8465 else
8466 if (col == 12)
8467 {
8468 w = double.Parse(val, CultureInfo.InvariantCulture);
8469 }
8470 else
8471 if (col == 13)
8472 {
8473 h = double.Parse(val, CultureInfo.InvariantCulture);
8474 }
8475 else
8476 if (col == 14)
8477 {
8478 //POINTS
8479 an.AddPoints(an.stringToPoints(val));
8480 points = false;
8481 an.BoundingBox = new RectangleD(x, y, w, h);
8482 }
8483 else
8484 if (col == 15)
8485 {
8486 //STROKECOLOR
8487 string[] st = val.Split(',');
8488 an.strokeColor = Color.FromArgb(int.Parse(st[0]), int.Parse(st[1]), int.Parse(st[2]), int.Parse(st[3]));
8489 }
8490 else
8491 if (col == 16)
8492 {
8493 //STROKECOLORW
8494 an.strokeWidth = double.Parse(val, CultureInfo.InvariantCulture);
8495 }
8496 else
8497 if (col == 17)
8498 {
8499 //FILLCOLOR
8500 string[] st = val.Split(',');
8501 an.fillColor = Color.FromArgb(int.Parse(st[0]), int.Parse(st[1]), int.Parse(st[2]), int.Parse(st[3]));
8502 }
8503 else
8504 if (col == 18)
8505 {
8506 //FONTSIZE
8507 double s = double.Parse(val, CultureInfo.InvariantCulture);
8508 an.fontSize = (float)s;
8509 an.family = "Times New Roman";
8510 }
8511 col++;
8512 val = "";
8513 }
8514 else
8515 val += c;
8516 }
8517
8518 return an;
8519 }

◆ Substack()

static BioImage BioLib.BioImage.Substack ( BioImage orig,
int ser,
int zs,
int ze,
int cs,
int ce,
int ts,
int te )
static

It takes a BioImage object, and returns a new BioImage object that is a subset of the original.

Parameters
BioImagethe image to be processed
serseries number
zsstarting z-plane
zeend of z-stack
cschannel start
cechannel end
tstime start
tetime end
Returns
A new BioImage object.
3534 {
3535 BioImage b = CopyInfo(orig, false, false);
3536 //b.ID = Images.GetImageName(orig.ID);
3537 int i = 0;
3538 b.Coords = new int[ze - zs, ce - cs, te - ts];
3539 b.sizeZ = ze - zs;
3540 b.sizeC = ce - cs;
3541 b.sizeT = te - ts;
3542 for (int ti = 0; ti < b.SizeT; ti++)
3543 {
3544 for (int zi = 0; zi < b.SizeZ; zi++)
3545 {
3546 for (int ci = 0; ci < b.SizeC; ci++)
3547 {
3548 int ind = orig.GetFrameIndex(zs + zi, cs + ci, ts + ti);
3549 Bitmap bf = new Bitmap(Images.GetImageName(orig.id), orig.SizeX, orig.SizeY, orig.Buffers[0].PixelFormat, orig.Buffers[ind].Bytes, new ZCT(zi, ci, ti), i);
3550 bf.Stats = Statistics.FromBytes(bf);
3551 b.Buffers.Add(bf);
3552 b.SetFrameIndex(zi, ci, ti, i);
3553 i++;
3554 }
3555 }
3556 }
3557 for (int ci = cs; ci < ce; ci++)
3558 {
3559 b.Channels.Add(orig.Channels[ci]);
3560 }
3561 b.Resolutions.Add(new Resolution(b.Buffers[0].SizeX, b.Buffers[0].SizeY, b.Buffers[0].PixelFormat, b.PhysicalSizeX, b.PhysicalSizeY, b.PhysicalSizeZ, b.StageSizeX, b.StageSizeY, b.StageSizeZ));
3562 AutoThreshold(b, false);
3563 if (b.bitsPerPixel > 8)
3564 b.StackThreshold(true);
3565 else
3566 b.StackThreshold(false);
3567 Images.AddImage(b);
3568 return b;
3569 }

◆ To16Bit()

void BioLib.BioImage.To16Bit ( )

Converts the image to 16 bit.

2770 {
2771 if (Buffers[0].RGBChannelsCount == 4)
2772 To24Bit();
2773 if (Buffers[0].PixelFormat == PixelFormat.Format16bppGrayScale)
2774 return;
2775 bitsPerPixel = 16;
2776 if (Buffers[0].PixelFormat == PixelFormat.Format48bppRgb)
2777 {
2778 List<Bitmap> bfs = new List<Bitmap>();
2779 int index = 0;
2780 for (int i = 0; i < Buffers.Count; i++)
2781 {
2782 Array.Reverse(Buffers[i].Bytes);
2783 Bitmap[] bs = Bitmap.RGB48To16(ID, SizeX, SizeY, Buffers[i].Stride, Buffers[i].Bytes, Buffers[i].Coordinate, index, Buffers[i].Plane);
2784 bfs.AddRange(bs);
2785 index += 3;
2786 }
2787 Buffers = bfs;
2788 UpdateCoords(SizeZ, SizeC * 3, SizeT);
2789 if (Channels[0].SamplesPerPixel == 3)
2790 {
2791 Channel c = Channels[0].Copy();
2792 c.SamplesPerPixel = 1;
2793 c.range = new IntRange[1];
2794 Channels.Clear();
2795 Channels.Add(c);
2796 Channels.Add(c.Copy());
2797 Channels.Add(c.Copy());
2798 Channels[1].Index = 1;
2799 Channels[2].Index = 2;
2800 }
2801 }
2802 else if (Buffers[0].PixelFormat == PixelFormat.Format8bppIndexed)
2803 {
2804 for (int i = 0; i < Buffers.Count; i++)
2805 {
2806 Buffers[i] = AForge.Imaging.Image.Convert8bppTo16bpp(Buffers[i]);
2807 }
2808 for (int c = 0; c < Channels.Count; c++)
2809 {
2810 for (int i = 0; i < Channels[c].range.Length; i++)
2811 {
2812 Channels[c].range[i].Min = (int)(((float)Channels[c].range[i].Min / (float)byte.MaxValue) * ushort.MaxValue);
2813 Channels[c].range[i].Max = (int)(((float)Channels[c].range[i].Max / (float)byte.MaxValue) * ushort.MaxValue);
2814 }
2815 Channels[c].BitsPerPixel = 16;
2816 }
2817 bitsPerPixel = 16;
2818 }
2819 else if (Buffers[0].PixelFormat == PixelFormat.Format24bppRgb)
2820 {
2821 To48Bit();
2822 To16Bit();
2823 }
2824 else if (Buffers[0].PixelFormat == PixelFormat.Float)
2825 {
2826 for (int i = 0; i < Buffers.Count; i++)
2827 {
2828 if (Statistics.StackMax <= 1)
2829 Buffers[i].To16Bit(true);
2830 else
2831 Buffers[i].To16Bit(false);
2832 }
2833 }
2834
2835 foreach (var item in Buffers)
2836 {
2837 item.Stats = Statistics.FromBytes(item);
2838 }
2839 AutoThreshold(this, true);
2840 StackThreshold(true);
2841 }
void To16Bit()
Converts the image to 16 bit.
Definition Bio.cs:2769
void To24Bit()
Converts the image to 24 bit.
Definition Bio.cs:2843
void To48Bit()
Definition Bio.cs:2921

◆ To24Bit()

void BioLib.BioImage.To24Bit ( )

Converts the image to 24 bit.

2844 {
2845 if (Buffers[0].PixelFormat == PixelFormat.Format24bppRgb)
2846 return;
2847 bitsPerPixel = 8;
2848 if (Buffers[0].PixelFormat == PixelFormat.Format32bppArgb || Buffers[0].PixelFormat == PixelFormat.Format32bppRgb)
2849 {
2850 for (int i = 0; i < Buffers.Count; i++)
2851 {
2852 Buffers[i] = Bitmap.To24Bit(Buffers[i]);
2853 }
2854 if (Channels.Count == 4)
2855 {
2856 Channels.RemoveAt(0);
2857 }
2858 else
2859 {
2860 Channels[0].SamplesPerPixel = 3;
2861 }
2862 }
2863 else
2864 if (Buffers[0].PixelFormat == PixelFormat.Format48bppRgb)
2865 {
2866 //We run 8bit so we get 24 bit rgb.
2867 for (int i = 0; i < Buffers.Count; i++)
2868 {
2869 Buffers[i] = AForge.Imaging.Image.Convert16bppTo8bpp(Buffers[i]);
2870 Buffers[i].SwitchRedBlue();
2871 }
2872 }
2873 else
2874 if (Buffers[0].PixelFormat == PixelFormat.Format16bppGrayScale)
2875 {
2876 //We run 8bit so we get 24 bit rgb.
2877 for (int i = 0; i < Buffers.Count; i++)
2878 {
2879 Buffers[i] = AForge.Imaging.Image.Convert16bppTo8bpp(Buffers[i]);
2880 }
2881 To24Bit();
2882 }
2883 else if(Buffers[0].PixelFormat == PixelFormat.Format8bppIndexed)
2884 {
2885 List<Bitmap> bms = new List<Bitmap>();
2886 //We run 8bit so we get 24 bit rgb.
2887 for (int i = 0; i < Buffers.Count; i+=3)
2888 {
2889 bms.Add(Bitmap.RGB8To24(new Bitmap[] { Buffers[i], Buffers[i+1], Buffers[i+2] }));
2890 }
2891 Buffers.Clear();
2892 Buffers.AddRange(bms);
2893 UpdateCoords(SizeZ, 1, SizeT);
2894 }
2895 foreach (var item in Buffers)
2896 {
2897 item.Stats = Statistics.FromBytes(item);
2898 }
2899 AutoThreshold(this, true);
2900 StackThreshold(false);
2901 }

◆ To32Bit()

void BioLib.BioImage.To32Bit ( )

Converts the image to 32 bit.

2904 {
2905 if (Buffers[0].PixelFormat == PixelFormat.Format32bppArgb)
2906 return;
2907 if (Buffers[0].PixelFormat != PixelFormat.Format24bppRgb)
2908 {
2909 To24Bit();
2910 }
2911 for (int i = 0; i < Buffers.Count; i++)
2912 {
2913 UnmanagedImage b = Bitmap.To32Bit(Buffers[i]);
2914 Buffers[i].Image = b;
2915 }
2916 AutoThreshold(this, true);
2917 }

◆ To48Bit()

void BioLib.BioImage.To48Bit ( )

It converts a 16 bit image to a 48 bit image

Returns
A list of Bitmaps.
2922 {
2923 if (Buffers[0].RGBChannelsCount == 4)
2924 To24Bit();
2925 if (Buffers[0].PixelFormat == PixelFormat.Format48bppRgb)
2926 return;
2927 if (Buffers[0].PixelFormat == PixelFormat.Format8bppIndexed || Buffers[0].PixelFormat == PixelFormat.Format16bppGrayScale)
2928 {
2929 if (Buffers[0].PixelFormat == PixelFormat.Format8bppIndexed)
2930 {
2931 for (int i = 0; i < Buffers.Count; i++)
2932 {
2933 Buffers[i].Image = AForge.Imaging.Image.Convert8bppTo16bpp(Buffers[i]);
2934 }
2935 }
2936 List<Bitmap> bfs = new List<Bitmap>();
2937 if (Buffers.Count % 3 != 0 && Buffers.Count % 2 != 0)
2938 for (int i = 0; i < Buffers.Count; i++)
2939 {
2940 Bitmap bs = new Bitmap(ID, SizeX, SizeY, Buffers[i].PixelFormat, Buffers[i].Bytes, new ZCT(Buffers[i].Coordinate.Z, 0, Buffers[i].Coordinate.T), i, Buffers[i].Plane);
2941 Bitmap bbs = Bitmap.RGB16To48(bs);
2942 bs.Dispose();
2943 bs = null;
2944 bfs.Add(bbs);
2945 }
2946 else
2947 for (int i = 0; i < Buffers.Count; i += Channels.Count)
2948 {
2949 Bitmap[] bs = new Bitmap[3];
2950 bs[0] = new Bitmap(ID, SizeX, SizeY, Buffers[i].PixelFormat, Buffers[i].Bytes, new ZCT(Buffers[i].Coordinate.Z, 0, Buffers[i].Coordinate.T), i, Buffers[i].Plane);
2951 bs[1] = new Bitmap(ID, SizeX, SizeY, Buffers[i + 1].PixelFormat, Buffers[i + 1].Bytes, new ZCT(Buffers[i + 1].Coordinate.Z, 0, Buffers[i + 1].Coordinate.T), i + 1, Buffers[i + 1].Plane);
2952 if (Channels.Count > 2)
2953 bs[2] = new Bitmap(ID, SizeX, SizeY, Buffers[i + 2].PixelFormat, Buffers[i + 2].Bytes, new ZCT(Buffers[i].Coordinate.Z, 0, Buffers[i + 2].Coordinate.T), i + 2, Buffers[i].Plane);
2954 Bitmap bbs = Bitmap.RGB16To48(bs);
2955 for (int b = 0; b < 3; b++)
2956 {
2957 if (bs[b] != null)
2958 bs[b].Dispose();
2959 bs[b] = null;
2960 }
2961 bfs.Add(bbs);
2962 }
2963 Buffers = bfs;
2964 UpdateCoords(SizeZ, 1, SizeT);
2965 Channel c = Channels[0].Copy();
2966 c.SamplesPerPixel = 3;
2967 rgbChannels[0] = 0;
2968 rgbChannels[1] = 0;
2969 rgbChannels[2] = 0;
2970 Channels.Clear();
2971 Channels.Add(c);
2972 }
2973 else
2974 if (Buffers[0].PixelFormat == PixelFormat.Format24bppRgb || Buffers[0].PixelFormat == PixelFormat.Format32bppArgb)
2975 {
2976 for (int i = 0; i < Buffers.Count; i++)
2977 {
2978 Buffers[i] = AForge.Imaging.Image.Convert8bppTo16bpp(Buffers[i]);
2979 Buffers[i].SwitchRedBlue();
2980 }
2981 }
2982 else
2983 {
2984 int index = 0;
2985 List<Bitmap> buffers = new List<Bitmap>();
2986 for (int i = 0; i < Buffers.Count; i += 3)
2987 {
2988 Bitmap[] bf = new Bitmap[3];
2989 bf[0] = Buffers[i];
2990 bf[1] = Buffers[i + 1];
2991 bf[2] = Buffers[i + 2];
2992 Bitmap inf = Bitmap.RGB16To48(bf);
2993 buffers.Add(inf);
2994 for (int b = 0; b < 3; b++)
2995 {
2996 bf[b].Dispose();
2997 }
2998 index++;
2999 }
3000 Buffers = buffers;
3001 UpdateCoords(SizeZ, 1, SizeT);
3002 }
3003 bitsPerPixel = 16;
3004 AutoThreshold(this, true);
3005 StackThreshold(true);
3006 }

◆ To8Bit()

void BioLib.BioImage.To8Bit ( )

Converts a 16-bit image to an 8-bit image.

2680 {
2681 if (Buffers[0].RGBChannelsCount == 4)
2682 To24Bit();
2683 PixelFormat px = Buffers[0].PixelFormat;
2684 if (px == PixelFormat.Format8bppIndexed)
2685 return;
2686 if (px == PixelFormat.Format48bppRgb)
2687 {
2688 To24Bit();
2689 List<AForge.Bitmap> bfs = new List<AForge.Bitmap>();
2690 int index = 0;
2691 for (int i = 0; i < Buffers.Count; i++)
2692 {
2693 Bitmap[] bs = Bitmap.RGB24To8(Buffers[i]);
2694 Bitmap br = new Bitmap(ID, bs[2], new ZCT(Buffers[i].Coordinate.Z, 0, Buffers[i].Coordinate.T), index, Buffers[i].Plane);
2695 Bitmap bg = new Bitmap(ID, bs[1], new ZCT(Buffers[i].Coordinate.Z, 1, Buffers[i].Coordinate.T), index + 1, Buffers[i].Plane);
2696 Bitmap bb = new Bitmap(ID, bs[0], new ZCT(Buffers[i].Coordinate.Z, 2, Buffers[i].Coordinate.T), index + 2, Buffers[i].Plane);
2697 for (int b = 0; b < 3; b++)
2698 {
2699 bs[b].Dispose();
2700 }
2701 bs = null;
2702 br.Stats = Statistics.FromBytes(br);
2703 bg.Stats = Statistics.FromBytes(bg);
2704 bb.Stats = Statistics.FromBytes(bb);
2705 bfs.Add(br);
2706 bfs.Add(bg);
2707 bfs.Add(bb);
2708 index += 3;
2709 }
2710 Buffers = bfs;
2711 UpdateCoords(SizeZ, 3, SizeT);
2712 }
2713 else
2714 if (px == PixelFormat.Format24bppRgb)
2715 {
2716 List<Bitmap> bfs = new List<Bitmap>();
2717 int index = 0;
2718 for (int i = 0; i < Buffers.Count; i++)
2719 {
2720 Bitmap[] bs = Bitmap.RGB24To8(Buffers[i]);
2721 Bitmap br = new Bitmap(ID, bs[2], new ZCT(Buffers[i].Coordinate.Z, 0, Buffers[i].Coordinate.T), index, Buffers[i].Plane);
2722 Bitmap bg = new Bitmap(ID, bs[1], new ZCT(Buffers[i].Coordinate.Z, 1, Buffers[i].Coordinate.T), index + 1, Buffers[i].Plane);
2723 Bitmap bb = new Bitmap(ID, bs[0], new ZCT(Buffers[i].Coordinate.Z, 2, Buffers[i].Coordinate.T), index + 2, Buffers[i].Plane);
2724 for (int b = 0; b < 3; b++)
2725 {
2726 bs[b].Dispose();
2727 bs[b] = null;
2728 }
2729 bs = null;
2730 br.Stats = Statistics.FromBytes(br);
2731 bg.Stats = Statistics.FromBytes(bg);
2732 bb.Stats = Statistics.FromBytes(bb);
2733 bfs.Add(br);
2734 bfs.Add(bg);
2735 bfs.Add(bb);
2736 index += 3;
2737 }
2738 Buffers = bfs;
2739 UpdateCoords(SizeZ, 3, SizeT);
2740 Channels.Clear();
2741 Channels.Add(new Channel(0, 8, 1));
2742 Channels.Add(new Channel(0, 8, 1));
2743 Channels.Add(new Channel(0, 8, 1));
2744 }
2745 else
2746 if (px == PixelFormat.Format16bppGrayScale)
2747 {
2748 foreach (var item in Buffers)
2749 {
2750 item.To8Bit();
2751 }
2752 }
2753 else
2754 if (px == PixelFormat.Float)
2755 {
2756 foreach (var item in Buffers)
2757 {
2758 if (Statistics.StackMax <= 1)
2759 item.To8Bit(true);
2760 else
2761 item.To8Bit(false);
2762 }
2763 }
2764 AutoThreshold(this, true);
2765 StackThreshold(false);
2766 bitsPerPixel = 8;
2767 }

◆ ToFloat()

void BioLib.BioImage.ToFloat ( )
3017 {
3018 foreach (var b in Buffers)
3019 {
3020 b.ToFloat();
3021 b.Stats = Statistics.FromBytes(b);
3022 }
3023 AutoThreshold(this, true);
3024 StackThreshold(false);
3025 }

◆ ToImageSizeX()

double BioLib.BioImage.ToImageSizeX ( double d)

Convert a physical size to an image size.

Parameters
dthe distance in microns
Returns
The value of d divided by the physicalSizeX.
3286 {
3287 return d / PhysicalSizeX;
3288 }

◆ ToImageSizeY()

double BioLib.BioImage.ToImageSizeY ( double d)

Convert a physical size in Y direction to an image size in Y direction.

Parameters
dthe distance in microns
Returns
The return value is the value of the parameter d divided by the value of the physicalSizeY field.
3296 {
3297 return d / PhysicalSizeY;
3298 }

◆ ToImageSpace() [1/5]

PointD[] BioLib.BioImage.ToImageSpace ( List< PointD > p)

Convert a list of points from stage space to image space.

Parameters
pList of points in stage space
Returns
A PointD array.
3339 {
3340 PointD[] ps = new PointD[p.Count];
3341 for (int i = 0; i < p.Count; i++)
3342 {
3343 PointD pp = new PointD();
3344 pp.X = ((p[i].X - StageSizeX) / PhysicalSizeX);
3345 pp.Y = ((p[i].Y - StageSizeY) / PhysicalSizeY);
3346 ps[i] = pp;
3347 }
3348 return ps;
3349 }

◆ ToImageSpace() [2/5]

static PointD[] BioLib.BioImage.ToImageSpace ( List< PointD > p,
double stageSizeX,
double stageSizeY,
double physicalSizeX,
double physicalSizeY )
static

The function takes a list of points in stage space and converts them to image space using the provided stage and physical size parameters.

Parameters
pA list of PointD objects representing points in stage space.
stageSizeXThe width of the stage or canvas in pixels.
stageSizeYThe stageSizeY parameter represents the size of the stage or canvas in the Y-axis direction. It is used to calculate the Y-coordinate of each point in the p list in image space.
physicalSizeXThe physical size of the X-axis in the image space.
physicalSizeYThe physical size of the Y-axis in the coordinate system of the stage or image.
Returns
The method is returning an array of PointD objects.
7419 {
7420 PointD[] ps = new PointD[p.Count];
7421 for (int i = 0; i < p.Count; i++)
7422 {
7423 PointD pp = new PointD();
7424 pp.X = ((p[i].X - stageSizeX) / physicalSizeX);
7425 pp.Y = ((p[i].Y - stageSizeY) / physicalSizeY);
7426 ps[i] = pp;
7427 }
7428 return ps;
7429 }

◆ ToImageSpace() [3/5]

PointD BioLib.BioImage.ToImageSpace ( PointD p)

Convert a point in the stage coordinate system to a point in the image coordinate system.

Parameters
PointD
Returns
A PointF object.
3327 {
3328 PointD pp = new PointD();
3329 pp.X = (float)((p.X - StageSizeX) / PhysicalSizeX);
3330 pp.Y = (float)((p.Y - StageSizeY) / PhysicalSizeY);
3331 return pp;
3332 }

◆ ToImageSpace() [4/5]

PointF[] BioLib.BioImage.ToImageSpace ( PointF[] p)

‍The function takes a list of points in the stage coordinate system and returns a list of points in the image coordinate system

Parameters
pthe points to be converted
Returns
A PointF[]
3357 {
3358 PointF[] ps = new PointF[p.Length];
3359 for (int i = 0; i < p.Length; i++)
3360 {
3361 PointF pp = new PointF();
3362 pp.X = (float)((p[i].X - StageSizeX) / PhysicalSizeX);
3363 pp.Y = (float)((p[i].Y - StageSizeY) / PhysicalSizeY);
3364 ps[i] = pp;
3365 }
3366 return ps;
3367 }

◆ ToImageSpace() [5/5]

RectangleF BioLib.BioImage.ToImageSpace ( RectangleD p)

‍Convert a rectangle in physical space to a rectangle in image space

Parameters
RectangleD
Returns
A RectangleF object.
3374 {
3375 RectangleF r = new RectangleF();
3376 Point pp = new Point();
3377 r.X = (int)((p.X - StageSizeX) / PhysicalSizeX);
3378 r.Y = (int)((p.Y - StageSizeY) / PhysicalSizeY);
3379 r.Width = (int)(p.W / PhysicalSizeX);
3380 r.Height = (int)(p.H / PhysicalSizeY);
3381 return r;
3382 }

◆ ToImageSpaceX()

double BioLib.BioImage.ToImageSpaceX ( double x)

‍Convert a stage coordinate to an image coordinate

Parameters
xthe x coordinate of the point in the image
Returns
The return value is a double.
3305 {
3306 if (isPyramidal)
3307 return x;
3308 return (float)((x - StageSizeX) / PhysicalSizeX);
3309 }

◆ ToImageSpaceY()

double BioLib.BioImage.ToImageSpaceY ( double y)

‍Convert a Y coordinate from stage space to image space

Parameters
ythe y coordinate of the point in the image
Returns
The return value is the y-coordinate of the image.
3316 {
3317 if (isPyramidal)
3318 return y;
3319 return (float)((y - StageSizeY) / PhysicalSizeY);
3320 }

◆ ToShort()

void BioLib.BioImage.ToShort ( )
3008 {
3009 foreach (var b in Buffers)
3010 {
3011 b.ToShort();
3012 }
3013 AutoThreshold(this, true);
3014 StackThreshold(false);
3015 }

◆ ToStageSpace() [1/7]

PointD BioLib.BioImage.ToStageSpace ( PointD p)

‍This function converts a point in the image space to a point in the stage space

Parameters
PointDA class that contains an X and Y coordinate.
Returns
A PointD object.
3389 {
3390 PointD pp = new PointD();
3391 if (isPyramidal)
3392 {
3393 pp.X = ((p.X * Resolutions[Level].PhysicalSizeX) + Volume.Location.X);
3394 pp.Y = ((p.Y * Resolutions[Level].PhysicalSizeY) + Volume.Location.Y);
3395 return pp;
3396 }
3397 else
3398 {
3399 pp.X = ((p.X * PhysicalSizeX) + Volume.Location.X);
3400 pp.Y = ((p.Y * PhysicalSizeY) + Volume.Location.Y);
3401 return pp;
3402 }
3403 }

◆ ToStageSpace() [2/7]

static PointD BioLib.BioImage.ToStageSpace ( PointD p,
double physicalSizeX,
double physicalSizeY,
double volumeX,
double volumeY )
static

‍The function takes a point in the volume space and converts it to a point in the stage space

Parameters
PointDA custom class that holds an X and Y coordinate.
physicalSizeXThe width of the stage in mm
physicalSizeYThe height of the stage in mm
volumeXThe X coordinate of the top left corner of the volume in stage space.
volumeYThe Y position of the top left corner of the volume in stage space.
Returns
A PointD object.
3428 {
3429 PointD pp = new PointD();
3430 pp.X = ((p.X * physicalSizeX) + volumeX);
3431 pp.Y = ((p.Y * physicalSizeY) + volumeY);
3432 return pp;
3433 }

◆ ToStageSpace() [3/7]

PointD BioLib.BioImage.ToStageSpace ( PointD p,
int resolution )

Convert a point in the image space to a point in the stage space.

Parameters
PointDA point in the image space
resolutionthe resolution of the image (0, 1, 2, 3, 4)
Returns
A PointD object.
3411 {
3412 PointD pp = new PointD();
3413 pp.X = ((p.X * Resolutions[resolution].PhysicalSizeX) + Volume.Location.X);
3414 pp.Y = ((p.Y * Resolutions[resolution].PhysicalSizeY) + Volume.Location.Y);
3415 return pp;
3416 }

◆ ToStageSpace() [4/7]

PointD[] BioLib.BioImage.ToStageSpace ( PointD[] p)

‍This function takes a list of points in the coordinate system of the image and returns a list of points in the coordinate system of the stage

Parameters
pThe array of points to convert
Returns
A PointD[] array.
3475 {
3476 PointD[] ps = new PointD[p.Length];
3477 for (int i = 0; i < p.Length; i++)
3478 {
3479 PointD pp = new PointD();
3480 pp.X = ((p[i].X * PhysicalSizeX) + Volume.Location.X);
3481 pp.Y = ((p[i].Y * PhysicalSizeY) + Volume.Location.Y);
3482 ps[i] = pp;
3483 }
3484 return ps;
3485 }

◆ ToStageSpace() [5/7]

static PointD[] BioLib.BioImage.ToStageSpace ( PointD[] p,
double physicalSizeX,
double physicalSizeY,
double volumeX,
double volumeY )
static

It takes a list of points, and converts them from a coordinate system where the origin is in the center of the image, to a coordinate system where the origin is in the top left corner of the image.

Parameters
pthe array of points to convert
physicalSizeXThe width of the image in microns
physicalSizeYThe height of the image in microns
volumeXThe X position of the volume in stage space.
volumeYThe Y position of the top left corner of the volume in stage space.
Returns
A PointD array.
3498 {
3499 PointD[] ps = new PointD[p.Length];
3500 for (int i = 0; i < p.Length; i++)
3501 {
3502 PointD pp = new PointD();
3503 pp.X = ((p[i].X * physicalSizeX) + volumeX);
3504 pp.Y = ((p[i].Y * physicalSizeY) + volumeY);
3505 ps[i] = pp;
3506 }
3507 return ps;
3508 }

◆ ToStageSpace() [6/7]

RectangleD BioLib.BioImage.ToStageSpace ( RectangleD p)

‍Convert a rectangle from the coordinate space of the image to the coordinate space of the stage

Parameters
RectangleDA rectangle with double precision coordinates.
Returns
A RectangleD object.
3441 {
3442 RectangleD r = new RectangleD();
3443 r.X = ((p.X * PhysicalSizeX) + Volume.Location.X);
3444 r.Y = ((p.Y * PhysicalSizeY) + Volume.Location.Y);
3445 r.W = (p.W * PhysicalSizeX);
3446 r.H = (p.H * PhysicalSizeY);
3447 return r;
3448 }

◆ ToStageSpace() [7/7]

static RectangleD BioLib.BioImage.ToStageSpace ( RectangleD p,
double physicalSizeX,
double physicalSizeY,
double volumeX,
double volumeY )
static

‍This function takes a rectangle in the coordinate space of the image and converts it to the coordinate space of the stage

Parameters
RectangleDA rectangle with double precision.
physicalSizeXThe width of the physical screen in pixels
physicalSizeYThe height of the stage in pixels
volumeXThe X position of the volume in stage space.
volumeYThe Y position of the top of the volume in stage space.
Returns
A RectangleD object.
3460 {
3461 RectangleD r = new RectangleD();
3462 r.X = ((p.X * physicalSizeX) + volumeX);
3463 r.Y = ((p.Y * physicalSizeY) + volumeY);
3464 r.W = (p.W * physicalSizeX);
3465 r.H = (p.H * physicalSizeY);
3466 return r;
3467 }

◆ ToString()

override string BioLib.BioImage.ToString ( )

This function returns the filename of the object, and the location of the object in the 3D space.

Returns
The filename, and the location of the volume.
8776 {
8777 return "BioLib.Images.GetImage(\"" + id + "\")";
8778 }

◆ Update() [1/2]

void BioLib.BioImage.Update ( )

Update() is a function that calls the Update() function of the parent class

7755 {
7756 Update(this);
7757 }
void Update()
Definition Bio.cs:7754

◆ Update() [2/2]

static void BioLib.BioImage.Update ( BioImage b)
static

The function takes a BioImage object, opens the file, and returns a updated BioImage object.

Parameters
BioImageThis is the class that contains the image data.
7616 {
7617 b = OpenFile(b.file);
7618 }

◆ UpdateBuffersPyramidal()

async Task BioLib.BioImage.UpdateBuffersPyramidal ( )

Updates the Buffers based on current pyramidal origin and resolution.

7623 {
7624 try
7625 {
7626 if (Type != ImageType.pyramidal)
7627 return;
7628 for (int i = 0; i < Buffers.Count; i++)
7629 {
7630 Buffers[i].Dispose();
7631 }
7632 Buffers.Clear();
7633 for (int z = 0; z < SizeZ; z++)
7634 {
7635 for (int c = 0; c < SizeC; c++)
7636 {
7637 for (int t = 0; t < SizeT; t++)
7638 {
7639 ZCT co = new ZCT(z, c, t);
7640 if (openSlideImage != null)
7641 {
7642 startos:
7643 int lev = LevelFromResolution(this.Resolution);
7644 openslideBase.SetSliceInfo(lev, PixelFormat.Format24bppRgb, co);
7645 byte[] bts = openslideBase.GetSlice(new OpenSlideGTK.SliceInfo(PyramidalOrigin.X, PyramidalOrigin.Y, PyramidalSize.Width, PyramidalSize.Height, resolution));
7646 if (bts == null)
7647 {
7648 pyramidalOrigin = new PointD(0, 0);
7649 Resolution = GetUnitPerPixel(lev) * 1.1f;
7650 goto startos;
7651 }
7652 Buffers.Add(new Bitmap((int)Math.Round(OpenSlideBase.destExtent.Width), (int)Math.Round(OpenSlideBase.destExtent.Height), PixelFormat.Format24bppRgb, bts, co, ""));
7653 }
7654 else
7655 {
7656 start:
7657 int lev = LevelFromResolution(this.Resolution);
7658 byte[] bts = await slideBase.GetSlice(new BioLib.SliceInfo(Math.Round(PyramidalOrigin.X), Math.Round(PyramidalOrigin.Y), PyramidalSize.Width, PyramidalSize.Height, resolution, co));
7659 if (bts == null)
7660 {
7661 pyramidalOrigin = new PointD(0, 0);
7662 Resolution = GetUnitPerPixel(lev) * 1.1f;
7663 goto start;
7664 }
7665 Bitmap bmp = new Bitmap((int)Math.Round(SlideBase.destExtent.Width), (int)Math.Round(SlideBase.destExtent.Height), Resolutions[Level].PixelFormat, bts, co, "");
7666 Buffers.Add(bmp);
7667 }
7668 }
7669 }
7670 }
7671 BioImage.AutoThreshold(this, false);
7672 if (bitsPerPixel > 8)
7673 StackThreshold(true);
7674 else
7675 StackThreshold(false);
7676 }
7677 catch (Exception e)
7678 {
7679 Console.WriteLine(e.Message);
7680 }
7681 }
static void AutoThreshold(BioImage b, bool updateImageStats)
It takes a BioImage object, and calculates the mean histogram for each channel, and for the entire im...
Definition Bio.cs:8598

◆ UpdateBuffersWells()

void BioLib.BioImage.UpdateBuffersWells ( )
7684 {
7685 try
7686 {
7687 if (Type != ImageType.well)
7688 return;
7689 for (int i = 0; i < Buffers.Count; i++)
7690 {
7691 Buffers[i].Dispose();
7692 }
7693 Buffers.Clear();
7694 if (imRead.getSeries() != Level)
7695 this.imRead.setSeries(Level);
7696 int w = imRead.getSizeX();
7697 int h = imRead.getSizeY();
7698 for (int z = 0; z < SizeZ; z++)
7699 {
7700 for (int c = 0; c < SizeC; c++)
7701 {
7702 for (int t = 0; t < SizeT; t++)
7703 {
7704 byte[] bm = this.imRead.openBytes(Coords[z, c, t]);
7705 Bitmap bmp = new Bitmap(w, h, Resolutions[Level].PixelFormat, bm, new ZCT(z, c, t), "");
7706 bmp.Stats = Statistics.FromBytes(bmp);
7707 Buffers.Add(bmp);
7708 }
7709 }
7710 }
7711 BioImage.AutoThreshold(this, false);
7712 if (bitsPerPixel > 8)
7713 StackThreshold(true);
7714 else
7715 StackThreshold(false);
7716 }
7717 catch (Exception e)
7718 {
7719 Console.WriteLine(e.Message);
7720 }
7721 }

◆ UpdateCoords() [1/3]

void BioLib.BioImage.UpdateCoords ( )

It takes a list of images and assigns them to a 3D array of coordinates.

3124 {
3125 int z = 0;
3126 int c = 0;
3127 int t = 0;
3128 Coords = new int[SizeZ, SizeC, SizeT];
3129 for (int im = 0; im < Buffers.Count; im++)
3130 {
3131 ZCT co = new ZCT(z, c, t);
3132 SetFrameIndex(co.Z, co.C, co.T, im);
3133 Buffers[im].Coordinate = co;
3134 if (c < SizeC - 1)
3135 c++;
3136 else
3137 {
3138 c = 0;
3139 if (z < SizeZ - 1)
3140 z++;
3141 else
3142 {
3143 z = 0;
3144 if (t < SizeT - 1)
3145 t++;
3146 else
3147 t = 0;
3148 }
3149 }
3150 }
3151 }

◆ UpdateCoords() [2/3]

void BioLib.BioImage.UpdateCoords ( int sz,
int sc,
int st )

It takes the number of Z, C, and T planes in the image and then assigns each image buffer a coordinate in the ZCT space.

Parameters
szsize of the Z dimension
scnumber of channels
stnumber of time points
3159 {
3160 int z = 0;
3161 int c = 0;
3162 int t = 0;
3163 sizeZ = sz;
3164 sizeC = sc;
3165 sizeT = st;
3166 Coords = new int[sz, sc, st];
3167 for (int im = 0; im < Buffers.Count; im++)
3168 {
3169 ZCT co = new ZCT(z, c, t);
3170 SetFrameIndex(co.Z, co.C, co.T, im);
3171 Buffers[im].Coordinate = co;
3172 if (c < SizeC - 1)
3173 c++;
3174 else
3175 {
3176 c = 0;
3177 if (z < SizeZ - 1)
3178 z++;
3179 else
3180 {
3181 z = 0;
3182 if (t < SizeT - 1)
3183 t++;
3184 else
3185 t = 0;
3186 }
3187 }
3188 }
3189 }

◆ UpdateCoords() [3/3]

void BioLib.BioImage.UpdateCoords ( int sz,
int sc,
int st,
Order order )

It takes a list of images and assigns them to a 3D array of coordinates.

Parameters
szsize of the Z dimension
scnumber of channels
stnumber of time points
orderXYCZT or XYZCT
3197 {
3198 int z = 0;
3199 int c = 0;
3200 int t = 0;
3201 sizeZ = sz;
3202 sizeC = sc;
3203 sizeT = st;
3204 Coords = new int[sz, sc, st];
3205 int fr = sz * sc * st;
3206 if (order == Order.CZT)
3207 {
3208 for (int im = 0; im < fr; im++)
3209 {
3210 ZCT co = new ZCT(z, c, t);
3211 SetFrameIndex(co.Z, co.C, co.T, im);
3212 if (c < SizeC - 1)
3213 c++;
3214 else
3215 {
3216 c = 0;
3217 if (z < SizeZ - 1)
3218 z++;
3219 else
3220 {
3221 z = 0;
3222 if (t < SizeT - 1)
3223 t++;
3224 else
3225 t = 0;
3226 }
3227 }
3228 }
3229 }
3230 else if (order == Order.ZCT)
3231 {
3232 for (int im = 0; im < fr; im++)
3233 {
3234 ZCT co = new ZCT(z, c, t);
3235 SetFrameIndex(co.Z, co.C, co.T, im);
3236 if (z < SizeZ - 1)
3237 z++;
3238 else
3239 {
3240 z = 0;
3241 if (c < SizeC - 1)
3242 c++;
3243 else
3244 {
3245 c = 0;
3246 if (t < SizeT - 1)
3247 t++;
3248 else
3249 t = 0;
3250 }
3251 }
3252 }
3253 }
3254 else
3255 {
3256 //Order.TZC
3257 for (int im = 0; im < fr; im++)
3258 {
3259 ZCT co = new ZCT(z, c, t);
3260 SetFrameIndex(co.Z, co.C, co.T, im);
3261 if (t < SizeT - 1)
3262 t++;
3263 else
3264 {
3265 t = 0;
3266 if (z < SizeZ - 1)
3267 z++;
3268 else
3269 {
3270 z = 0;
3271 if (c < SizeC - 1)
3272 c++;
3273 else
3274 c = 0;
3275 }
3276 }
3277 }
3278 }
3279 }

◆ VipsSupport()

static bool BioLib.BioImage.VipsSupport ( string file)
static

The function checks if a given file is supported by the Vips library and returns true if it is, false otherwise.

Parameters
fileThe "file" parameter is a string that represents the file path of the TIFF image that you want to load using the NetVips library.
Returns
The method is returning a boolean value. If the try block is executed successfully, it will return true. If an exception is caught, it will return false.
7890 {
7891
7892 try
7893 {
7894 if (isOME(file))
7895 {
7896 return true;
7897 }
7898 netim = NetVips.Image.Tiffload(file);
7899 Settings.AddSettings("VipsSupport", "true");
7900 netim.Close();
7901 netim.Dispose();
7902 }
7903 catch (Exception e)
7904 {
7905 Console.WriteLine(e.ToString());
7906 return false;
7907 }
7908 return true;
7909 }

Member Data Documentation

◆ rgbChannels

int [] BioLib.BioImage.rgbChannels = new int[3] { 0, 1, 2 }
1986{ 0, 1, 2 };

Property Documentation

◆ AnnotationsB

List<ROI> BioLib.BioImage.AnnotationsB
get
2411 {
2412 get
2413 {
2414 return GetAnnotations(Coordinate.Z, BChannel.Index, Coordinate.T);
2415 }
2416 }

◆ AnnotationsG

List<ROI> BioLib.BioImage.AnnotationsG
get
2403 {
2404 get
2405 {
2406 return GetAnnotations(Coordinate.Z, GChannel.Index, Coordinate.T);
2407 }
2408 }

◆ AnnotationsR

List<ROI> BioLib.BioImage.AnnotationsR
get
2395 {
2396 get
2397 {
2398 return GetAnnotations(Coordinate.Z, RChannel.Index, Coordinate.T);
2399 }
2400 }

◆ BChannel

Channel BioLib.BioImage.BChannel
get
2384 {
2385 get
2386 {
2387 if (Channels.Count >= 3)
2388 return Channels[rgbChannels[2]];
2389 else
2390 return Channels[0];
2391 }
2392 }

◆ BRange

IntRange BioLib.BioImage.BRange
get
2602 {
2603 get
2604 {
2605 return BChannel.RangeB;
2606 }
2607 }

◆ Coordinate

ZCT BioLib.BioImage.Coordinate
getset
1923 {
1924 get
1925 {
1926 return coordinate;
1927 }
1928 set
1929 {
1930 coordinate = value;
1931 }
1932 }

◆ Filename

string BioLib.BioImage.Filename
getset
1974 {
1975 get
1976 {
1977 if (filename == null || filename == "")
1978 return Type.ToString() + ".ome.tif";
1979 return filename;
1980 }
1981 set
1982 {
1983 filename = value;
1984 }
1985 }

◆ GChannel

Channel BioLib.BioImage.GChannel
get
2374 {
2375 get
2376 {
2377 if (Channels.Count >= 3)
2378 return Channels[rgbChannels[1]];
2379 else
2380 return Channels[0];
2381 }
2382 }

◆ GRange

IntRange BioLib.BioImage.GRange
get
2595 {
2596 get
2597 {
2598 return GChannel.RangeG;
2599 }
2600 }

◆ ID

string BioLib.BioImage.ID
getset
2237 {
2238 get { return id; }
2239 set { id = value; }
2240 }

◆ ImageCount

int BioLib.BioImage.ImageCount
get
2242 {
2243 get
2244 {
2245 return Buffers.Count;
2246 }
2247 }

◆ Initialized

bool BioLib.BioImage.Initialized
staticget
2672 {
2673 get
2674 {
2675 return initialized;
2676 }
2677 }

◆ isPyramidal

bool BioLib.BioImage.isPyramidal
get
2647 {
2648 get
2649 {
2650 if (Type == ImageType.pyramidal)
2651 return true;
2652 else
2653 return false;
2654 }
2655 }

◆ isRGB

bool BioLib.BioImage.isRGB
get
2617 {
2618 get
2619 {
2620 if (RGBChannelCount == 3 || RGBChannelCount == 4)
2621 return true;
2622 else
2623 return false;
2624 }
2625 }

◆ isSeries

bool BioLib.BioImage.isSeries
get
2637 {
2638 get
2639 {
2640 if (seriesCount > 1)
2641 return true;
2642 else
2643 return false;
2644 }
2645 }

◆ isTime

bool BioLib.BioImage.isTime
get
2627 {
2628 get
2629 {
2630 if (SizeT > 1)
2631 return true;
2632 else
2633 return false;
2634 }
2635 }

◆ LabelResolution

int? BioLib.BioImage.LabelResolution
getset
3027{ get; set; }

◆ Level

int BioLib.BioImage.Level
getset
1947 {
1948 get
1949 {
1950 if (Type == ImageType.well)
1951 return level;
1952 int l = 0;
1953 if (openslideBase != null)
1954 l = OpenSlideGTK.TileUtil.GetLevel(openslideBase.Schema.Resolutions, Resolution);
1955 else
1956 if (slideBase != null)
1958 if (l < 0)
1959 return 0;
1960 return l;
1961 }
1962 set
1963 {
1964 if (value < 0)
1965 return;
1966 level = value;
1967 }
1968 }

◆ MacroResolution

int? BioLib.BioImage.MacroResolution
getset
3026{ get; set; }

◆ Magnification

double BioLib.BioImage.Magnification
getset
2579 {
2580 get; set;
2581 }

◆ OpenSlideBase

OpenSlideBase BioLib.BioImage.OpenSlideBase
get
2360{ get { return openslideBase; } }

◆ PhysicalSizeX

double BioLib.BioImage.PhysicalSizeX
get
2249 {
2250 get
2251 {
2252 if (isPyramidal)
2253 return Resolutions[Level].PhysicalSizeX;
2254 else
2255 if (Plate != null)
2256 return Resolutions[serie].PhysicalSizeX;
2257 else if (Resolutions.Count > 0)
2258 return Resolutions[0].PhysicalSizeX;
2259 else
2260 return 0;
2261 }
2262 }

◆ PhysicalSizeY

double BioLib.BioImage.PhysicalSizeY
get
2264 {
2265 get
2266 {
2267 if (isPyramidal)
2268 return Resolutions[Level].PhysicalSizeY;
2269 else
2270 if (Plate != null)
2271 return Resolutions[serie].PhysicalSizeY;
2272 else if (Resolutions.Count > 0)
2273 return Resolutions[0].PhysicalSizeY;
2274 else
2275 return 0;
2276 }
2277 }

◆ PhysicalSizeZ

double BioLib.BioImage.PhysicalSizeZ
get
2279 {
2280 get
2281 {
2282 if (isPyramidal)
2283 return Resolutions[Level].PhysicalSizeZ;
2284 else
2285 if (Plate != null)
2286 return Resolutions[serie].PhysicalSizeZ;
2287 else if (Resolutions.Count > 0)
2288 return Resolutions[0].PhysicalSizeZ;
2289 else
2290 return 0;
2291 }
2292 }

◆ PyramidalOrigin

PointD BioLib.BioImage.PyramidalOrigin
getset
2339 {
2340 get { return pyramidalOrigin; }
2341 set
2342 {
2343 pyramidalOrigin = value;
2344 }
2345 }

◆ PyramidalSize

AForge.Size BioLib.BioImage.PyramidalSize
getset
2336{ get { return s; } set { s = value; } }

◆ RChannel

Channel BioLib.BioImage.RChannel
get
2364 {
2365 get
2366 {
2367 if(Channels.Count >= 3)
2368 return Channels[rgbChannels[0]];
2369 else
2370 return Channels[0];
2371 }
2372 }

◆ Resolution

double BioLib.BioImage.Resolution
getset
2018 {
2019 get { return resolution; }
2020 set
2021 {
2022 if (value < 0)
2023 return;
2024 resolution = value;
2025 }
2026 }

◆ RGBChannelCount

int BioLib.BioImage.RGBChannelCount
get
1988 {
1989 get
1990 {
1991 return Buffers[0].RGBChannelsCount;
1992 }
1993 }

◆ RRange

IntRange BioLib.BioImage.RRange
get
2588 {
2589 get
2590 {
2591 return RChannel.RangeR;
2592 }
2593 }

◆ SelectedBuffer

Bitmap BioLib.BioImage.SelectedBuffer
get
2609 {
2610 get
2611 {
2612 return Buffers[GetFrameIndex(Coordinate.Z, Coordinate.C, Coordinate.T)];
2613 }
2614 }

◆ series

int BioLib.BioImage.series
getset
2347 {
2348 get
2349 {
2350 return imageInfo.Series;
2351 }
2352 set
2353 {
2354 imageInfo.Series = value;
2355 }
2356 }

◆ SizeC

int BioLib.BioImage.SizeC
get
2564 {
2565 get { return sizeC; }
2566 }

◆ SizeT

int BioLib.BioImage.SizeT
get
2568 {
2569 get { return sizeT; }
2570 }

◆ SizeX

int BioLib.BioImage.SizeX
get
2542 {
2543 get
2544 {
2545 if (Buffers.Count > 0)
2546 return Buffers[0].SizeX;
2547 else return 0;
2548 }
2549 }

◆ SizeY

int BioLib.BioImage.SizeY
get
2551 {
2552 get
2553 {
2554 if (Buffers.Count > 0)
2555 return Buffers[0].SizeY;
2556 else return 0;
2557 }
2558 }

◆ SizeZ

int BioLib.BioImage.SizeZ
get
2560 {
2561 get { return sizeZ; }
2562 }

◆ SlideBase

SlideBase BioLib.BioImage.SlideBase
getset
2362{ get { return slideBase; } set { slideBase = value; } }

◆ StackOrder

Order BioLib.BioImage.StackOrder
getset
2583 {
2584 get; set;
2585 }

◆ StageSizeX

double BioLib.BioImage.StageSizeX
get
2294 {
2295 get
2296 {
2297 if (isPyramidal)
2298 return Resolutions[Level].StageSizeX;
2299 else
2300 if (Plate != null)
2301 return Resolutions[serie].StageSizeX;
2302 else
2303 return Resolutions[0].StageSizeX;
2304 }
2305
2306 }

◆ StageSizeY

double BioLib.BioImage.StageSizeY
get
2308 {
2309 get
2310 {
2311 if (isPyramidal)
2312 return Resolutions[Level].StageSizeY;
2313 else
2314 if (Plate != null)
2315 return Resolutions[serie].StageSizeY;
2316 else
2317 return Resolutions[0].StageSizeY;
2318 }
2319
2320 }

◆ StageSizeZ

double BioLib.BioImage.StageSizeZ
get
2322 {
2323 get
2324 {
2325 if (isPyramidal)
2326 return Resolutions[Level].StageSizeZ;
2327 else
2328 if (Plate != null)
2329 return Resolutions[serie].StageSizeZ;
2330 else
2331 return Resolutions[0].StageSizeZ;
2332 }
2333 }

◆ Statistics

Statistics BioLib.BioImage.Statistics
getset
2004 {
2005 get
2006 {
2007 return statistics;
2008 }
2009 set
2010 {
2011 statistics = value;
2012 }
2013 }

◆ Status

string BioLib.BioImage.Status
staticgetset
2659 {
2660 get
2661 {
2662 return stat;
2663 }
2664 set
2665 {
2666 stat = value;
2667 Console.WriteLine(stat);
2668 }
2669 }

◆ Tag

object BioLib.BioImage.Tag
getset
2586{ get; set; }

◆ Type

ImageType BioLib.BioImage.Type
getset
1940{ get; set; }

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