BioLib  3.9.1
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)
 
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.
 
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 (int level)
 Updates the Buffers based on current pyramidal origin and resolution.
 
void UpdateBuffersWells ()
 
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 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 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 SKImage Convert16bppBitmapToSKImage (Bitmap sourceBitmap)
 
static SKImage BitmapToSKImage (AForge.Bitmap bitm)
 
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 GLContext Context
 
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]
 
bool UseOSMNegativeY = true [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
7245 {
7246 OpenSlide,
7247 Bioformats,
7248 LibVips,
7249 }

◆ ImageType

enum BioLib.BioImage.ImageType
1947 {
1948 stack,
1949 pyramidal,
1950 well,
1951 }

◆ Order

enum BioLib.BioImage.Order
2639 {
2640 ZCT,
2641 CZT,
2642 TCZ
2643 }

Constructor & Destructor Documentation

◆ BioImage()

BioLib.BioImage.BioImage ( string file)
3577 {
3578 id = file;
3579 this.file = file;
3580 filename = Images.GetImageName(id);
3581 Coordinate = new ZCT();
3582 rgbChannels[0] = 0;
3583 rgbChannels[1] = 0;
3584 rgbChannels[2] = 0;
3585 }

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.

9216 {
9217 AutoThreshold(bstats, update);
9218 }
static void AutoThreshold()
It takes the current image, and finds the best threshold value for it.
Definition Bio.cs:9215

◆ 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.
9142 {
9143 bstats = b;
9144 Statistics statistics = null;
9145 if (b.bitsPerPixel > 8)
9146 statistics = new Statistics(true);
9147 else
9148 statistics = new Statistics(false);
9149 for (int i = 0; i < b.Buffers.Count; i++)
9150 {
9151 if (b.Buffers[i].Stats == null || updateImageStats)
9152 b.Buffers[i].Stats = Statistics.FromBytes(b.Buffers[i]);
9153 if (b.Buffers[i].RGBChannelsCount == 1)
9154 statistics.AddStatistics(b.Buffers[i].Stats[0]);
9155 else
9156 {
9157 for (int r = 0; r < b.Buffers[i].RGBChannelsCount; r++)
9158 {
9159 statistics.AddStatistics(b.Buffers[i].Stats[r]);
9160 }
9161 }
9162 }
9163 for (int c = 0; c < b.Channels.Count; c++)
9164 {
9165 Statistics[] sts = new Statistics[b.Buffers[0].RGBChannelsCount];
9166 for (int i = 0; i < b.Buffers[0].RGBChannelsCount; i++)
9167 {
9168 if (b.bitsPerPixel > 8)
9169 {
9170 sts[i] = new Statistics(true);
9171 }
9172 else
9173 sts[i] = new Statistics(false);
9174 }
9175 for (int z = 0; z < b.SizeZ; z++)
9176 {
9177 for (int t = 0; t < b.SizeT; t++)
9178 {
9179 int ind;
9180 if (b.Channels.Count > b.SizeC)
9181 {
9182 ind = b.GetFrameIndex(z, 0, t);
9183 }
9184 else
9185 ind = b.GetFrameIndex(z, c, t);
9186 if (b.Buffers[ind].RGBChannelsCount == 1)
9187 sts[0].AddStatistics(b.Buffers[ind].Stats[0]);
9188 else
9189 {
9190 sts[0].AddStatistics(b.Buffers[ind].Stats[0]);
9191 sts[1].AddStatistics(b.Buffers[ind].Stats[1]);
9192 sts[2].AddStatistics(b.Buffers[ind].Stats[2]);
9193 if (b.Buffers[ind].RGBChannelsCount == 4)
9194 sts[3].AddStatistics(b.Buffers[ind].Stats[3]);
9195 }
9196 }
9197 }
9198 if (b.RGBChannelCount == 1)
9199 sts[0].MeanHistogram();
9200 else
9201 {
9202 sts[0].MeanHistogram();
9203 sts[1].MeanHistogram();
9204 sts[2].MeanHistogram();
9205 if (b.Buffers[0].RGBChannelsCount == 4)
9206 sts[3].MeanHistogram();
9207 }
9208 b.Channels[c].stats = sts;
9209 }
9210 statistics.MeanHistogram();
9211 b.statistics = statistics;
9212 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), true, b, updateImageStats);
9213 }
Definition Recorder.cs:12
Definition Bio.cs:52

◆ 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.
9223 {
9224 bstats = b;
9225 Thread th = new Thread(AutoThreshold);
9226 th.Start();
9227 }

◆ 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.
3153 {
3154 Bake(new IntRange(rmin, rmax), new IntRange(gmin, gmax), new IntRange(bmin, bmax));
3155 }
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:3152

◆ 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
3163 {
3164 BioImage bm = new BioImage(Images.GetImageName(ID));
3165 bm = CopyInfo(this, true, true);
3166 for (int i = 0; i < Buffers.Count; i++)
3167 {
3168 ZCT co = Buffers[i].Coordinate;
3169 UnmanagedImage b = GetFiltered(i, rf, gf, bf);
3170 Bitmap inf = new Bitmap(bm.ID, b, co, i);
3171 bm.SetFrameIndex(co.Z, co.C, co.T, i);
3172 bm.Buffers.Add(inf);
3173 }
3174 foreach (Channel item in bm.Channels)
3175 {
3176 for (int i = 0; i < item.range.Length; i++)
3177 {
3178 item.range[i].Min = 0;
3179 if (bm.bitsPerPixel > 8)
3180 item.range[i].Max = ushort.MaxValue;
3181 else
3182 item.range[i].Max = 255;
3183 }
3184 }
3185 AutoThreshold(bm, true);
3186 Images.AddImage(bm);
3187 }
Definition Bio.cs:1861
Bitmap GetFiltered(ZCT coord, IntRange r, IntRange g, IntRange b)
Definition Bio.cs:4142
static BioImage CopyInfo(BioImage b, bool copyAnnotations, bool copyChannels)
Definition Bio.cs:2146

◆ BitmapToSKImage()

static SKImage BioLib.BioImage.BitmapToSKImage ( AForge.Bitmap bitm)
static
8193 {
8194 if (bitm.PixelFormat == PixelFormat.Format24bppRgb)
8195 return Convert24bppBitmapToSKImage(bitm);
8196 if (bitm.PixelFormat == PixelFormat.Format32bppArgb)
8197 return Convert32bppBitmapToSKImage(bitm);
8198 if (bitm.PixelFormat == PixelFormat.Float)
8199 return Convert32bppBitmapToSKImage(bitm.GetImageRGBA());
8200 if (bitm.PixelFormat == PixelFormat.Format16bppGrayScale)
8201 return Convert16bppBitmapToSKImage(bitm.GetImageRGBA());
8202 if (bitm.PixelFormat == PixelFormat.Format48bppRgb)
8203 return Convert16bppBitmapToSKImage(bitm.GetImageRGBA());
8204 if (bitm.PixelFormat == PixelFormat.Format8bppIndexed)
8205 return Convert8bppBitmapToSKImage(bitm);
8206 else
8207 throw new NotSupportedException("PixelFormat " + bitm.PixelFormat + " is not supported for SKImage.");
8208 }

◆ 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.
9267 {
9268 if (b.RGBChannelsCount == 1)
9269 {
9270 long sum = 0;
9271 long sumOfSquaresR = 0;
9272 for (int y = 0; y < b.SizeY; y++)
9273 for (int x = 0; x < b.SizeX; x++)
9274 {
9275 ColorS pixel = b.GetPixel(x, y);
9276 sum += pixel.R;
9277 sumOfSquaresR += pixel.R * pixel.R;
9278 }
9279 return sumOfSquaresR * b.SizeX * b.SizeY - sum * sum;
9280 }
9281 else
9282 {
9283 long sum = 0;
9284 long sumOfSquares = 0;
9285 for (int y = 0; y < b.SizeY; y++)
9286 for (int x = 0; x < b.SizeX; x++)
9287 {
9288 ColorS pixel = b.GetPixel(x, y);
9289 int p = (pixel.R + pixel.G + pixel.B) / 3;
9290 sum += p;
9291 sumOfSquares += p * p;
9292 }
9293 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), true, b);
9294 return sumOfSquares * b.SizeX * b.SizeY - sum * sum;
9295 }
9296 }

◆ Convert16bppBitmapToSKImage()

static SKImage BioLib.BioImage.Convert16bppBitmapToSKImage ( Bitmap sourceBitmap)
static
8159 {
8160 Bitmap bm = sourceBitmap.GetImageRGBA();
8161 int width = bm.Width;
8162 int height = bm.Height;
8163
8164 SKBitmap skBitmap = new SKBitmap(width, height, SKColorType.Bgra8888, SKAlphaType.Opaque);
8165
8166 BitmapData bitmapData = sourceBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bm.PixelFormat);
8167
8168 unsafe
8169 {
8170 byte* sourcePtr = (byte*)bm.Data.ToPointer();
8171 byte* destPtr = (byte*)skBitmap.GetPixels().ToPointer();
8172
8173 for (int y = 0; y < height; y++)
8174 {
8175 for (int x = 0; x < width; x++)
8176 {
8177 destPtr[0] = sourcePtr[0]; // Blue
8178 destPtr[1] = sourcePtr[1]; // Green
8179 destPtr[2] = sourcePtr[2]; // Red
8180 destPtr[3] = 255; // Alpha (fully opaque)
8181
8182 sourcePtr += 3;
8183 destPtr += 4;
8184 }
8185 }
8186 }
8187
8188 sourceBitmap.UnlockBits(bitmapData);
8189
8190 return SKImage.FromBitmap(skBitmap);
8191 }

◆ 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.
2136 {
2137 return BioImage.Copy(this, true);
2138 }
static BioImage Copy(BioImage b, bool rois)
Definition Bio.cs:2057

◆ 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.
2120 {
2121 return Copy(b, true);
2122 }
BioImage Copy()
Definition Bio.cs:2135

◆ 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.
2058 {
2059 BioImage bi = new BioImage(b.ID);
2060 if (rois)
2061 foreach (ROI an in b.Annotations)
2062 {
2063 bi.Annotations.Add(an);
2064 }
2065 foreach (Bitmap bf in b.Buffers)
2066 {
2067 bi.Buffers.Add(bf.Copy());
2068 }
2069 foreach (Channel c in b.Channels)
2070 {
2071 bi.Channels.Add(c);
2072 }
2073 bi.Volume = b.Volume;
2074 bi.Coords = b.Coords;
2075 bi.sizeZ = b.sizeZ;
2076 bi.sizeC = b.sizeC;
2077 bi.sizeT = b.sizeT;
2078 bi.series = b.series;
2079 bi.seriesCount = b.seriesCount;
2080 bi.frameInterval = b.frameInterval;
2081 bi.littleEndian = b.littleEndian;
2082 bi.isGroup = b.isGroup;
2083 bi.imageInfo = b.imageInfo;
2084 bi.bitsPerPixel = b.bitsPerPixel;
2085 bi.file = b.file;
2086 bi.filename = b.filename;
2087 foreach (var item in b.Resolutions)
2088 {
2089 bi.Resolutions.Add(item);
2090 }
2091 bi.statistics = b.statistics;
2092 bi.MacroResolution = b.MacroResolution;
2093 bi.LabelResolution = b.LabelResolution;
2094 bi.Resolution = b.Resolution;
2095 bi.imagesPerSeries = b.imagesPerSeries;
2096 bi.imRead = b.imRead;
2097 bi.Type = b.Type;
2098 bi.tifRead = b.tifRead;
2099 if (b.OpenSlideBase != null)
2100 {
2101 bi.openslideBase = b.openslideBase;
2102 bi.openSlideImage = b.openSlideImage;
2103 }
2104 else
2105 {
2106 bi.slideBase = b.slideBase;
2107 }
2108 bi.PyramidalOrigin = b.PyramidalOrigin;
2109 bi.PyramidalSize = b.PyramidalSize;
2110 bi.Plate = b.Plate;
2111 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, b, rois);
2112 return bi;
2113 }
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.
2129 {
2130 return BioImage.Copy(this, rois);
2131 }

◆ 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.
2147 {
2148 BioImage bi = new BioImage(b.ID);
2149 if (copyAnnotations)
2150 foreach (ROI an in b.Annotations)
2151 {
2152 bi.Annotations.Add(an);
2153 }
2154 if (copyChannels)
2155 foreach (Channel c in b.Channels)
2156 {
2157 bi.Channels.Add(c.Copy());
2158 }
2159 foreach (var item in b.Resolutions)
2160 {
2161 bi.Resolutions.Add(item);
2162 }
2163 bi.Coords = b.Coords;
2164 bi.Volume = b.Volume;
2165 bi.sizeZ = b.sizeZ;
2166 bi.sizeC = b.sizeC;
2167 bi.sizeT = b.sizeT;
2168 bi.series = b.series;
2169 bi.seriesCount = b.seriesCount;
2170 bi.frameInterval = b.frameInterval;
2171 bi.littleEndian = b.littleEndian;
2172 bi.isGroup = b.isGroup;
2173 bi.imageInfo = b.imageInfo;
2174 bi.bitsPerPixel = b.bitsPerPixel;
2175 bi.Coordinate = b.Coordinate;
2176 bi.file = b.file;
2177 bi.Filename = b.Filename;
2178 bi.ID = Images.GetImageName(b.file);
2179 bi.statistics = b.statistics;
2180 bi.MacroResolution = b.MacroResolution;
2181 bi.LabelResolution = b.LabelResolution;
2182 bi.Resolution = b.Resolution;
2183 bi.imagesPerSeries = b.imagesPerSeries;
2184 bi.imRead = b.imRead;
2185 bi.tifRead = b.tifRead;
2186 bi.Type = b.Type;
2187 bi.PyramidalOrigin = b.PyramidalOrigin;
2188 bi.PyramidalSize = b.PyramidalSize;
2189 if (b.OpenSlideBase != null)
2190 {
2191 bi.openslideBase = b.openslideBase;
2192 bi.openSlideImage = b.openSlideImage;
2193 }
2194 else
2195 {
2196 bi.slideBase = b.slideBase;
2197 }
2198 bi.Plate = b.Plate;
2199 return bi;
2200 }

◆ 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.

9300 {
9301 for (int i = 0; i < Buffers.Count; i++)
9302 {
9303 Buffers[i].Dispose();
9304 }
9305 for (int i = 0; i < Channels.Count; i++)
9306 {
9307 Channels[i].Dispose();
9308 }
9309 for (int i = 0; i < Annotations.Count; i++)
9310 {
9311 Annotations[i].Dispose();
9312 }
9313 }

◆ 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
9101 {
9102 string[] fs = Directory.GetFiles(path);
9103 int i = 0;
9104 foreach (string f in fs)
9105 {
9106 List<ROI> annotations = OpenOMEROIs(f, 0);
9107 string ff = Path.GetFileNameWithoutExtension(f);
9108 ExportROIsCSV(path + "//" + ff + "-" + i.ToString() + ".csv", annotations);
9109 i++;
9110 }
9111 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, path, filename);
9112 }
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:9067
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:8484

◆ 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
9068 {
9069 string con = columns;
9070 con += ROIsToString(Annotations);
9071 File.WriteAllText(filename, con);
9072 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, filename, Annotations);
9073 }
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:8868

◆ 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.
6363 {
6364 try
6365 {
6366 // Validate inputs
6367 if (b == null) throw new ArgumentNullException(nameof(b));
6368 if (b.vipPages == null || b.vipPages.Count <= level) throw new ArgumentException("Invalid image level.");
6369
6370 // Extract the region from the specified level
6371 NetVips.Image subImage = b.vipPages[level].ExtractArea(x, y, width, height);
6372
6373 // Convert the NetVips.Image to Bitmap
6374 Bitmap bitmap = ConvertVipsImageToBitmap(subImage, b.bitsPerPixel);
6375
6376 // Clean up
6377 subImage.Dispose();
6378
6379 return bitmap;
6380 }
6381 catch (Exception ex)
6382 {
6383 Console.WriteLine($"Error: {ex.Message}\n{ex.StackTrace}");
6384 return null;
6385 }
6386 }

◆ 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.
6255 {
6256 BioImage b = new BioImage(files[0]);
6257 for (int i = 0; i < files.Length; i++)
6258 {
6259 BioImage bb = OpenFile(files[i], false);
6260 b.Buffers.AddRange(bb.Buffers);
6261 }
6262 b.UpdateCoords(sizeZ, sizeC, sizeT);
6263 Images.AddImage(b);
6264 return b;
6265 }
static BioImage OpenFile(string file)
This function opens a file and returns a BioImage object.
Definition Bio.cs:4859
void UpdateCoords()
It takes a list of images and assigns them to a 3D array of coordinates.
Definition Bio.cs:3189

◆ 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.
9240 {
9241 long mf = 0;
9242 int fr = 0;
9243 List<double> dt = new List<double>();
9244 ZCT c = new ZCT(0, 0, 0);
9245 for (int i = 0; i < im.SizeZ; i++)
9246 {
9247 long f = CalculateFocusQuality(im.Buffers[im.GetFrameIndex(i, Channel, Time)]);
9248 dt.Add(f);
9249 if (f > mf)
9250 {
9251 mf = f;
9252 fr = im.GetFrameIndex(i, Channel, Time);
9253 }
9254 }
9255
9256 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, im, Channel, Time);
9257 return fr;
9258 }
static long CalculateFocusQuality(Bitmap b)
The function calculates the focus quality of a given bitmap image.
Definition Bio.cs:9266

◆ 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.
6272 {
6273 string[] files = Directory.GetFiles(path);
6274 BioImage b = new BioImage(files[0]);
6275 int z = 0;
6276 int c = 0;
6277 int t = 0;
6278 BioImage bb = null;
6279 for (int i = 0; i < files.Length; i++)
6280 {
6281 string[] st = files[i].Split('_');
6282 if (st.Length > 3)
6283 {
6284 z = int.Parse(st[1].Replace("Z", ""));
6285 c = int.Parse(st[2].Replace("C", ""));
6286 t = int.Parse(st[3].Replace("T", ""));
6287 }
6288 bb = OpenFile(files[i], tab);
6289 b.Buffers.AddRange(bb.Buffers);
6290 }
6291 if (z == 0)
6292 {
6293 /*TO DO
6294 ImagesToStack im = new ImagesToStack();
6295 if (im.ShowDialog() != DialogResult.OK)
6296 return null;
6297 b.UpdateCoords(im.SizeZ, im.SizeC, im.SizeT);
6298 */
6299 }
6300 else
6301 b.UpdateCoords(z + 1, c + 1, t + 1);
6302 Images.AddImage(b);
6303 return b;
6304 }

◆ FromNumpy()

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

Converts a numpy array to BioImage.

Parameters
file
Returns
6031 {
6032 BioImage bm = new BioImage(file);
6033 var (shape, dataType, data) = NumPy.ReadNpyFile(file);
6034
6035 // Handle different shapes and cast the data into appropriate multi-dimensional arrays
6036 if (shape.Length == 5)
6037 {
6038 if (dataType == NumPy.NpyDataType.Float32)
6039 {
6040 float[,,,,] fs = NumPy.ConvertToMultidimensional<float, float[,,,,]>(data, shape);
6041 for (int z = 0; z < shape[2]; z++)
6042 {
6043 for (int c = 0; c < shape[1]; c++)
6044 {
6045 for (int t = 0; t < shape[0]; t++)
6046 {
6047 Bitmap b = new Bitmap(shape[3], shape[4], PixelFormat.Float);
6048 for (int y = 0; y < shape[4]; y++)
6049 {
6050 for (int x = 0; x < shape[3]; x++)
6051 {
6052 b.SetValue(x, y, fs[t, c, z, x, y]);
6053 }
6054 }
6055 bm.Buffers.Add(b);
6056 }
6057 }
6058 }
6059 }
6060 else if (dataType == NumPy.NpyDataType.UInt8)
6061 {
6062 uint[,,,,] fs = NumPy.ConvertToMultidimensional<uint, uint[,,,,]>(data, shape);
6063 for (int z = 0; z < shape[2]; z++)
6064 {
6065 for (int c = 0; c < shape[1]; c++)
6066 {
6067 for (int t = 0; t < shape[0]; t++)
6068 {
6069 Bitmap b = new Bitmap(shape[3], shape[4], PixelFormat.Format8bppIndexed);
6070 for (int y = 0; y < shape[4]; y++)
6071 {
6072 for (int x = 0; x < shape[3]; x++)
6073 {
6074 b.SetValue(x, y, fs[t, c, z, x, y]);
6075 }
6076 }
6077 bm.Buffers.Add(b);
6078 }
6079 }
6080 }
6081 }
6082 bm.sizeZ = shape[2];
6083 bm.sizeC = shape[1];
6084 bm.sizeT = shape[0];
6085 }
6086 else if (shape.Length == 4)
6087 {
6088 if (dataType == NumPy.NpyDataType.Float32)
6089 {
6090 float[,,,] fs = NumPy.ConvertToMultidimensional<float, float[,,,]>(data, shape);
6091 for (int z = 0; z < shape[1]; z++)
6092 {
6093 for (int c = 0; c < shape[0]; c++)
6094 {
6095 Bitmap b = new Bitmap(shape[2], shape[3], PixelFormat.Float);
6096 for (int y = 0; y < shape[3]; y++)
6097 {
6098 for (int x = 0; x < shape[2]; x++)
6099 {
6100 b.SetValue(x, y, fs[c, z, x, y]);
6101 }
6102 }
6103 bm.Buffers.Add(b);
6104 }
6105 }
6106 }
6107 else if (dataType == NumPy.NpyDataType.UInt8)
6108 {
6109 uint[,,,] fs = NumPy.ConvertToMultidimensional<uint, uint[,,,]>(data, shape);
6110 for (int z = 0; z < shape[1]; z++)
6111 {
6112 for (int c = 0; c < shape[0]; c++)
6113 {
6114 Bitmap b = new Bitmap(shape[2], shape[3], PixelFormat.Format8bppIndexed);
6115 for (int y = 0; y < shape[3]; y++)
6116 {
6117 for (int x = 0; x < shape[2]; x++)
6118 {
6119 b.SetValue(x, y, fs[c, z, x, y]);
6120 }
6121 }
6122 bm.Buffers.Add(b);
6123 }
6124 }
6125 }
6126 bm.sizeZ = shape[1];
6127 bm.sizeC = shape[0];
6128 }
6129 else if (shape.Length == 3)
6130 {
6131 if (dataType == NumPy.NpyDataType.Float32)
6132 {
6133 float[,,] fs = NumPy.ConvertToMultidimensional<float, float[,,]>(data, shape);
6134 for (int z = 0; z < shape[0]; z++)
6135 {
6136 Bitmap b = new Bitmap(shape[1], shape[2], PixelFormat.Float);
6137 for (int y = 0; y < shape[1]; y++)
6138 {
6139 for (int x = 0; x < shape[2]; x++)
6140 {
6141 b.SetValue(x, y, fs[z, x, y]);
6142 }
6143 }
6144 bm.Buffers.Add(b);
6145 }
6146 }
6147 else if (dataType == NumPy.NpyDataType.UInt8)
6148 {
6149 uint[,,] fs = NumPy.ConvertToMultidimensional<uint, uint[,,]>(data, shape);
6150 for (int z = 0; z < shape[0]; z++)
6151 {
6152 Bitmap b = new Bitmap(shape[1], shape[2], PixelFormat.Format8bppIndexed);
6153 for (int y = 0; y < shape[1]; y++)
6154 {
6155 for (int x = 0; x < shape[2]; x++)
6156 {
6157 b.SetValue(x, y, fs[z, x, y]);
6158 }
6159 }
6160 bm.Buffers.Add(b);
6161 }
6162 }
6163 bm.sizeZ = shape[0];
6164 bm.sizeC = 1;
6165 }
6166 else if (shape.Length == 2)
6167 {
6168 if (dataType == NumPy.NpyDataType.Float32)
6169 {
6170 float[,] fs = NumPy.ConvertToMultidimensional<float, float[,]>(data, shape);
6171 Bitmap b = new Bitmap(shape[0], shape[1], PixelFormat.Float);
6172 for (int y = 0; y < shape[1]; y++)
6173 {
6174 for (int x = 0; x < shape[0]; x++)
6175 {
6176 b.SetValue(x, y, fs[x, y]);
6177 }
6178 }
6179 bm.Buffers.Add(b);
6180 }
6181 else if (dataType == NumPy.NpyDataType.UInt8)
6182 {
6183 uint[,] fs = NumPy.ConvertToMultidimensional<uint, uint[,]>(data, shape);
6184 Bitmap b = new Bitmap(shape[0], shape[1], PixelFormat.Format8bppIndexed);
6185 for (int y = 0; y < shape[1]; y++)
6186 {
6187 for (int x = 0; x < shape[0]; x++)
6188 {
6189 b.SetValue(x, y, fs[x, y]);
6190 }
6191 }
6192 bm.Buffers.Add(b);
6193 }
6194 bm.sizeC = 1;
6195 bm.sizeZ = 1;
6196 }
6197 else
6198 {
6199 throw new InvalidOperationException("Unsupported array shape.");
6200 }
6201
6202 for (int i = 0; i < bm.SizeC; i++)
6203 {
6204 if (bm.Buffers[0].PixelFormat == PixelFormat.Float || bm.Buffers[0].PixelFormat == PixelFormat.UInt || bm.Buffers[0].PixelFormat == PixelFormat.Int)
6205 bm.Channels.Add(new Channel(i, 32, 1));
6206 else
6207 if (bm.Buffers[0].PixelFormat == PixelFormat.Format8bppIndexed)
6208 bm.Channels.Add(new Channel(i, 8, 1));
6209 }
6210 bm.sizeT = 1;
6211 bm.Coords = new int[bm.SizeZ, bm.SizeC, bm.SizeT];
6212 bm.UpdateCoords();
6213 bm.bitsPerPixel = 8;
6214 if (dataType == NumPy.NpyDataType.Float32)
6215 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));
6216 else
6217 if (dataType == NumPy.NpyDataType.UInt32)
6218 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));
6219 else
6220 if (dataType == NumPy.NpyDataType.Int32)
6221 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));
6222 else
6223 if (dataType == NumPy.NpyDataType.UInt8)
6224 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));
6225 foreach (var item in bm.Buffers)
6226 {
6227 item.Stats = Statistics.FromBytes(item);
6228 }
6229 bm.Type = ImageType.stack;
6230 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));
6231 AutoThreshold(bm, false);
6232 if (bm.bitsPerPixel > 8)
6233 bm.StackThreshold(true);
6234 else
6235 bm.StackThreshold(false);
6236 bm.StackOrder = Order.ZCT;
6237 bm.ID = Path.GetFileName(file);
6238 bm.Filename = bm.ID;
6239 bm.file = file;
6240 Images.AddImage(bm);
6241 return bm;
6242 }
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:7399
Definition Bio.cs:1154
ImageType
Image type.
Definition ISlideSource.cs:798
Definition Bio.cs:190

◆ 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.
4488 {
4489 List<ROI> annotations = new List<ROI>();
4490 foreach (ROI an in Annotations)
4491 {
4492 if (an.coord.Z == Z && an.coord.Z == Z && an.coord.C == C && an.coord.T == T)
4493 annotations.Add(an);
4494 }
4495 return annotations;
4496 }

◆ 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.
4468 {
4469 List<ROI> annotations = new List<ROI>();
4470 foreach (ROI an in Annotations)
4471 {
4472 if (an == null)
4473 continue;
4474 if (an.coord == coord)
4475 annotations.Add(an);
4476 }
4477 return annotations;
4478 }

◆ 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.
5842 {
5843 switch (format)
5844 {
5845 case AForge.PixelFormat.Format8bppIndexed: return 1;
5846 case AForge.PixelFormat.Format16bppGrayScale: return 1;
5847 case AForge.PixelFormat.Format24bppRgb: return 3;
5848 case AForge.PixelFormat.Format32bppArgb:
5849 case AForge.PixelFormat.Format32bppPArgb:
5850 case AForge.PixelFormat.Format32bppRgb:
5851 return 4;
5852 case AForge.PixelFormat.Format48bppRgb:
5853 return 3;
5854 default:
5855 throw new NotSupportedException($"Unsupported pixel format: {format}");
5856 }
5857 }

◆ 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.
3956 {
3957 return Buffers[GetFrameIndex(z, c, t)];
3958 }

◆ 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.
4131 {
4132 return (Bitmap)GetImageByCoord(coord.Z, coord.C, coord.T);
4133 }
Bitmap GetImageByCoord(int z, int c, int t)
Definition Bio.cs:3942

◆ 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.
4302 {
4303 if (px == PixelFormat.Format32bppArgb)
4304 {
4305 //opening a 8 bit per pixel jpg image
4306 Bitmap bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);
4307 //creating the bitmapdata and lock bits
4308 AForge.Rectangle rec = new AForge.Rectangle(0, 0, w, h);
4309 BitmapData bmd = bmp.LockBits(rec, ImageLockMode.ReadWrite, bmp.PixelFormat);
4310 //iterating through all the pixels in y direction
4311 for (int y = 0; y < h; y++)
4312 {
4313 //getting the pixels of current row
4314 byte* row = (byte*)bmd.Scan0 + (y * bmd.Stride);
4315 int rowRGB = y * w * 4;
4316 //iterating through all the pixels in x direction
4317 for (int x = 0; x < w; x++)
4318 {
4319 int indexRGB = x * 4;
4320 int indexRGBA = x * 4;
4321 row[indexRGBA + 3] = bts[rowRGB + indexRGB + 3];//byte A
4322 row[indexRGBA + 2] = bts[rowRGB + indexRGB + 2];//byte R
4323 row[indexRGBA + 1] = bts[rowRGB + indexRGB + 1];//byte G
4324 row[indexRGBA] = bts[rowRGB + indexRGB];//byte B
4325 }
4326 }
4327 //unlocking bits and disposing image
4328 bmp.UnlockBits(bmd);
4329 return bmp;
4330 }
4331 else if (px == PixelFormat.Format24bppRgb)
4332 {
4333 //opening a 8 bit per pixel jpg image
4334 Bitmap bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);
4335 //creating the bitmapdata and lock bits
4336 AForge.Rectangle rec = new AForge.Rectangle(0, 0, w, h);
4337 BitmapData bmd = bmp.LockBits(rec, ImageLockMode.ReadWrite, bmp.PixelFormat);
4338 //iterating through all the pixels in y direction
4339 for (int y = 0; y < h; y++)
4340 {
4341 //getting the pixels of current row
4342 byte* row = (byte*)bmd.Scan0 + (y * bmd.Stride);
4343 int rowRGB = y * w * 3;
4344 //iterating through all the pixels in x direction
4345 for (int x = 0; x < w; x++)
4346 {
4347 int indexRGB = x * 3;
4348 int indexRGBA = x * 4;
4349 row[indexRGBA + 3] = byte.MaxValue;//byte A
4350 row[indexRGBA + 2] = bts[rowRGB + indexRGB + 2];//byte R
4351 row[indexRGBA + 1] = bts[rowRGB + indexRGB + 1];//byte G
4352 row[indexRGBA] = bts[rowRGB + indexRGB];//byte B
4353 }
4354 }
4355 //unlocking bits and disposing image
4356 bmp.UnlockBits(bmd);
4357 return bmp;
4358 }
4359 else
4360 if (px == PixelFormat.Format48bppRgb)
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 * 6;
4375 //iterating through all the pixels in x direction
4376 for (int x = 0; x < w; x++)
4377 {
4378 int indexRGB = x * 6;
4379 int indexRGBA = x * 4;
4380 int b = (int)((float)BitConverter.ToUInt16(bts, rowRGB + indexRGB) / 255);
4381 int g = (int)((float)BitConverter.ToUInt16(bts, rowRGB + indexRGB + 2) / 255);
4382 int r = (int)((float)BitConverter.ToUInt16(bts, rowRGB + indexRGB + 4) / 255);
4383 row[indexRGBA + 3] = 255;//byte A
4384 row[indexRGBA + 2] = (byte)(b);//byte R
4385 row[indexRGBA + 1] = (byte)(g);//byte G
4386 row[indexRGBA] = (byte)(r);//byte B
4387 }
4388 }
4389 }
4390 bmp.UnlockBits(bmd);
4391 return bmp;
4392 }
4393 else
4394 if (px == PixelFormat.Format8bppIndexed)
4395 {
4396 //opening a 8 bit per pixel jpg image
4397 Bitmap bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);
4398 //creating the bitmapdata and lock bits
4399 AForge.Rectangle rec = new AForge.Rectangle(0, 0, w, h);
4400 BitmapData bmd = bmp.LockBits(rec, ImageLockMode.ReadWrite, bmp.PixelFormat);
4401 unsafe
4402 {
4403 //iterating through all the pixels in y direction
4404 for (int y = 0; y < h; y++)
4405 {
4406 //getting the pixels of current row
4407 byte* row = (byte*)bmd.Scan0 + (y * bmd.Stride);
4408 int rowRGB = y * w;
4409 //iterating through all the pixels in x direction
4410 for (int x = 0; x < w; x++)
4411 {
4412 int indexRGB = x;
4413 int indexRGBA = x * 4;
4414 byte b = bts[rowRGB + indexRGB];
4415 row[indexRGBA + 3] = 255;//byte A
4416 row[indexRGBA + 2] = (byte)(b);//byte R
4417 row[indexRGBA + 1] = (byte)(b);//byte G
4418 row[indexRGBA] = (byte)(b);//byte B
4419 }
4420 }
4421 }
4422 bmp.UnlockBits(bmd);
4423 return bmp;
4424 }
4425 else
4426 if (px == PixelFormat.Format16bppGrayScale)
4427 {
4428 //opening a 8 bit per pixel jpg image
4429 Bitmap bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);
4430 //creating the bitmapdata and lock bits
4431 AForge.Rectangle rec = new AForge.Rectangle(0, 0, w, h);
4432 BitmapData bmd = bmp.LockBits(rec, ImageLockMode.ReadWrite, bmp.PixelFormat);
4433 unsafe
4434 {
4435 //iterating through all the pixels in y direction
4436 for (int y = 0; y < h; y++)
4437 {
4438 //getting the pixels of current row
4439 byte* row = (byte*)bmd.Scan0 + (y * bmd.Stride);
4440 int rowRGB = y * w * 2;
4441 //iterating through all the pixels in x direction
4442 for (int x = 0; x < w; x++)
4443 {
4444 int indexRGB = x * 2;
4445 int indexRGBA = x * 4;
4446 ushort b = (ushort)((float)BitConverter.ToUInt16(bts, rowRGB + indexRGB) / 255);
4447 row[indexRGBA + 3] = 255;//byte A
4448 row[indexRGBA + 2] = (byte)(b);//byte R
4449 row[indexRGBA + 1] = (byte)(b);//byte G
4450 row[indexRGBA] = (byte)(b);//byte B
4451 }
4452 }
4453 }
4454 bmp.UnlockBits(bmd);
4455 return bmp;
4456 }
4457
4458 throw new NotSupportedException("Pixelformat " + px + " is not supported.");
4459 }

◆ 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.
7466 {
7467 if (bt == 8)
7468 return 255;
7469 if (bt == 9)
7470 return 512;
7471 else if (bt == 10)
7472 return 1023;
7473 else if (bt == 11)
7474 return 2047;
7475 else if (bt == 12)
7476 return 4095;
7477 else if (bt == 13)
7478 return 8191;
7479 else if (bt == 14)
7480 return 16383;
7481 else if (bt == 15)
7482 return 32767;
7483 else
7484 return 65535;
7485 }

◆ 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.
7440 {
7441 if (bt <= 255)
7442 return 8;
7443 if (bt <= 512)
7444 return 9;
7445 else if (bt <= 1023)
7446 return 10;
7447 else if (bt <= 2047)
7448 return 11;
7449 else if (bt <= 4095)
7450 return 12;
7451 else if (bt <= 8191)
7452 return 13;
7453 else if (bt <= 16383)
7454 return 14;
7455 else if (bt <= 32767)
7456 return 15;
7457 else
7458 return 16;
7459 }

◆ 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
4208 {
4209 Bitmap bf = Buffers[ind];
4210 if (bf.isRGB)
4211 {
4212 if (s == 0)
4213 return extractR.Apply(Buffers[ind].Image);
4214 else
4215 if (s == 1)
4216 return extractG.Apply(Buffers[ind].Image);
4217 else
4218 return extractB.Apply(Buffers[ind].Image);
4219 }
4220 else
4221 throw new InvalidOperationException();
4222 }

◆ 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.
4233 {
4234 if (RGBChannelCount == 1)
4235 {
4236 Bitmap[] bs = new Bitmap[Channels.Count];
4237 List<Channel> chs = new List<Channel>();
4238 for (int c = 0; c < Channels.Count; c++)
4239 {
4240 int index = GetFrameIndex(coord.Z, c, coord.T);
4241 bs[c] = Buffers[index];
4242 chs.Add(Channels[c]);
4243 }
4244 Bitmap bm = (Bitmap)Bitmap.GetEmissionBitmap(bs, chs.ToArray());
4245 return bm;
4246 }
4247 else
4248 {
4249 int index = GetFrameIndex(coord.Z, coord.C, coord.T);
4250 return Buffers[index];
4251 }
4252 }

◆ 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.
4168 {
4169 if (Buffers[ind].PixelFormat == PixelFormat.Float)
4170 {
4171 if (Statistics.StackMax <= 1)
4172 {
4173 Bitmap bm = Buffers[ind].GetImageRGBA(true);
4174 return bm;
4175 }
4176 else
4177 {
4178 BioImage.filter8.InRed = MapIntRangeToByteRange(r);
4179 BioImage.filter8.InGreen = MapIntRangeToByteRange(g);
4180 BioImage.filter8.InBlue = MapIntRangeToByteRange(b);
4181 Bitmap bm = BioImage.filter8.Apply(Buffers[ind].GetImageRGBA(false));
4182 return bm;
4183 }
4184 }
4185 else
4186 if (Buffers[ind].BitsPerPixel > 8)
4187 {
4188 BioImage.filter16.InRed = r;
4189 BioImage.filter16.InGreen = g;
4190 BioImage.filter16.InBlue = b;
4191 Bitmap bm = BioImage.filter16.Apply(Buffers[ind]);
4192 return bm;
4193 }
4194 else
4195 {
4196 // set ranges
4197 BioImage.filter8.InRed = r;
4198 BioImage.filter8.InGreen = g;
4199 BioImage.filter8.InBlue = b;
4200 return BioImage.filter8.Apply(Buffers[ind]);
4201 }
4202 }

◆ 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.
4143 {
4144 int index = GetFrameIndex(coord.Z, coord.C, coord.T);
4145 return GetFiltered(index, r, g, b);
4146 }

◆ GetFrameIndex()

int BioLib.BioImage.GetFrameIndex ( int z,
int c,
int t )
7216 {
7217 try
7218 {
7219 if (StackOrder == Order.ZCT)
7220 {
7221 return Coords[z, c, t];
7222 }
7223 else if (StackOrder == Order.CZT)
7224 {
7225 return Coords[c, z, t];
7226 }
7227 else
7228 return Coords[t, c, z];
7229 }
7230 catch (Exception e)
7231 {
7232 return 0;
7233 }
7234
7235 }

◆ 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.
3943 {
3944 return Buffers[GetFrameIndex(z, c, t)];
3945 }

◆ 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.
3970 {
3971 if (ix > SizeX || iy > SizeY || ix < 0 || iy < 0)
3972 return 0;
3973 int stridex = SizeX;
3974 int x = ix;
3975 int y = iy;
3976 if (bitsPerPixel > 8)
3977 {
3978 return (y * stridex + x) * 2;
3979 }
3980 else
3981 {
3982 return (y * stridex + x);
3983 }
3984 }

◆ 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.
3993 {
3994 int stridex = SizeX;
3995 //For 16bit (2*8bit) images we multiply buffer index by 2
3996 int x = ix;
3997 int y = iy;
3998 if (bitsPerPixel > 8)
3999 {
4000 return (y * stridex + x) * 2 * index;
4001 }
4002 else
4003 {
4004 return (y * stridex + x) * index;
4005 }
4006 }

◆ 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
2210 {
2211 int originalWidth = Resolutions[0].SizeX; // Width of the original level
2212 int nextLevelWidth = Resolutions[level].SizeX; // Width of the next level (downsampled)
2213 return (double)originalWidth / (double)nextLevelWidth;
2214 }

◆ GetLevelDownsamples()

double[] BioLib.BioImage.GetLevelDownsamples ( )
2216 {
2217 double[] ds = new double[Resolutions.Count];
2218 for (int i = 0; i < Resolutions.Count; i++)
2219 {
2220 ds[i] = Resolutions[0].PhysicalSizeX * GetLevelDownsample(i);
2221 }
2222 return ds;
2223 }
double GetLevelDownsample(int level)
Get the downsampling factor of a given level.
Definition Bio.cs:2209

◆ 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.
7523 {
7524 if (bitsPerPixel == 8)
7525 {
7526 if (rgbChannelCount == 1)
7527 return PixelFormat.Format8bppIndexed;
7528 else if (rgbChannelCount == 3)
7529 return PixelFormat.Format24bppRgb;
7530 else if (rgbChannelCount == 4)
7531 return PixelFormat.Format32bppArgb;
7532 }
7533 else
7534 {
7535 if (rgbChannelCount == 1)
7536 return PixelFormat.Format16bppGrayScale;
7537 if (rgbChannelCount == 3)
7538 return PixelFormat.Format48bppRgb;
7539 }
7540 throw new NotSupportedException("Not supported pixel format.");
7541 }

◆ 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.
7553 {
7554 if (rgbChannelCount == 1)
7555 {
7556 if (px == ome.xml.model.enums.PixelType.INT8 || px == ome.xml.model.enums.PixelType.UINT8)
7557 return PixelFormat.Format8bppIndexed;
7558 else if (px == ome.xml.model.enums.PixelType.INT16 || px == ome.xml.model.enums.PixelType.UINT16)
7559 return PixelFormat.Format16bppGrayScale;
7560 }
7561 else if (rgbChannelCount == 3)
7562 {
7563 if (px == ome.xml.model.enums.PixelType.INT8 || px == ome.xml.model.enums.PixelType.UINT8)
7564 return PixelFormat.Format24bppRgb;
7565 else if (px == ome.xml.model.enums.PixelType.INT16 || px == ome.xml.model.enums.PixelType.UINT16)
7566 return PixelFormat.Format48bppRgb;
7567 }
7568 else
7569 return PixelFormat.Format32bppArgb;
7570 throw new InvalidDataException("RGBChannels Count of " + rgbChannelCount + " not supported.");
7571 }

◆ GetRegion()

BioImage BioLib.BioImage.GetRegion ( int x,
int y,
int w,
int h )
7382 {
7383 string id = System.IO.Path.GetFileNameWithoutExtension(Filename);
7384 id.Replace(".ome", "");
7385 BioImage bm = Copy();
7386 bm.ID = id + ".ome.tif";
7387 bm.Filename = id + ".ome.tif";
7388 bm.Volume = new VolumeD(new Point3D(StageSizeX + (PhysicalSizeX * PyramidalOrigin.X), StageSizeY + (PhysicalSizeY * PyramidalOrigin.Y), StageSizeZ),
7389 new Point3D(w * PhysicalSizeX, h * PhysicalSizeY, SizeZ * PhysicalSizeZ));
7390 bm.Resolutions.Add(new Resolution(w, h, bm.Buffers[0].PixelFormat, PhysicalSizeX, PhysicalSizeY, PhysicalSizeZ, StageSizeX, StageSizeY, StageSizeZ));
7391 bm.Resolutions.RemoveAt(0);
7392 Recorder.AddLine("BioLib.Images.GetImage(\"" + bm.ID + "\").GetRegion(" + x + "," + y + "," + w + "," + h + ");", false);
7393 return bm;
7394 }

◆ 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.
4262 {
4263 int index = GetFrameIndex(coord.Z, 0, coord.T);
4264 if (Buffers[0].RGBChannelsCount == 1)
4265 {
4266 if (Channels.Count >= 3)
4267 {
4268 Bitmap[] bs = new Bitmap[3];
4269 bs[2] = Buffers[index + RChannel.Index];
4270 bs[1] = Buffers[index + GChannel.Index];
4271 bs[0] = Buffers[index + BChannel.Index];
4272 return Bitmap.GetRGBBitmap(bs, rf, gf, bf);
4273 }
4274 else
4275 {
4276 Bitmap[] bs = new Bitmap[3];
4277 bs[2] = Buffers[index + RChannel.Index];
4278 bs[1] = Buffers[index + RChannel.Index + 1];
4279 bs[0] = Buffers[index + RChannel.Index + 2];
4280 return Bitmap.GetRGBBitmap(bs, rf, gf, bf);
4281 }
4282 }
4283 else
4284 {
4285 if (Buffers[0].PixelFormat == PixelFormat.Float || Buffers[0].PixelFormat == PixelFormat.Short)
4286 {
4287 return Buffers[index].GetImageRGBA();
4288 }
4289 else
4290 return Buffers[index];
4291 }
4292 }

◆ GetSeriesCount()

static int BioLib.BioImage.GetSeriesCount ( string file)
static
9323 {
9324 ImageReader r = new ImageReader();
9325 r.setId(file);
9326 return r.getSeriesCount();
9327 }

◆ GetTile()

Bitmap BioLib.BioImage.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.

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.
7265 {
7266 if (b.Tag != null)
7267 {
7268 if (b.Tag.ToString() != "OMERO")
7269 return null;
7270 //This is a OMERO file we need to update it.
7271 int i = 0;
7272 for (int z = 0; z < b.SizeZ; z++)
7273 {
7274 for (int c = 0; c < b.SizeC; c++)
7275 {
7276 for (int t = 0; t < b.SizeT; t++)
7277 {
7278 if(i == index)
7279 return OMERO.GetTile(b, new ZCT(z,c,t), tilex, tiley, tileSizeX, tileSizeY, level).Result;
7280 i++;
7281 }
7282 }
7283 }
7284 }
7285 if (vips && b.openSlideImage == null)
7286 {
7287 //We can get a tile faster with libvips rather than bioformats.
7288 Bitmap bmp = ExtractRegionFromTiledTiff(b, tilex, tiley, tileSizeX, tileSizeY, level);
7289 if (bmp != null)
7290 {
7291 return bmp;
7292 }
7293 else
7294 vips = false;
7295 }
7296 //We check if we can open this with OpenSlide as this is faster than Bioformats with IKVM.
7297 if (b.openSlideImage != null)
7298 {
7299 byte[] bts = b.openSlideImage.ReadRegion(level, tilex, tiley, tileSizeX, tileSizeY);
7300 if (b.IsEmpty(bts) && b.Resolutions.Count > level - 1)
7301 {
7302 bts = b.openSlideImage.ReadRegion(level - 1, tilex, tiley, b.Resolutions[level - 1].SizeX, b.Resolutions[level - 1].SizeY);
7303 Bitmap bm = new Bitmap("", b.Resolutions[level - 1].SizeX, b.Resolutions[level - 1].SizeY, AForge.PixelFormat.Format32bppArgb, bts, new ZCT(), 0);
7304 return bm;
7305 }
7306 else
7307 {
7308 Bitmap bm = new Bitmap("", tileSizeX, tileSizeY, AForge.PixelFormat.Format32bppArgb, bts, new ZCT(), 0);
7309 return bm;
7310 }
7311 }
7312
7313 string curfile = b.imRead.getCurrentFile();
7314 if (curfile == null)
7315 {
7316 b.meta = (IMetadata)((OMEXMLService)factory.getInstance(typeof(OMEXMLService))).createOMEXMLMetadata();
7317 b.imRead.close();
7318 b.imRead.setMetadataStore(b.meta);
7319 b.imRead.setId(b.file);
7320 curfile = b.file;
7321 }
7322 else
7323 {
7324 string fi = b.file.Replace("\\", "/");
7325 string cf = curfile.Replace("\\", "/");
7326 if (cf != fi)
7327 {
7328 b.imRead.close();
7329 b.meta = (IMetadata)((OMEXMLService)factory.getInstance(typeof(OMEXMLService))).createOMEXMLMetadata();
7330 b.imRead.setMetadataStore(b.meta);
7331 b.imRead.setId(b.file);
7332 }
7333 }
7334 if (b.imRead.getSeries() != level)
7335 b.imRead.setSeries(level);
7336 int SizeX = b.imRead.getSizeX();
7337 int SizeY = b.imRead.getSizeY();
7338 bool flat = b.imRead.hasFlattenedResolutions();
7339 bool littleEndian = b.imRead.isLittleEndian();
7340 bool interleaved = b.imRead.isInterleaved();
7341 PixelFormat PixelFormat = b.Resolutions[level].PixelFormat;
7342 if (tilex < 0)
7343 tilex = 0;
7344 if (tiley < 0)
7345 tiley = 0;
7346 if (tilex >= SizeX)
7347 tilex = SizeX;
7348 if (tiley >= SizeY)
7349 tiley = SizeY;
7350 int sx = tileSizeX;
7351 if (tilex + tileSizeX > SizeX)
7352 sx -= (tilex + tileSizeX) - (SizeX);
7353 int sy = tileSizeY;
7354 if (tiley + tileSizeY > SizeY)
7355 sy -= (tiley + tileSizeY) - (SizeY);
7356 //For some reason calling openBytes with 1x1px area causes an exception.
7357 if (sx <= 1)
7358 return null;
7359 if (sy <= 1)
7360 return null;
7361 try
7362 {
7363 byte[] bytesr = b.imRead.openBytes(index, tilex, tiley, sx, sy);
7364 return new Bitmap(b.file, sx, sy, PixelFormat, bytesr, new ZCT(), index, null, littleEndian, interleaved).GetImageRGBA();
7365 }
7366 catch (Exception e)
7367 {
7368 Console.WriteLine(e.Message);
7369 return null;
7370 }
7371 }
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:6362
Definition OMERO.cs:32

◆ GetUnitPerPixel()

double BioLib.BioImage.GetUnitPerPixel ( int level)

Get Unit Per Pixel for pyramidal images.

Parameters
level
Returns
2257 {
2258 return Resolutions[0].PhysicalSizeX * GetLevelDownsample(level);
2259 }

◆ 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.
4054 {
4055 return GetValueRGB(new ZCTXY(z, c, t, x, y), 0);
4056 }
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:4023

◆ 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.
4041 {
4042 return GetValueRGB(new ZCTXY(coord.Z, coord.C, coord.T, x, y), 0);
4043 }

◆ 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.
4014 {
4015 return GetValueRGB(coord, 0);
4016 }

◆ 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.
4082 {
4083 return GetValueRGB(new ZCT(z, c, t), x, y, RGBindex);
4084 }

◆ 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.
4066 {
4067 int i = GetFrameIndex(coord.Z, coord.C, coord.T);
4068 return Buffers[i].GetValue(x, y, RGBindex);
4069 }

◆ 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.
4024 {
4025 int ind = 0;
4026 if (coord.C >= SizeC)
4027 {
4028 coord.C = 0;
4029 }
4030 ind = GetFrameIndex(coord.Z, coord.C, coord.T);
4031 return (ushort)Buffers[ind].GetValue(coord.X, coord.Y, index);
4032 }

◆ 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.
7659 {
7660 BioImage[] bs = new BioImage[files.Length];
7661 int z = 0;
7662 int c = 0;
7663 int t = 0;
7664 for (int i = 0; i < files.Length; i++)
7665 {
7666 string str = Path.GetFileNameWithoutExtension(files[i]);
7667 str = str.Replace(".ome", "");
7668 string[] st = str.Split('_');
7669 if (st.Length > 3)
7670 {
7671 z = int.Parse(st[1].Replace("Z", ""));
7672 c = int.Parse(st[2].Replace("C", ""));
7673 t = int.Parse(st[3].Replace("T", ""));
7674 }
7675 if (i == 0)
7676 bs[0] = OpenOME(files[i], tab);
7677 else
7678 {
7679 bs[i] = OpenFile(files[i], 0, tab, false);
7680 }
7681 }
7682 BioImage b = BioImage.CopyInfo(bs[0], true, true);
7683 for (int i = 0; i < files.Length; i++)
7684 {
7685 for (int bc = 0; bc < bs[i].Buffers.Count; bc++)
7686 {
7687 b.Buffers.Add(bs[i].Buffers[bc]);
7688 }
7689 }
7690 b.UpdateCoords(z + 1, c + 1, t + 1);
7691 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));
7692 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, files, tab);
7693 return b;
7694 }
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:6009

◆ 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.
9080 {
9081 List<ROI> list = new List<ROI>();
9082 if (!File.Exists(filename))
9083 return list;
9084 string[] sts = File.ReadAllLines(filename);
9085 //We start reading from line 1.
9086 for (int i = 1; i < sts.Length; i++)
9087 {
9088 list.Add(StringToROI(sts[i]));
9089 }
9090 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, filename);
9091 return list;
9092 }
static ROI StringToROI(string sts)
It takes a string and returns an ROI object.
Definition Bio.cs:8908

◆ Initialize()

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

Initializes ImageJ/Fiji with the given path.

Parameters
imageJPath
4503 {
4504 //We initialize OME on a seperate thread so the user doesn't have to wait for initialization to
4505 //view images.
4506 InitFactory();
4507 InitReader();
4508 InitWriter();
4509 if (imageJPath.Contains("Fiji"))
4510 {
4511 Fiji.Initialize(imageJPath);
4512 }
4513 else
4514 ImageJ.Initialize(imageJPath);
4515
4516 }

◆ 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.
5341 {
5342 if (file.EndsWith("ome.tif") || file.EndsWith("ome.tiff"))
5343 {
5344 return true;
5345 }
5346 if (file.EndsWith(".tif") || file.EndsWith(".TIF") || file.EndsWith("tiff") || file.EndsWith("TIFF"))
5347 {
5348 Tiff image = Tiff.Open(file, "r");
5349 string desc = "";
5350 FieldValue[] f = image.GetField(TiffTag.IMAGEDESCRIPTION);
5351 desc = f[0].ToString();
5352 image.Close();
5353 if (desc.Contains("OME-XML"))
5354 return true;
5355 else
5356 return false;
5357 }
5358 if ((file.EndsWith("png") || file.EndsWith("PNG") || file.EndsWith("jpg") || file.EndsWith("JPG") ||
5359 file.EndsWith("jpeg") || file.EndsWith("JPEG") || file.EndsWith("bmp") || file.EndsWith("BMP")))
5360 {
5361 return false;
5362 }
5363 else return true;
5364 }

◆ 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.
5371 {
5372 if (!isOME(file))
5373 return false;
5374 ImageReader reader = new ImageReader();
5375 var meta = (IMetadata)((OMEXMLService)new ServiceFactory().getInstance(typeof(OMEXMLService))).createOMEXMLMetadata();
5376 reader.setMetadataStore((MetadataStore)meta);
5377 file = file.Replace("\\", "/");
5378 reader.setId(file);
5379 bool ser = false;
5380 if (reader.getSeriesCount() > 1)
5381 ser = true;
5382 reader.close();
5383 reader = null;
5384 return ser;
5385 }
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:5340

◆ 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.
5306 {
5307 Tiff image = Tiff.Open(file, "r");
5308 string desc = "";
5309 FieldValue[] f = image.GetField(TiffTag.IMAGEDESCRIPTION);
5310 image.Close();
5311 string[] sts = desc.Split('\n');
5312 int index = 0;
5313 for (int i = 0; i < sts.Length; i++)
5314 {
5315 if (sts[i].StartsWith("-ImageInfo"))
5316 {
5317 string val = sts[i].Substring(11);
5318 val = val.Substring(0, val.IndexOf(':'));
5319 int serie = int.Parse(val);
5320 if (sts[i].Length > 10)
5321 {
5322 string cht = sts[i].Substring(sts[i].IndexOf('{'), sts[i].Length - sts[i].IndexOf('{'));
5323 ImageInfo info = JsonConvert.DeserializeObject<ImageInfo>(cht);
5324 if (info.Series > 1)
5325 return true;
5326 else
5327 return false;
5328 }
5329 }
5330 }
5331 return false;
5332 }
Definition Bio.cs:1055

◆ LevelFromResolution()

int BioLib.BioImage.LevelFromResolution ( double Resolution)

Returns the level of a given resolution.

Parameters
Resolution
Returns
2230 {
2231 int l = 0;
2232 double[] ds = GetLevelDownsamples();
2233 if (MacroResolution.HasValue)
2234 {
2235 for (int i = 0; i < MacroResolution.Value; i++)
2236 {
2237 if (ds[i] < Resolution)
2238 l = i;
2239 }
2240 }
2241 else
2242 {
2243 for (int i = 0; i < Resolutions.Count; i++)
2244 {
2245 if (ds[i] < Resolution)
2246 l = i;
2247 }
2248 }
2249 return l;
2250 }

◆ MapIntRangeToByteRange()

static IntRange BioLib.BioImage.MapIntRangeToByteRange ( IntRange ushortRange)
static
4148 {
4149 // Ensure the range is valid
4150 if (ushortRange.Min < 0 || ushortRange.Max > ushort.MaxValue)
4151 throw new ArgumentOutOfRangeException(nameof(ushortRange), "Range must be within 0 to ushort.MaxValue.");
4152
4153 // Map each value in the range
4154 int mappedMin = (int)((ushortRange.Min / (float)ushort.MaxValue) * byte.MaxValue);
4155 int mappedMax = (int)((ushortRange.Max / (float)ushort.MaxValue) * byte.MaxValue);
4156
4157 return new IntRange(mappedMin, mappedMax);
4158 }

◆ 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.
3643 {
3644 BioImage res = new BioImage(b2.ID);
3645 res.ID = Images.GetImageName(b2.ID);
3646 res.series = b2.series;
3647 res.sizeZ = b2.SizeZ;
3648 int cOrig = b2.SizeC;
3649 res.sizeC = b2.SizeC + b.SizeC;
3650 res.sizeT = b2.SizeT;
3651 res.bitsPerPixel = b2.bitsPerPixel;
3652 res.imageInfo = b2.imageInfo;
3653 res.littleEndian = b2.littleEndian;
3654 res.seriesCount = b2.seriesCount;
3655 res.imagesPerSeries = res.ImageCount / res.seriesCount;
3656 res.Coords = new int[res.SizeZ, res.SizeC, res.SizeT];
3657 res.Resolutions.Add(b2.Resolutions[0]);
3658 res.Volume = new VolumeD(new Point3D(res.StageSizeX, res.StageSizeY, res.StageSizeZ), new Point3D(b2.SizeX, b2.SizeY, b2.SizeZ));
3659 int i = 0;
3660 for (int ci = 0; ci < res.SizeC; ci++)
3661 {
3662 for (int ti = 0; ti < res.SizeT; ti++)
3663 {
3664 for (int zi = 0; zi < res.SizeZ; zi++)
3665 {
3666 if (i < b.ImageCount)
3667 {
3668 ZCT co = new ZCT(zi, ci, ti);
3669 int ind = b.GetFrameIndex(zi, 0, ti);
3670 //This plane is not part of b1 so we add the planes from b2 channels.
3671 Bitmap copy = new Bitmap(b.id, b.SizeX, b.SizeY, b.Buffers[0].PixelFormat, b.Buffers[ind].Bytes, co, ind);
3672 res.SetFrameIndex(zi, ci, ti, ind);
3673 res.Buffers.Add(copy);
3674 //Lets copy the ROI's from the original image.
3675 List<ROI> anns = b.GetAnnotations(zi, ci, ti);
3676 if (anns.Count > 0)
3677 res.Annotations.AddRange(anns);
3678 }
3679 else
3680 {
3681 ZCT co = new ZCT(zi, ci, ti);
3682 int ind = b2.GetFrameIndex(zi, 0, ti);
3683 //This plane is not part of b1 so we add the planes from b2 channels.
3684 Bitmap copy = new Bitmap(b2.id, b2.SizeX, b2.SizeY, b2.Buffers[0].PixelFormat, b2.Buffers[ind].Bytes, co, ind);
3685 res.SetFrameIndex(zi, ci, ti, b.ImageCount + ind);
3686 res.Buffers.Add(copy);
3687 //Lets copy the ROI's from the original image.
3688 List<ROI> anns = b2.GetAnnotations(zi, ci, ti);
3689 if (anns.Count > 0)
3690 res.Annotations.AddRange(anns);
3691 }
3692 i++;
3693 }
3694 }
3695 }
3696 for (int ci = 0; ci < b.SizeC; ci++)
3697 {
3698 res.Channels.Add(b.Channels[ci].Copy());
3699 }
3700 for (int ci = 0; ci < b2.SizeC; ci++)
3701 {
3702 res.Channels.Add(b2.Channels[ci].Copy());
3703 }
3704 res.rgbChannels[0] = 0;
3705 if (res.Channels.Count > 1)
3706 res.rgbChannels[1] = 1;
3707 if (res.Channels.Count > 2)
3708 res.rgbChannels[2] = 2;
3709 Images.AddImage(res);
3710 res.imagesPerSeries = res.Buffers.Count;
3711 //We wait for threshold image statistics calculation
3712 do
3713 {
3714 Thread.Sleep(100);
3715 } while (res.Buffers[res.Buffers.Count - 1].Stats == null);
3716 AutoThreshold(res, false);
3717 if (res.bitsPerPixel > 8)
3718 res.StackThreshold(true);
3719 else
3720 res.StackThreshold(false);
3721 return res;
3722 }
List< ROI > GetAnnotations(ZCT coord)
Definition Bio.cs:4467

◆ 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.
3730 {
3731 BioImage b = Images.GetImage(bname);
3732 BioImage b2 = Images.GetImage(b2name);
3733 return MergeChannels(b, b2);
3734 }
static BioImage MergeChannels(BioImage b2, BioImage b)
This function takes two images and merges them together.
Definition Bio.cs:3642

◆ 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.
3779 {
3780 BioImage bi = BioImage.CopyInfo(b, true, true);
3781 int ind = 0;
3782 for (int c = 0; c < b.SizeC; c++)
3783 {
3784 for (int z = 0; z < b.sizeZ; z++)
3785 {
3786 Merge m = new Merge(b.Buffers[b.GetFrameIndex(z, c, 0)]);
3787 Bitmap bm = new Bitmap(b.SizeX, b.SizeY, b.Buffers[0].PixelFormat);
3788 for (int i = 1; i < b.sizeT; i++)
3789 {
3790 m.OverlayImage = bm;
3791 bm = m.Apply(b.Buffers[b.GetFrameIndex(z, c, i)]);
3792 }
3793 Bitmap bf = new Bitmap(b.file, bm, new ZCT(z, c, 0), ind);
3794 bi.Buffers.Add(bf);
3795 bf.Stats = Statistics.FromBytes(bf);
3796 ind++;
3797 }
3798 }
3799 Images.AddImage(bi);
3800 bi.UpdateCoords(1, b.SizeC, b.SizeT);
3801 bi.Coordinate = new ZCT(0, 0, 0);
3802 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));
3803 AutoThreshold(bi, false);
3804 if (bi.bitsPerPixel > 8)
3805 bi.StackThreshold(true);
3806 else
3807 bi.StackThreshold(false);
3808 return bi;
3809 }

◆ 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.
3741 {
3742 BioImage bi = BioImage.CopyInfo(b, true, true);
3743 int ind = 0;
3744 for (int c = 0; c < b.SizeC; c++)
3745 {
3746 for (int t = 0; t < b.sizeT; t++)
3747 {
3748 Merge m = new Merge(b.Buffers[b.GetFrameIndex(0, c, t)]);
3749 Bitmap bm = new Bitmap(b.SizeX, b.SizeY, b.Buffers[0].PixelFormat);
3750 for (int i = 1; i < b.sizeZ; i++)
3751 {
3752 m.OverlayImage = bm;
3753 bm = m.Apply(b.Buffers[b.GetFrameIndex(i, c, t)]);
3754 }
3755 Bitmap bf = new Bitmap(b.file, bm, new ZCT(0, c, t), ind);
3756 bi.Buffers.Add(bf);
3757 bf.Stats = Statistics.FromBytes(bf);
3758 ind++;
3759 }
3760 }
3761 Images.AddImage(bi);
3762 bi.UpdateCoords(1, b.SizeC, b.SizeT);
3763 bi.Coordinate = new ZCT(0, 0, 0);
3764 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));
3765
3766 AutoThreshold(bi, false);
3767 if (bi.bitsPerPixel > 8)
3768 bi.StackThreshold(true);
3769 else
3770 bi.StackThreshold(false);
3771 return bi;
3772 }

◆ Open() [1/2]

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

It opens a file.

Parameters
fileThe file to open.
7640 {
7641 OpenFile(file);
7642 }

◆ Open() [2/2]

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

It opens a file.

Parameters
filesThe files to open.
7647 {
7648 foreach (string file in files)
7649 {
7650 Open(file);
7651 }
7652 }
static void Open(string file)
It opens a file.
Definition Bio.cs:7639

◆ 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
7618 {
7619 openfile = file;
7620 omes = OME;
7621 tab = newtab;
7622 add = images;
7623 serie = series;
7624 await Task.Run(OpenThread);
7625 }

◆ 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.
7630 {
7631 foreach (string file in files)
7632 {
7633 await OpenAsync(file, OME, tab, images, 0);
7634 }
7635 }
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:7617

◆ 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.
4860 {
4861 return OpenFile(file, 0, true, true);
4862 }

◆ OpenFile() [2/4]

static BioImage BioLib.BioImage.OpenFile ( string file,
bool tab )
static
4864 {
4865 return OpenFile(file, 0, tab, true);
4866 }

◆ 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.
4874 {
4875 return OpenFile(file, series, tab, addToImages, false, 0, 0, 0, 0);
4876 }

◆ 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.
5001 {
5002 string fs = file.Replace("\\", "/");
5003 Console.WriteLine("Opening BioImage: " + file);
5004 if (file.EndsWith(".npy"))
5005 return BioImage.FromNumpy(file);
5006 bool ome = isOME(file);
5007 if (ome) return OpenOME(file, series, tab, addToImages, tile, tileX, tileY, tileSizeX, tileSizeY);
5008 bool tiled = IsTiffTiled(file);
5009 Console.WriteLine("IsTiled=" + tiled.ToString());
5010 tile = tiled;
5011
5012 Stopwatch st = new Stopwatch();
5013 st.Start();
5014 Status = "Opening Image";
5015 progFile = file;
5016 BioImage b = new BioImage(file);
5017 if (tiled && file.EndsWith(".tif") && !file.EndsWith(".ome.tif"))
5018 {
5019 try
5020 {
5021 //To open this we need libvips
5022 vips = VipsSupport(b.file);
5023 }
5024 catch (Exception e)
5025 {
5026 Console.WriteLine(e.Message);
5027 }
5028 }
5029 b.series = series;
5030 b.file = file;
5031 if (tiled)
5032 b.Type = ImageType.pyramidal;
5033 string fn = Path.GetFileNameWithoutExtension(file);
5034 string dir = Path.GetDirectoryName(file);
5035 if (File.Exists(fn + ".csv"))
5036 {
5037 string f = dir + "//" + fn + ".csv";
5038 b.Annotations = BioImage.ImportROIsCSV(f);
5039 }
5040 if (file.EndsWith("tif") || file.EndsWith("tiff") || file.EndsWith("TIF") || file.EndsWith("TIFF"))
5041 {
5042 Tiff image = Tiff.Open(file, "r");
5043 b.tifRead = image;
5044 int SizeX = image.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
5045 int SizeY = image.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
5046 b.bitsPerPixel = image.GetField(TiffTag.BITSPERSAMPLE)[0].ToInt();
5047 b.littleEndian = image.IsBigEndian();
5048 int RGBChannelCount = image.GetField(TiffTag.SAMPLESPERPIXEL)[0].ToInt();
5049 string desc = "";
5050
5051 FieldValue[] f = image.GetField(TiffTag.IMAGEDESCRIPTION);
5052 desc = f[0].ToString();
5053 ImageJDesc imDesc = null;
5054 b.sizeC = 1;
5055 b.sizeT = 1;
5056 b.sizeZ = 1;
5057 bool imagej = false;
5058 if (f != null && !tile)
5059 {
5060 imDesc = new ImageJDesc();
5061 desc = f[0].ToString();
5062 if (desc.StartsWith("ImageJ"))
5063 {
5064 imDesc.SetString(desc);
5065 if (imDesc.channels != 0)
5066 b.sizeC = imDesc.channels;
5067 else
5068 b.sizeC = 1;
5069 if (imDesc.slices != 0)
5070 b.sizeZ = imDesc.slices;
5071 else
5072 b.sizeZ = 1;
5073 if (imDesc.frames != 0)
5074 b.sizeT = imDesc.frames;
5075 else
5076 b.sizeT = 1;
5077 if (imDesc.finterval != 0)
5078 b.frameInterval = imDesc.finterval;
5079 else
5080 b.frameInterval = 1;
5081 if (imDesc.spacing != 0)
5082 b.imageInfo.PhysicalSizeZ = imDesc.spacing;
5083 else
5084 b.imageInfo.PhysicalSizeZ = 1;
5085 imagej = true;
5086 }
5087 }
5088 int stride = 0;
5089 PixelFormat PixelFormat;
5090 if (RGBChannelCount == 1)
5091 {
5092 if (b.bitsPerPixel > 8)
5093 {
5094 PixelFormat = PixelFormat.Format16bppGrayScale;
5095 stride = SizeX * 2;
5096 }
5097 else
5098 {
5099 PixelFormat = PixelFormat.Format8bppIndexed;
5100 stride = SizeX;
5101 }
5102 }
5103 else
5104 if (RGBChannelCount == 3)
5105 {
5106 b.sizeC = 1;
5107 if (b.bitsPerPixel > 8)
5108 {
5109 PixelFormat = PixelFormat.Format48bppRgb;
5110 stride = SizeX * 2 * 3;
5111 }
5112 else
5113 {
5114 PixelFormat = PixelFormat.Format24bppRgb;
5115 stride = SizeX * 3;
5116 }
5117 }
5118 else
5119 {
5120 PixelFormat = PixelFormat.Format32bppArgb;
5121 stride = SizeX * 4;
5122 }
5123
5124 string[] sts = desc.Split('\n');
5125 int index = 0;
5126 for (int i = 0; i < sts.Length; i++)
5127 {
5128 if (sts[i].StartsWith("-Channel"))
5129 {
5130 string val = sts[i].Substring(9);
5131 val = val.Substring(0, val.IndexOf(':'));
5132 int serie = int.Parse(val);
5133 if (serie == series && sts[i].Length > 7)
5134 {
5135 string cht = sts[i].Substring(sts[i].IndexOf('{'), sts[i].Length - sts[i].IndexOf('{'));
5136 Channel.ChannelInfo info = JsonConvert.DeserializeObject<Channel.ChannelInfo>(cht);
5137 Channel ch = new Channel(index, b.bitsPerPixel, info.SamplesPerPixel);
5138 ch.info = info;
5139 b.Channels.Add(ch);
5140 if (index == 0)
5141 {
5142 b.rgbChannels[0] = 0;
5143 }
5144 else
5145 if (index == 1)
5146 {
5147 b.rgbChannels[1] = 1;
5148 }
5149 else
5150 if (index == 2)
5151 {
5152 b.rgbChannels[2] = 2;
5153 }
5154 index++;
5155 }
5156 }
5157 else
5158 if (sts[i].StartsWith("-ROI"))
5159 {
5160 string val = sts[i].Substring(5);
5161 val = val.Substring(0, val.IndexOf(':'));
5162 int serie = int.Parse(val);
5163 if (serie == series && sts[i].Length > 7)
5164 {
5165 string s = sts[i].Substring(sts[i].IndexOf("ROI:") + 4, sts[i].Length - (sts[i].IndexOf("ROI:") + 4));
5166 string ro = s.Substring(s.IndexOf(":") + 1, s.Length - (s.IndexOf(':') + 1));
5167 ROI roi = StringToROI(ro);
5168 b.Annotations.Add(roi);
5169 }
5170 }
5171 else
5172 if (sts[i].StartsWith("-ImageInfo"))
5173 {
5174 string val = sts[i].Substring(11);
5175 val = val.Substring(0, val.IndexOf(':'));
5176 int serie = int.Parse(val);
5177 if (serie == series && sts[i].Length > 10)
5178 {
5179 string cht = sts[i].Substring(sts[i].IndexOf('{'), sts[i].Length - sts[i].IndexOf('{'));
5180 b.imageInfo = JsonConvert.DeserializeObject<ImageInfo>(cht);
5181 }
5182 }
5183 }
5184 b.Coords = new int[b.SizeZ, b.SizeC, b.SizeT];
5185 if (tiled && tileSizeX == 0 && tileSizeY == 0)
5186 {
5187 tileSizeX = 1920;
5188 tileSizeY = 1080;
5189 }
5190
5191 //If this is a tiff file not made by Bio we init channels based on RGBChannels.
5192 if (b.Channels.Count == 0)
5193 b.Channels.Add(new Channel(0, b.bitsPerPixel, RGBChannelCount));
5194
5195 //Lets check to see the channels are correctly defined in this file
5196 for (int ch = 0; ch < b.Channels.Count; ch++)
5197 {
5198 if (b.Channels[ch].SamplesPerPixel != RGBChannelCount)
5199 {
5200 b.Channels[ch].SamplesPerPixel = RGBChannelCount;
5201 }
5202 }
5203
5204 b.Buffers = new List<Bitmap>();
5205 int pages = image.NumberOfDirectories() / b.seriesCount;
5206 if (!imagej)
5207 b.sizeZ = pages;
5208 int str = image.ScanlineSize();
5209 bool inter = true;
5210 if (stride != str)
5211 inter = false;
5212 InitDirectoryResolution(b, image, imDesc);
5213 if (tiled)
5214 {
5215 Console.WriteLine("Opening tiles.");
5216 if (vips)
5217 OpenVips(b);
5218 for (int t = 0; t < b.SizeT; t++)
5219 {
5220 for (int c = 0; c < b.SizeC; c++)
5221 {
5222 for (int z = 0; z < b.SizeZ; z++)
5223 {
5224 Bitmap bmp = b.GetTile(b, b.GetFrameIndex(z, c, t), b.level, tileX, tileY, tileSizeX, tileSizeY);
5225 b.Buffers.Add(bmp);
5226 bmp.Stats = Statistics.FromBytes(bmp);
5227 }
5228 }
5229 }
5230 Console.WriteLine("Calculating statisitics.");
5231 }
5232 else
5233 {
5234 for (int p = series * pages; p < (series + 1) * pages; p++)
5235 {
5236 image.SetDirectory((short)p);
5237
5238 byte[] bytes = new byte[stride * SizeY];
5239 for (int im = 0, offset = 0; im < SizeY; im++)
5240 {
5241 image.ReadScanline(bytes, offset, im, 0);
5242 offset += stride;
5243 }
5244 Bitmap inf = new Bitmap(file, SizeX, SizeY, b.Resolutions[series].PixelFormat, bytes, new ZCT(0, 0, 0), p, null, b.littleEndian, inter);
5245 b.Buffers.Add(inf);
5246 inf.Stats = Statistics.FromBytes(inf);
5247 }
5248 }
5249 image.Close();
5250 b.UpdateCoords();
5251 }
5252 else
5253 {
5254 Gdk.Pixbuf pf = new Gdk.Pixbuf(file);
5255 b.littleEndian = BitConverter.IsLittleEndian;
5256 PixelFormat px = GetPixelFormat(pf.NChannels, pf.BitsPerSample);
5257 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));
5258 b.bitsPerPixel = pf.BitsPerSample;
5259 b.Buffers.Add(new Bitmap(pf.Width, pf.Height, pf.Width * pf.NChannels, px, pf.Pixels));
5260 b.Buffers.Last().ID = Bitmap.CreateID(file, 0);
5261 b.Buffers.Last().Stats = Statistics.FromBytes(b.Buffers.Last());
5262 b.Channels.Add(new Channel(0, b.bitsPerPixel, b.RGBChannelCount));
5263 b.Coords = new int[1, 1, 1];
5264 b.sizeC = 1;
5265 b.sizeT = 1;
5266 b.sizeZ = 1;
5267 }
5268 /*
5269 if (b.StageSizeX == -1)
5270 {
5271 b.imageInfo.Series = 0;
5272 b.stageSizeX = 0;
5273 b.stageSizeY = 0;
5274 b.stageSizeZ = 0;
5275 }
5276 */
5277 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));
5278
5279 //If file is ome and we have OME support then check for annotation in metadata.
5280 if (ome)
5281 {
5282 b.Annotations.AddRange(OpenOMEROIs(file, series));
5283 }
5284 AutoThreshold(b, false);
5285 if (b.bitsPerPixel > 8)
5286 b.StackThreshold(true);
5287 else
5288 b.StackThreshold(false);
5289 if (addToImages)
5290 Images.AddImage(b);
5291 //pr.Close();
5292 //pr.Dispose();
5293 st.Stop();
5294 b.loadTimeMS = st.ElapsedMilliseconds;
5295 Console.WriteLine("BioImage loaded " + b.ToString());
5296 BioLib.Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, file, series, tab, addToImages, tile, tileX, tileY, tileSizeX, tileSizeY);
5297 return b;
5298 }
override string ToString()
This function returns the filename of the object, and the location of the object in the 3D space.
Definition Bio.cs:9318
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:7522
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:8432
static void OpenVips(BioImage b)
The function "OpenVips" takes a BioImage object and an integer representing the number of pages,...
Definition Bio.cs:6314
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:7264
static BioImage FromNumpy(string file)
Converts a numpy array to BioImage.
Definition Bio.cs:6030
static List< ROI > ImportROIsCSV(string filename)
It reads the CSV file and converts each line into a ROI object.
Definition Bio.cs:9079

◆ 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.
6010 {
6011 return OpenOMESeries(file, tab, true)[0];
6012 }
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:7579

◆ 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.
6022 {
6023 return OpenOME(file, serie, true, false, false, 0, 0, 0, 0);
6024 }

◆ 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

6471 {
6472 if (file == null || file == "")
6473 throw new InvalidDataException("File is empty or null");
6474 //We wait incase OME has not initialized.
6475 do
6476 {
6477 Thread.Sleep(10);
6478 } while (!initialized);
6479 Console.WriteLine("OpenOME " + file);
6480 reader = new ImageReader();
6481 if (tileSizeX == 0)
6482 tileSizeX = 1920;
6483 if (tileSizeY == 0)
6484 tileSizeY = 1080;
6485 progFile = file;
6486 BioImage b = new BioImage(file);
6487 b.Type = ImageType.stack;
6488 b.Loading = true;
6489 if (b.meta == null)
6490 b.meta = service.createOMEXMLMetadata();
6491 string f = file.Replace("\\", "/");
6492 string cf = reader.getCurrentFile();
6493 if (cf != null)
6494 cf = cf.Replace("\\", "/");
6495 if (cf != f)
6496 {
6497 reader.close();
6498 reader.setMetadataStore(b.meta);
6499 try
6500 {
6501 Status = "Opening file " + b.Filename;
6502 reader.setId(f);
6503 }
6504 catch (Exception e)
6505 {
6506 Console.WriteLine(e.Message);
6507 return null;
6508 }
6509 }
6510
6511 //status = "Reading OME Metadata.";
6512 reader.setSeries(serie);
6513 int RGBChannelCount = reader.getRGBChannelCount();
6514 //OME reader.getBitsPerPixel(); sometimes returns incorrect bits per pixel, like when opening ImageJ images.
6515 //So we check the pixel type from xml metadata and if it fails we use the readers value.
6516 PixelFormat PixelFormat;
6517 try
6518 {
6519 PixelFormat = GetPixelFormat(RGBChannelCount, b.meta.getPixelsType(serie));
6520 }
6521 catch (Exception)
6522 {
6523 PixelFormat = GetPixelFormat(RGBChannelCount, reader.getBitsPerPixel());
6524 }
6525
6526 b.id = file;
6527 b.file = file;
6528 int SizeX, SizeY;
6529 SizeX = reader.getSizeX();
6530 SizeY = reader.getSizeY();
6531 int SizeZ = reader.getSizeZ();
6532 b.sizeC = reader.getSizeC();
6533 b.sizeZ = reader.getSizeZ();
6534 b.sizeT = reader.getSizeT();
6535 b.littleEndian = reader.isLittleEndian();
6536 b.seriesCount = reader.getSeriesCount();
6537 b.imagesPerSeries = reader.getImageCount();
6538 b.imRead = reader;
6539 List<Resolution> ress = new List<Resolution>();
6540 if (PixelFormat == PixelFormat.Format8bppIndexed || PixelFormat == PixelFormat.Format24bppRgb || PixelFormat == PixelFormat.Format32bppArgb)
6541 b.bitsPerPixel = 8;
6542 else
6543 b.bitsPerPixel = 16;
6544 b.series = serie;
6545 string order = reader.getDimensionOrder();
6546 if (vips && tile)
6547 OpenVips(b);
6548 //Lets get the channels and initialize them
6549 int i = 0;
6550 int sumSamples = 0;
6551 while (true)
6552 {
6553 Status = "Reading channels.";
6554 bool def = false;
6555 try
6556 {
6557 int s = b.meta.getChannelSamplesPerPixel(serie, i).getNumberValue().intValue();
6558 Channel ch = new Channel(i, b.bitsPerPixel, s);
6559 if (b.meta.getChannelSamplesPerPixel(serie, i) != null)
6560 {
6561 ch.SamplesPerPixel = s;
6562 sumSamples += s;
6563 def = true;
6564 b.Channels.Add(ch);
6565 }
6566 if (i == 0)
6567 {
6568 b.rgbChannels[0] = 0;
6569 }
6570 else
6571 if (i == 1)
6572 {
6573 b.rgbChannels[1] = 1;
6574 }
6575 else
6576 if (i == 2)
6577 {
6578 b.rgbChannels[2] = 2;
6579 }
6580 //If this channel is not defined we have loaded all the channels in the file.
6581 if (!def)
6582 break;
6583 if (b.meta.getChannelName(serie, i) != null)
6584 ch.Name = b.meta.getChannelName(serie, i);
6585 if (b.meta.getChannelAcquisitionMode(serie, i) != null)
6586 ch.AcquisitionMode = b.meta.getChannelAcquisitionMode(serie, i).ToString();
6587 if (b.meta.getChannelID(serie, i) != null)
6588 ch.info.ID = b.meta.getChannelID(serie, i);
6589 if (b.meta.getChannelFluor(serie, i) != null)
6590 ch.Fluor = b.meta.getChannelFluor(serie, i);
6591 if (b.meta.getChannelColor(serie, i) != null)
6592 {
6593 ome.xml.model.primitives.Color cc = b.meta.getChannelColor(serie, i);
6594 ch.Color = Color.FromArgb(cc.getRed(), cc.getGreen(), cc.getBlue());
6595 }
6596 if (b.meta.getChannelIlluminationType(serie, i) != null)
6597 ch.IlluminationType = b.meta.getChannelIlluminationType(serie, i).ToString();
6598 if (b.meta.getChannelContrastMethod(serie, i) != null)
6599 ch.ContrastMethod = b.meta.getChannelContrastMethod(serie, i).ToString();
6600 if (b.meta.getChannelEmissionWavelength(serie, i) != null)
6601 ch.Emission = b.meta.getChannelEmissionWavelength(serie, i).value().intValue();
6602 if (b.meta.getChannelExcitationWavelength(serie, i) != null)
6603 ch.Excitation = b.meta.getChannelExcitationWavelength(serie, i).value().intValue();
6604 if (b.meta.getLightEmittingDiodePower(serie, i) != null)
6605 ch.LightSourceIntensity = b.meta.getLightEmittingDiodePower(serie, i).value().doubleValue();
6606 if (b.meta.getLightEmittingDiodeID(serie, i) != null)
6607 ch.DiodeName = b.meta.getLightEmittingDiodeID(serie, i);
6608 if (b.meta.getChannelLightSourceSettingsAttenuation(serie, i) != null)
6609 ch.LightSourceAttenuation = b.meta.getChannelLightSourceSettingsAttenuation(serie, i).toString();
6610
6611
6612 }
6613 catch (Exception e)
6614 {
6615 Console.WriteLine(e.Message);
6616 if (!def)
6617 break;
6618 }
6619 i++;
6620 }
6621 try
6622 {
6623 if (b.meta.getObjectiveNominalMagnification(serie, 0) != null)
6624 {
6625 b.Magnification = b.meta.getObjectiveNominalMagnification(serie, 0).intValue();
6626 }
6627 }
6628 catch (Exception e)
6629 {
6630 Console.WriteLine(e.Message);
6631 }
6632
6633 //If the file doens't have channels we initialize them.
6634 if (b.Channels.Count == 0)
6635 {
6636 b.Channels.Add(new Channel(0, b.bitsPerPixel, RGBChannelCount));
6637 }
6638 try
6639 {
6640 Status = "Reading wells.";
6641 int wells = b.meta.getWellCount(0);
6642 if (wells > 0)
6643 {
6644 b.Type = ImageType.well;
6645 b.Plate = new WellPlate(b);
6646 tile = false;
6647 }
6648 }
6649 catch (Exception e)
6650 {
6651 //This file is not a well plate.
6652 Console.WriteLine(e.Message);
6653 }
6654 if (reader.getResolutionCount() > 0)
6655 ress.AddRange(GetResolutions(b));
6656 Console.WriteLine("Done reading resolutions.");
6657 reader.setSeries(serie);
6658
6659 int pyramidCount = 0;
6660 int pyramidResolutions = 0;
6661 List<Tuple<int, int>> prs = new List<Tuple<int, int>>();
6662 Console.WriteLine("Determining pyramidal levels.");
6663 //We need to determine if this image is pyramidal or not.
6664 //We do this by seeing if the resolutions are downsampled or not.
6665 if (ress.Count > 1 && b.Type != ImageType.well)
6666 {
6667 if (ress[0].SizeX > ress[1].SizeX)
6668 {
6669 b.Type = ImageType.pyramidal;
6670 tile = true;
6671 //We need to determine number of pyramids in this image and which belong to the series we are opening.
6672 int? sr = null;
6673 for (int r = 0; r < ress.Count - 1; r++)
6674 {
6675 if (ress[r].SizeX > ress[r + 1].SizeX && ress[r].PixelFormat == ress[r + 1].PixelFormat)
6676 {
6677 if (sr == null)
6678 {
6679 sr = r;
6680 prs.Add(new Tuple<int, int>(r, 0));
6681 }
6682 }
6683 else
6684 {
6685 if (ress[prs[prs.Count - 1].Item1].PixelFormat == ress[r].PixelFormat)
6686 prs[prs.Count - 1] = new Tuple<int, int>(prs[prs.Count - 1].Item1, r);
6687 sr = null;
6688 }
6689 }
6690 pyramidCount = prs.Count;
6691 for (int p = 0; p < prs.Count; p++)
6692 {
6693 pyramidResolutions += (prs[p].Item2 - prs[p].Item1) + 1;
6694 }
6695 if (prs[serie].Item2 == 0)
6696 {
6697 prs[serie] = new Tuple<int, int>(prs[serie].Item1, b.seriesCount - 1);
6698 }
6699 }
6700 }
6701 if (b.Type == ImageType.pyramidal)
6702 {
6703 Console.WriteLine("Determining Label and Macro resolutions.");
6704 for (int p = 0; p < prs.Count; p++)
6705 {
6706 for (int r = prs[p].Item1; r < prs[p].Item2 + 1; r++)
6707 {
6708 b.Resolutions.Add(ress[r]);
6709 }
6710 }
6711 //If we have 2 resolutions that we're not added they are the label & macro resolutions so we add them to the image.
6712 if (ress.Count > b.Resolutions.Count)
6713 {
6714 b.LabelResolution = ress.Count - 1;
6715 b.Resolutions.Add(ress[ress.Count - 1]);
6716 b.MacroResolution = ress.Count - 2;
6717 b.Resolutions.Add(ress[ress.Count - 2]);
6718 }
6719 }
6720 if (b.Resolutions.Count == 0)
6721 b.Resolutions.AddRange(ress);
6722 try
6723 {
6724 string s = b.meta.getStageLabelName(serie);
6725 if (s != null)
6726 {
6727 Resolution res = new Resolution(b.SizeX, b.SizeY, PixelFormat, b.PhysicalSizeX, b.PhysicalSizeY, b.PhysicalSizeZ,
6728 b.meta.getStageLabelX(serie).value().doubleValue(),
6729 b.meta.getStageLabelY(serie).value().doubleValue(),
6730 b.meta.getStageLabelZ(serie).value().doubleValue());
6731 }
6732 }
6733 catch (Exception e)
6734 {
6735 Console.WriteLine("No Stage Cooordinates");
6736 }
6737
6738 b.Volume = new VolumeD(new Point3D(b.StageSizeX, b.StageSizeY, b.StageSizeZ), new Point3D(b.PhysicalSizeX * SizeX, b.PhysicalSizeY * SizeY, b.PhysicalSizeZ * SizeZ));
6739 int rc = b.meta.getROICount();
6740 for (int im = 0; im < rc; im++)
6741 {
6742 string roiID = b.meta.getROIID(im);
6743 string roiName = b.meta.getROIName(im);
6744 ZCT co = new ZCT(0, 0, 0);
6745 int scount = 1;
6746 try
6747 {
6748 scount = b.meta.getShapeCount(im);
6749 }
6750 catch (Exception e)
6751 {
6752 Console.WriteLine(e.Message.ToString());
6753 }
6754 for (int sc = 0; sc < scount; sc++)
6755 {
6756 Status = "Reading ROI " + (sc + 1).ToString() + "/" + scount;
6757 string typ = b.meta.getShapeType(im, sc);
6758 ROI an = new ROI();
6759 an.roiID = roiID;
6760 an.roiName = roiName;
6761 an.shapeIndex = sc;
6762 if (typ == "Point")
6763 {
6764 an.type = ROI.Type.Point;
6765 an.id = b.meta.getPointID(im, sc);
6766 double dx = b.meta.getPointX(im, sc).doubleValue();
6767 double dy = b.meta.getPointY(im, sc).doubleValue();
6768 an.AddPoint(b.ToStageSpace(new PointD(dx, dy)));
6769 an.coord = new ZCT();
6770 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getPointTheZ(im, sc);
6771 if (nz != null)
6772 an.coord.Z = nz.getNumberValue().intValue();
6773 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getPointTheC(im, sc);
6774 if (nc != null)
6775 an.coord.C = nc.getNumberValue().intValue();
6776 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getPointTheT(im, sc);
6777 if (nt != null)
6778 an.coord.T = nt.getNumberValue().intValue();
6779 an.Text = b.meta.getPointText(im, sc);
6780 ome.units.quantity.Length fl = b.meta.getPointFontSize(im, sc);
6781 if (fl != null)
6782 an.fontSize = fl.value().intValue();
6783 ome.xml.model.enums.FontFamily ff = b.meta.getPointFontFamily(im, sc);
6784 if (ff != null)
6785 an.family = ff.name();
6786 ome.xml.model.primitives.Color col = b.meta.getPointStrokeColor(im, sc);
6787 if (col != null)
6788 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
6789 ome.units.quantity.Length fw = b.meta.getPointStrokeWidth(im, sc);
6790 if (fw != null)
6791 an.strokeWidth = (float)fw.value().floatValue();
6792 ome.xml.model.primitives.Color colf = b.meta.getPointStrokeColor(im, sc);
6793 if (colf != null)
6794 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
6795 }
6796 else
6797 if (typ == "Line")
6798 {
6799 an.type = ROI.Type.Line;
6800 an.id = b.meta.getLineID(im, sc);
6801 double px1 = b.meta.getLineX1(im, sc).doubleValue();
6802 double py1 = b.meta.getLineY1(im, sc).doubleValue();
6803 double px2 = b.meta.getLineX2(im, sc).doubleValue();
6804 double py2 = b.meta.getLineY2(im, sc).doubleValue();
6805 List<PointD> pds = new List<PointD>();
6806 pds.Add(b.ToStageSpace(new PointD(px1, py1)));
6807 pds.Add(b.ToStageSpace(new PointD(px2, py2)));
6808 an.Points = pds;
6809 an.UpdateBoundingBox();
6810 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getLineTheZ(im, sc);
6811 if (nz != null)
6812 co.Z = nz.getNumberValue().intValue();
6813 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getLineTheC(im, sc);
6814 if (nc != null)
6815 co.C = nc.getNumberValue().intValue();
6816 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getLineTheT(im, sc);
6817 if (nt != null)
6818 co.T = nt.getNumberValue().intValue();
6819 an.coord = co;
6820 an.Text = b.meta.getLineText(im, sc);
6821 ome.units.quantity.Length fl = b.meta.getLineFontSize(im, sc);
6822 if (fl != null)
6823 an.fontSize = fl.value().intValue();
6824 ome.xml.model.enums.FontFamily ff = b.meta.getLineFontFamily(im, sc);
6825 if (ff != null)
6826 an.family = ff.name();
6827 ome.xml.model.primitives.Color col = b.meta.getLineStrokeColor(im, sc);
6828 if (col != null)
6829 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
6830 ome.units.quantity.Length fw = b.meta.getLineStrokeWidth(im, sc);
6831 if (fw != null)
6832 an.strokeWidth = (float)fw.value().floatValue();
6833 ome.xml.model.primitives.Color colf = b.meta.getLineFillColor(im, sc);
6834 if (colf != null)
6835 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
6836 }
6837 else
6838 if (typ == "Rectangle")
6839 {
6840 an.type = ROI.Type.Rectangle;
6841 an.id = b.meta.getRectangleID(im, sc);
6842 double px = b.meta.getRectangleX(im, sc).doubleValue();
6843 double py = b.meta.getRectangleY(im, sc).doubleValue();
6844 double pw = b.meta.getRectangleWidth(im, sc).doubleValue();
6845 double ph = b.meta.getRectangleHeight(im, sc).doubleValue();
6846 an.BoundingBox = b.ToStageSpace(new RectangleD(px, py, pw, ph));
6847 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getRectangleTheZ(im, sc);
6848 if (nz != null)
6849 co.Z = nz.getNumberValue().intValue();
6850 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getRectangleTheC(im, sc);
6851 if (nc != null)
6852 co.C = nc.getNumberValue().intValue();
6853 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getRectangleTheT(im, sc);
6854 if (nt != null)
6855 co.T = nt.getNumberValue().intValue();
6856 an.coord = co;
6857
6858 an.Text = b.meta.getRectangleText(im, sc);
6859 ome.units.quantity.Length fl = b.meta.getRectangleFontSize(im, sc);
6860 if (fl != null)
6861 an.fontSize = fl.value().intValue();
6862 ome.xml.model.enums.FontFamily ff = b.meta.getRectangleFontFamily(im, sc);
6863 if (ff != null)
6864 an.family = ff.name();
6865 ome.xml.model.primitives.Color col = b.meta.getRectangleStrokeColor(im, sc);
6866 if (col != null)
6867 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
6868 ome.units.quantity.Length fw = b.meta.getRectangleStrokeWidth(im, sc);
6869 if (fw != null)
6870 an.strokeWidth = (float)fw.value().floatValue();
6871 ome.xml.model.primitives.Color colf = b.meta.getRectangleFillColor(im, sc);
6872 if (colf != null)
6873 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
6874 ome.xml.model.enums.FillRule fr = b.meta.getRectangleFillRule(im, sc);
6875
6876 }
6877 else
6878 if (typ == "Ellipse")
6879 {
6880 an.type = ROI.Type.Ellipse;
6881 an.id = b.meta.getEllipseID(im, sc);
6882 double px = b.meta.getEllipseX(im, sc).doubleValue();
6883 double py = b.meta.getEllipseY(im, sc).doubleValue();
6884 double ew = b.meta.getEllipseRadiusX(im, sc).doubleValue();
6885 double eh = b.meta.getEllipseRadiusY(im, sc).doubleValue();
6886 //We convert the ellipse radius to Rectangle
6887 double w = ew * 2;
6888 double h = eh * 2;
6889 double x = px - ew;
6890 double y = py - eh;
6891 an.BoundingBox = b.ToStageSpace(new RectangleD(x, y, w, h));
6892 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getEllipseTheZ(im, sc);
6893 if (nz != null)
6894 co.Z = nz.getNumberValue().intValue();
6895 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getEllipseTheC(im, sc);
6896 if (nc != null)
6897 co.C = nc.getNumberValue().intValue();
6898 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getEllipseTheT(im, sc);
6899 if (nt != null)
6900 co.T = nt.getNumberValue().intValue();
6901 an.coord = co;
6902 an.Text = b.meta.getEllipseText(im, sc);
6903 ome.units.quantity.Length fl = b.meta.getEllipseFontSize(im, sc);
6904 if (fl != null)
6905 an.fontSize = fl.value().intValue();
6906 ome.xml.model.enums.FontFamily ff = b.meta.getEllipseFontFamily(im, sc);
6907 if (ff != null)
6908 an.family = ff.name();
6909 ome.xml.model.primitives.Color col = b.meta.getEllipseStrokeColor(im, sc);
6910 if (col != null)
6911 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
6912 ome.units.quantity.Length fw = b.meta.getEllipseStrokeWidth(im, sc);
6913 if (fw != null)
6914 an.strokeWidth = (float)fw.value().floatValue();
6915 ome.xml.model.primitives.Color colf = b.meta.getEllipseFillColor(im, sc);
6916 if (colf != null)
6917 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
6918 }
6919 else
6920 if (typ == "Polygon")
6921 {
6922 an.type = ROI.Type.Polygon;
6923 an.id = b.meta.getPolygonID(im, sc);
6924 an.closed = true;
6925 string pxs = b.meta.getPolygonPoints(im, sc);
6926 PointD[] pts = an.stringToPoints(pxs);
6927 pts = b.ToStageSpace(pts);
6928 if (pts.Length > 100)
6929 {
6930 an.type = ROI.Type.Freeform;
6931 }
6932 an.AddPoints(pts);
6933 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getPolygonTheZ(im, sc);
6934 if (nz != null)
6935 co.Z = nz.getNumberValue().intValue();
6936 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getPolygonTheC(im, sc);
6937 if (nc != null)
6938 co.C = nc.getNumberValue().intValue();
6939 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getPolygonTheT(im, sc);
6940 if (nt != null)
6941 co.T = nt.getNumberValue().intValue();
6942 an.coord = co;
6943 an.Text = b.meta.getPolygonText(im, sc);
6944 ome.units.quantity.Length fl = b.meta.getPolygonFontSize(im, sc);
6945 if (fl != null)
6946 an.fontSize = fl.value().intValue();
6947 ome.xml.model.enums.FontFamily ff = b.meta.getPolygonFontFamily(im, sc);
6948 if (ff != null)
6949 an.family = ff.name();
6950 ome.xml.model.primitives.Color col = b.meta.getPolygonStrokeColor(im, sc);
6951 if (col != null)
6952 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
6953 ome.units.quantity.Length fw = b.meta.getPolygonStrokeWidth(im, sc);
6954 if (fw != null)
6955 an.strokeWidth = (float)fw.value().floatValue();
6956 ome.xml.model.primitives.Color colf = b.meta.getPolygonFillColor(im, sc);
6957 if (colf != null)
6958 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
6959 }
6960 else
6961 if (typ == "Polyline")
6962 {
6963 an.type = ROI.Type.Polyline;
6964 an.id = b.meta.getPolylineID(im, sc);
6965 string pxs = b.meta.getPolylinePoints(im, sc);
6966 PointD[] pts = an.stringToPoints(pxs);
6967 for (int pi = 0; pi < pts.Length; pi++)
6968 {
6969 pts[pi] = b.ToStageSpace(pts[pi]);
6970 }
6971 an.AddPoints(pts);
6972 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getPolylineTheZ(im, sc);
6973 if (nz != null)
6974 co.Z = nz.getNumberValue().intValue();
6975 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getPolylineTheC(im, sc);
6976 if (nc != null)
6977 co.C = nc.getNumberValue().intValue();
6978 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getPolylineTheT(im, sc);
6979 if (nt != null)
6980 co.T = nt.getNumberValue().intValue();
6981 an.coord = co;
6982 an.Text = b.meta.getPolylineText(im, sc);
6983 ome.units.quantity.Length fl = b.meta.getPolylineFontSize(im, sc);
6984 if (fl != null)
6985 an.fontSize = fl.value().intValue();
6986 ome.xml.model.enums.FontFamily ff = b.meta.getPolylineFontFamily(im, sc);
6987 if (ff != null)
6988 an.family = ff.name();
6989 ome.xml.model.primitives.Color col = b.meta.getPolylineStrokeColor(im, sc);
6990 if (col != null)
6991 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
6992 ome.units.quantity.Length fw = b.meta.getPolylineStrokeWidth(im, sc);
6993 if (fw != null)
6994 an.strokeWidth = (float)fw.value().floatValue();
6995 ome.xml.model.primitives.Color colf = b.meta.getPolylineFillColor(im, sc);
6996 if (colf != null)
6997 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
6998 }
6999 else
7000 if (typ == "Label")
7001 {
7002 an.type = ROI.Type.Label;
7003 an.id = b.meta.getLabelID(im, sc);
7004 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getLabelTheZ(im, sc);
7005 if (nz != null)
7006 co.Z = nz.getNumberValue().intValue();
7007 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getLabelTheC(im, sc);
7008 if (nc != null)
7009 co.C = nc.getNumberValue().intValue();
7010 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getLabelTheT(im, sc);
7011 if (nt != null)
7012 co.T = nt.getNumberValue().intValue();
7013 an.coord = co;
7014
7015 ome.units.quantity.Length fl = b.meta.getLabelFontSize(im, sc);
7016 if (fl != null)
7017 an.fontSize = fl.value().intValue();
7018 ome.xml.model.enums.FontFamily ff = b.meta.getLabelFontFamily(im, sc);
7019 if (ff != null)
7020 an.family = ff.name();
7021 ome.xml.model.primitives.Color col = b.meta.getLabelStrokeColor(im, sc);
7022 if (col != null)
7023 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
7024 ome.units.quantity.Length fw = b.meta.getLabelStrokeWidth(im, sc);
7025 if (fw != null)
7026 an.strokeWidth = (float)fw.value().floatValue();
7027 ome.xml.model.primitives.Color colf = b.meta.getLabelFillColor(im, sc);
7028 if (colf != null)
7029 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
7030 PointD p = new PointD(b.meta.getLabelX(im, sc).doubleValue(), b.meta.getLabelY(im, sc).doubleValue());
7031 an.UpdatePoint(b.ToStageSpace(p),0);
7032 an.Text = b.meta.getLabelText(im, sc);
7033 }
7034 else
7035 if (typ == "Mask")
7036 {
7037 byte[] bts = b.meta.getMaskBinData(im, sc);
7038 bool end = b.meta.getMaskBinDataBigEndian(im, sc).booleanValue();
7039 double h = b.meta.getMaskHeight(im, sc).doubleValue();
7040 double w = b.meta.getMaskWidth(im, sc).doubleValue();
7041 double x = b.meta.getMaskX(im, sc).doubleValue();
7042 double y = b.meta.getMaskY(im, sc).doubleValue();
7043 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);
7044 an.Text = b.meta.getMaskText(im, sc);
7045 an.id = b.meta.getMaskID(im, sc);
7046 an.BoundingBox = new RectangleD(an.X, an.Y, an.W, an.H);
7047 ome.xml.model.primitives.NonNegativeInteger nz = b.meta.getMaskTheZ(im, sc);
7048 if (nz != null)
7049 co.Z = nz.getNumberValue().intValue();
7050 ome.xml.model.primitives.NonNegativeInteger nc = b.meta.getMaskTheC(im, sc);
7051 if (nc != null)
7052 co.C = nc.getNumberValue().intValue();
7053 ome.xml.model.primitives.NonNegativeInteger nt = b.meta.getMaskTheT(im, sc);
7054 if (nt != null)
7055 co.T = nt.getNumberValue().intValue();
7056 an.coord = co;
7057
7058 ome.units.quantity.Length fl = b.meta.getMaskFontSize(im, sc);
7059 if (fl != null)
7060 an.fontSize = fl.value().intValue();
7061 ome.xml.model.enums.FontFamily ff = b.meta.getMaskFontFamily(im, sc);
7062 if (ff != null)
7063 an.family = ff.name();
7064 ome.xml.model.primitives.Color col = b.meta.getMaskStrokeColor(im, sc);
7065 if (col != null)
7066 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
7067 ome.units.quantity.Length fw = b.meta.getMaskStrokeWidth(im, sc);
7068 if (fw != null)
7069 an.strokeWidth = (float)fw.value().floatValue();
7070 ome.xml.model.primitives.Color colf = b.meta.getMaskFillColor(im, sc);
7071 if (colf != null)
7072 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
7073 }
7074 b.Annotations.Add(an);
7075 }
7076 }
7077
7078 List<string> serFiles = new List<string>();
7079 serFiles.AddRange(reader.getSeriesUsedFiles());
7080
7081 b.Buffers = new List<Bitmap>();
7082 if (b.Type == ImageType.pyramidal)
7083 {
7084
7085 try
7086 {
7087
7088 string st = OpenSlideImage.DetectVendor(file);
7089 if (st != null && !file.EndsWith("ome.tif") && useOpenSlide)
7090 {
7091 Status = "Opening file with OpenSlide.";
7092 Console.WriteLine("Opening file with OpenSlide.");
7093 b.openSlideImage = OpenSlideImage.Open(file);
7094 b.openslideBase = (OpenSlideBase)OpenSlideGTK.SlideSourceBase.Create(file, true);
7095 }
7096 else
7097 {
7098 Status = "Opening file with BioFormats.";
7099 Console.WriteLine("Opening file with BioFormats.");
7100 b.slideBase = (SlideBase)SlideBase.Create(b, SlideImage.Open(b));
7101 }
7102 }
7103 catch (Exception e)
7104 {
7105 Console.WriteLine(e.Message.ToString());
7106 b.slideBase = (SlideBase)SlideBase.Create(b, SlideImage.Open(b));
7107 }
7108 tile = true;
7109 }
7110 // read the image data bytes
7111 int pages = reader.getImageCount();
7112 bool inter = reader.isInterleaved();
7113 int z = 0;
7114 int c = 0;
7115 int t = 0;
7116 if (!tile)
7117 {
7118 Status = "Reading image planes.";
7119 try
7120 {
7121 for (int p = 0; p < pages; p++)
7122 {
7123 Progress = ((float)p / (float)pages) * 100;
7124 Bitmap bf;
7125 byte[] bytes = reader.openBytes(p);
7126 bf = new Bitmap(file, SizeX, SizeY, PixelFormat, bytes, new ZCT(z, c, t), p, null, b.littleEndian, inter);
7127 b.Buffers.Add(bf);
7128 }
7129 }
7130 catch (Exception ex)
7131 {
7132 Console.WriteLine(ex.Message);
7133 }
7134
7135 }
7136 else
7137 {
7138 Status = "Reading tiles.";
7139 b.imRead = reader;
7140 for (int p = 0; p < pages; p++)
7141 {
7142 Progress = ((float)p / (float)pages) * 100;
7143 b.Buffers.Add(b.GetTile(b, p, b.Level, tilex, tiley, tileSizeX, tileSizeY));
7144 }
7145 }
7146 int pls;
7147 try
7148 {
7149 pls = b.meta.getPlaneCount(serie);
7150 }
7151 catch (Exception)
7152 {
7153 pls = 0;
7154 }
7155 if (pls == b.Buffers.Count)
7156 for (int bi = 0; bi < b.Buffers.Count; bi++)
7157 {
7158 Plane pl = new Plane();
7159 pl.Coordinate = new ZCT();
7160 double px = 0; double py = 0; double pz = 0;
7161 if (b.meta.getPlanePositionX(serie, bi) != null)
7162 px = b.meta.getPlanePositionX(serie, bi).value().doubleValue();
7163 if (b.meta.getPlanePositionY(serie, bi) != null)
7164 py = b.meta.getPlanePositionY(serie, bi).value().doubleValue();
7165 if (b.meta.getPlanePositionZ(serie, bi) != null)
7166 pz = b.meta.getPlanePositionZ(serie, bi).value().doubleValue();
7167 pl.Location = new AForge.Point3D(px, py, pz);
7168 int cc = 0; int zc = 0; int tc = 0;
7169 if (b.meta.getPlaneTheC(serie, bi) != null)
7170 cc = b.meta.getPlaneTheC(serie, bi).getNumberValue().intValue();
7171 if (b.meta.getPlaneTheZ(serie, bi) != null)
7172 zc = b.meta.getPlaneTheZ(serie, bi).getNumberValue().intValue();
7173 if (b.meta.getPlaneTheT(serie, bi) != null)
7174 tc = b.meta.getPlaneTheT(serie, bi).getNumberValue().intValue();
7175 pl.Coordinate = new ZCT(zc, cc, tc);
7176 if (b.meta.getPlaneDeltaT(serie, bi) != null)
7177 pl.Delta = b.meta.getPlaneDeltaT(serie, bi).value().doubleValue();
7178 if (b.meta.getPlaneExposureTime(serie, bi) != null)
7179 pl.Exposure = b.meta.getPlaneExposureTime(serie, bi).value().doubleValue();
7180 b.Buffers[bi].Plane = pl;
7181 }
7182 //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.
7183 if (RGBChannelCount >= 3)
7184 {
7185 b.sizeC = sumSamples / b.Channels[0].SamplesPerPixel;
7186 }
7187 string ord = reader.getDimensionOrder();
7188 if (ord == "XYZCT")
7189 b.UpdateCoords(b.SizeZ, b.SizeC, b.SizeT, Order.ZCT);
7190 else if (ord == "XYCZT")
7191 b.UpdateCoords(b.SizeZ, b.SizeC, b.SizeT, Order.CZT);
7192 else if (ord == "XYTCZ")
7193 b.UpdateCoords(b.SizeZ, b.SizeC, b.SizeT, Order.TCZ);
7194 AutoThreshold(b, true);
7195 if (b.bitsPerPixel > 8)
7196 b.StackThreshold(true);
7197 else
7198 b.StackThreshold(false);
7199 try
7200 {
7201 if (b.Type == ImageType.stack)
7202 reader.close();
7203 if (addToImages)
7204 Images.AddImage(b);
7205 }
7206 catch (Exception e)
7207 {
7208 Console.WriteLine(e.Message);
7209 }
7210 b.Loading = false;
7211 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, file, serie, tab, addToImages, tile, tilex, tiley, tileSizeX, tileSizeY);
7212 return b;
7213 }
PointD ToStageSpace(PointD p)
Definition Bio.cs:3454
void UpdateBoundingBox()
Definition ROI.cs:1456
PointD[] stringToPoints(string s)
Definition ROI.cs:1419
void AddPoints(PointD[] p, bool convertPixelSpace=false, double physX=1, double physY=1)
Definition ROI.cs:1345
void UpdatePoint(PointD p, int i)
Definition ROI.cs:1285
Definition SlideBase.cs:15
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.
8485 {
8486 List<ROI> Annotations = new List<ROI>();
8487 // create OME-XML metadata store
8488 ServiceFactory factory = new ServiceFactory();
8489 OMEXMLService service = (OMEXMLService)factory.getInstance(typeof(OMEXMLService));
8490 loci.formats.ome.OMEXMLMetadata meta = service.createOMEXMLMetadata();
8491 // create format reader
8492 ImageReader imageReader = new ImageReader();
8493 imageReader.setMetadataStore(meta);
8494 // initialize file
8495 file = file.Replace("\\", "/");
8496 imageReader.setId(file);
8497 int imageCount = imageReader.getImageCount();
8498 int seriesCount = imageReader.getSeriesCount();
8499 double physicalSizeX = 0;
8500 double physicalSizeY = 0;
8501 double physicalSizeZ = 0;
8502 double stageSizeX = 0;
8503 double stageSizeY = 0;
8504 double stageSizeZ = 0;
8505 int SizeX = imageReader.getSizeX();
8506 int SizeY = imageReader.getSizeY();
8507 int SizeZ = imageReader.getSizeY();
8508 try
8509 {
8510 bool hasPhysical = false;
8511 if (meta.getPixelsPhysicalSizeX(series) != null)
8512 {
8513 physicalSizeX = meta.getPixelsPhysicalSizeX(series).value().doubleValue();
8514 hasPhysical = true;
8515 }
8516 if (meta.getPixelsPhysicalSizeY(series) != null)
8517 {
8518 physicalSizeY = meta.getPixelsPhysicalSizeY(series).value().doubleValue();
8519 }
8520 if (meta.getPixelsPhysicalSizeZ(series) != null)
8521 {
8522 physicalSizeZ = meta.getPixelsPhysicalSizeZ(series).value().doubleValue();
8523 }
8524 else
8525 {
8526 physicalSizeZ = 1;
8527 }
8528 if (meta.getStageLabelX(series) != null)
8529 stageSizeX = meta.getStageLabelX(series).value().doubleValue();
8530 if (meta.getStageLabelY(series) != null)
8531 stageSizeY = meta.getStageLabelY(series).value().doubleValue();
8532 if (meta.getStageLabelZ(series) != null)
8533 stageSizeZ = meta.getStageLabelZ(series).value().doubleValue();
8534 else
8535 stageSizeZ = 1;
8536 }
8537 catch (Exception e)
8538 {
8539 stageSizeX = 0;
8540 stageSizeY = 0;
8541 stageSizeZ = 1;
8542 }
8543 VolumeD volume = new VolumeD(new Point3D(stageSizeX, stageSizeY, stageSizeZ), new Point3D(physicalSizeX * SizeX, physicalSizeY * SizeY, physicalSizeZ * SizeZ));
8544 int rc = meta.getROICount();
8545 for (int im = 0; im < rc; im++)
8546 {
8547 string roiID = meta.getROIID(im);
8548 string roiName = meta.getROIName(im);
8549 ZCT co = new ZCT(0, 0, 0);
8550 int scount = 1;
8551 try
8552 {
8553 scount = meta.getShapeCount(im);
8554 }
8555 catch (Exception e)
8556 {
8557 Console.WriteLine(e.Message.ToString());
8558 }
8559 for (int sc = 0; sc < scount; sc++)
8560 {
8561 string type = meta.getShapeType(im, sc);
8562 ROI an = new ROI();
8563 an.roiID = roiID;
8564 an.roiName = roiName;
8565 an.shapeIndex = sc;
8566 if (type == "Point")
8567 {
8568 an.type = ROI.Type.Point;
8569 an.id = meta.getPointID(im, sc);
8570 double dx = meta.getPointX(im, sc).doubleValue();
8571 double dy = meta.getPointY(im, sc).doubleValue();
8572 an.AddPoint(ToStageSpace(new PointD(dx, dy), physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y));
8573 an.coord = new ZCT();
8574 ome.xml.model.primitives.NonNegativeInteger nz = meta.getPointTheZ(im, sc);
8575 if (nz != null)
8576 an.coord.Z = nz.getNumberValue().intValue();
8577 ome.xml.model.primitives.NonNegativeInteger nc = meta.getPointTheC(im, sc);
8578 if (nc != null)
8579 an.coord.C = nc.getNumberValue().intValue();
8580 ome.xml.model.primitives.NonNegativeInteger nt = meta.getPointTheT(im, sc);
8581 if (nt != null)
8582 an.coord.T = nt.getNumberValue().intValue();
8583 an.Text = meta.getPointText(im, sc);
8584 ome.units.quantity.Length fl = meta.getPointFontSize(im, sc);
8585 if (fl != null)
8586 an.fontSize = fl.value().intValue();
8587 an.family = meta.getPointFontFamily(im, sc).name();
8588 ome.xml.model.primitives.Color col = meta.getPointStrokeColor(im, sc);
8589 if (col != null)
8590 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8591 ome.units.quantity.Length fw = meta.getPointStrokeWidth(im, sc);
8592 if (fw != null)
8593 an.strokeWidth = (float)fw.value().floatValue();
8594 ome.xml.model.primitives.Color colf = meta.getPointStrokeColor(im, sc);
8595 if (colf != null)
8596 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8597 }
8598 else
8599 if (type == "Line")
8600 {
8601 an.type = ROI.Type.Line;
8602 an.id = meta.getLineID(im, sc);
8603 double px1 = meta.getLineX1(im, sc).doubleValue();
8604 double py1 = meta.getLineY1(im, sc).doubleValue();
8605 double px2 = meta.getLineX2(im, sc).doubleValue();
8606 double py2 = meta.getLineY2(im, sc).doubleValue();
8607 an.AddPoint(ToStageSpace(new PointD(px1, py1), physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y));
8608 an.AddPoint(ToStageSpace(new PointD(px2, py2), physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y));
8609 ome.xml.model.primitives.NonNegativeInteger nz = meta.getLineTheZ(im, sc);
8610 if (nz != null)
8611 co.Z = nz.getNumberValue().intValue();
8612 ome.xml.model.primitives.NonNegativeInteger nc = meta.getLineTheC(im, sc);
8613 if (nc != null)
8614 co.C = nc.getNumberValue().intValue();
8615 ome.xml.model.primitives.NonNegativeInteger nt = meta.getLineTheT(im, sc);
8616 if (nt != null)
8617 co.T = nt.getNumberValue().intValue();
8618 an.coord = co;
8619 an.Text = meta.getLineText(im, sc);
8620 ome.units.quantity.Length fl = meta.getLineFontSize(im, sc);
8621 if (fl != null)
8622 an.fontSize = fl.value().intValue();
8623 an.family = meta.getPointFontFamily(im, sc).name();
8624 ome.xml.model.primitives.Color col = meta.getLineStrokeColor(im, sc);
8625 if (col != null)
8626 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8627 ome.units.quantity.Length fw = meta.getLineStrokeWidth(im, sc);
8628 if (fw != null)
8629 an.strokeWidth = (float)fw.value().floatValue();
8630 ome.xml.model.primitives.Color colf = meta.getLineFillColor(im, sc);
8631 if (colf != null)
8632 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8633 }
8634 else
8635 if (type == "Rectangle")
8636 {
8637 an.type = ROI.Type.Rectangle;
8638 an.id = meta.getRectangleID(im, sc);
8639 double px = meta.getRectangleX(im, sc).doubleValue();
8640 double py = meta.getRectangleY(im, sc).doubleValue();
8641 double pw = meta.getRectangleWidth(im, sc).doubleValue();
8642 double ph = meta.getRectangleHeight(im, sc).doubleValue();
8643 an.BoundingBox = ToStageSpace(new RectangleD(px, py, pw, ph), physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y);
8644 ome.xml.model.primitives.NonNegativeInteger nz = meta.getRectangleTheZ(im, sc);
8645 if (nz != null)
8646 co.Z = nz.getNumberValue().intValue();
8647 ome.xml.model.primitives.NonNegativeInteger nc = meta.getRectangleTheC(im, sc);
8648 if (nc != null)
8649 co.C = nc.getNumberValue().intValue();
8650 ome.xml.model.primitives.NonNegativeInteger nt = meta.getRectangleTheT(im, sc);
8651 if (nt != null)
8652 co.T = nt.getNumberValue().intValue();
8653 an.coord = co;
8654
8655 an.Text = meta.getRectangleText(im, sc);
8656 ome.units.quantity.Length fl = meta.getRectangleFontSize(im, sc);
8657 if (fl != null)
8658 an.fontSize = fl.value().intValue();
8659 an.family = meta.getPointFontFamily(im, sc).name();
8660 ome.xml.model.primitives.Color col = meta.getRectangleStrokeColor(im, sc);
8661 if (col != null)
8662 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8663 ome.units.quantity.Length fw = meta.getRectangleStrokeWidth(im, sc);
8664 if (fw != null)
8665 an.strokeWidth = (float)fw.value().floatValue();
8666 ome.xml.model.primitives.Color colf = meta.getRectangleFillColor(im, sc);
8667 if (colf != null)
8668 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8669 ome.xml.model.enums.FillRule fr = meta.getRectangleFillRule(im, sc);
8670 }
8671 else
8672 if (type == "Ellipse")
8673 {
8674 an.type = ROI.Type.Ellipse;
8675 an.id = meta.getEllipseID(im, sc);
8676 double px = meta.getEllipseX(im, sc).doubleValue();
8677 double py = meta.getEllipseY(im, sc).doubleValue();
8678 double ew = meta.getEllipseRadiusX(im, sc).doubleValue();
8679 double eh = meta.getEllipseRadiusY(im, sc).doubleValue();
8680 //We convert the ellipse radius to Rectangle
8681 double w = ew * 2;
8682 double h = eh * 2;
8683 double x = px - ew;
8684 double y = py - eh;
8685 an.BoundingBox = ToStageSpace(new RectangleD(px, py, w, h), physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y);
8686 ome.xml.model.primitives.NonNegativeInteger nz = meta.getEllipseTheZ(im, sc);
8687 if (nz != null)
8688 co.Z = nz.getNumberValue().intValue();
8689 ome.xml.model.primitives.NonNegativeInteger nc = meta.getEllipseTheC(im, sc);
8690 if (nc != null)
8691 co.C = nc.getNumberValue().intValue();
8692 ome.xml.model.primitives.NonNegativeInteger nt = meta.getEllipseTheT(im, sc);
8693 if (nt != null)
8694 co.T = nt.getNumberValue().intValue();
8695 an.coord = co;
8696 an.Text = meta.getEllipseText(im, sc);
8697 ome.units.quantity.Length fl = meta.getEllipseFontSize(im, sc);
8698 if (fl != null)
8699 an.fontSize = fl.value().intValue();
8700 an.family = meta.getPointFontFamily(im, sc).name();
8701 ome.xml.model.primitives.Color col = meta.getEllipseStrokeColor(im, sc);
8702 if (col != null)
8703 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8704 ome.units.quantity.Length fw = meta.getEllipseStrokeWidth(im, sc);
8705 if (fw != null)
8706 an.strokeWidth = (float)fw.value().floatValue();
8707 ome.xml.model.primitives.Color colf = meta.getEllipseFillColor(im, sc);
8708 if (colf != null)
8709 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8710 }
8711 else
8712 if (type == "Polygon")
8713 {
8714 an.type = ROI.Type.Polygon;
8715 an.id = meta.getPolygonID(im, sc);
8716 an.closed = true;
8717 string pxs = meta.getPolygonPoints(im, sc);
8718 PointD[] pts = an.stringToPoints(pxs);
8719 pts = ToStageSpace(pts, physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y);
8720 if (pts.Length > 100)
8721 {
8722 an.type = ROI.Type.Freeform;
8723 }
8724 an.AddPoints(pts);
8725 ome.xml.model.primitives.NonNegativeInteger nz = meta.getPolygonTheZ(im, sc);
8726 if (nz != null)
8727 co.Z = nz.getNumberValue().intValue();
8728 ome.xml.model.primitives.NonNegativeInteger nc = meta.getPolygonTheC(im, sc);
8729 if (nc != null)
8730 co.C = nc.getNumberValue().intValue();
8731 ome.xml.model.primitives.NonNegativeInteger nt = meta.getPolygonTheT(im, sc);
8732 if (nt != null)
8733 co.T = nt.getNumberValue().intValue();
8734 an.coord = co;
8735 an.Text = meta.getPolygonText(im, sc);
8736 ome.units.quantity.Length fl = meta.getPolygonFontSize(im, sc);
8737 if (fl != null)
8738 an.fontSize = fl.value().intValue();
8739 an.family = meta.getPointFontFamily(im, sc).name();
8740 ome.xml.model.primitives.Color col = meta.getPolygonStrokeColor(im, sc);
8741 if (col != null)
8742 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8743 ome.units.quantity.Length fw = meta.getPolygonStrokeWidth(im, sc);
8744 if (fw != null)
8745 an.strokeWidth = (float)fw.value().floatValue();
8746 ome.xml.model.primitives.Color colf = meta.getPolygonFillColor(im, sc);
8747 if (colf != null)
8748 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8749 }
8750 else
8751 if (type == "Polyline")
8752 {
8753 an.type = ROI.Type.Polyline;
8754 an.id = meta.getPolylineID(im, sc);
8755 string pxs = meta.getPolylinePoints(im, sc);
8756 PointD[] pts = an.stringToPoints(pxs);
8757 for (int pi = 0; pi < pts.Length; pi++)
8758 {
8759 pts[pi] = ToStageSpace(pts[pi], physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y);
8760 }
8761 an.AddPoints(an.stringToPoints(pxs));
8762 ome.xml.model.primitives.NonNegativeInteger nz = meta.getPolylineTheZ(im, sc);
8763 if (nz != null)
8764 co.Z = nz.getNumberValue().intValue();
8765 ome.xml.model.primitives.NonNegativeInteger nc = meta.getPolylineTheC(im, sc);
8766 if (nc != null)
8767 co.C = nc.getNumberValue().intValue();
8768 ome.xml.model.primitives.NonNegativeInteger nt = meta.getPolylineTheT(im, sc);
8769 if (nt != null)
8770 co.T = nt.getNumberValue().intValue();
8771 an.coord = co;
8772 an.Text = meta.getPolylineText(im, sc);
8773 ome.units.quantity.Length fl = meta.getPolylineFontSize(im, sc);
8774 if (fl != null)
8775 an.fontSize = fl.value().intValue();
8776 an.family = meta.getPointFontFamily(im, sc).name();
8777 ome.xml.model.primitives.Color col = meta.getPolylineStrokeColor(im, sc);
8778 if (col != null)
8779 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8780 ome.units.quantity.Length fw = meta.getPolylineStrokeWidth(im, sc);
8781 if (fw != null)
8782 an.strokeWidth = (float)fw.value().floatValue();
8783 ome.xml.model.primitives.Color colf = meta.getPolylineFillColor(im, sc);
8784 if (colf != null)
8785 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8786 }
8787 else
8788 if (type == "Label")
8789 {
8790 an.type = ROI.Type.Label;
8791 an.id = meta.getLabelID(im, sc);
8792
8793 ome.xml.model.primitives.NonNegativeInteger nz = meta.getLabelTheZ(im, sc);
8794 if (nz != null)
8795 co.Z = nz.getNumberValue().intValue();
8796 ome.xml.model.primitives.NonNegativeInteger nc = meta.getLabelTheC(im, sc);
8797 if (nc != null)
8798 co.C = nc.getNumberValue().intValue();
8799 ome.xml.model.primitives.NonNegativeInteger nt = meta.getLabelTheT(im, sc);
8800 if (nt != null)
8801 co.T = nt.getNumberValue().intValue();
8802 an.coord = co;
8803
8804 ome.units.quantity.Length fl = meta.getLabelFontSize(im, sc);
8805 if (fl != null)
8806 an.fontSize = fl.value().intValue();
8807 an.family = meta.getPointFontFamily(im, sc).name();
8808 ome.xml.model.primitives.Color col = meta.getLabelStrokeColor(im, sc);
8809 if (col != null)
8810 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8811 ome.units.quantity.Length fw = meta.getLabelStrokeWidth(im, sc);
8812 if (fw != null)
8813 an.strokeWidth = (float)fw.value().floatValue();
8814 ome.xml.model.primitives.Color colf = meta.getLabelFillColor(im, sc);
8815 if (colf != null)
8816 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8817 PointD p = new PointD(meta.getLabelX(im, sc).doubleValue(), meta.getLabelY(im, sc).doubleValue());
8818 an.AddPoint(ToStageSpace(p, physicalSizeX, physicalSizeY, volume.Location.X, volume.Location.Y));
8819 an.Text = meta.getLabelText(im, sc);
8820 }
8821 else
8822 if (type == "Mask")
8823 {
8824 byte[] bts = meta.getMaskBinData(im, sc);
8825 bool end = meta.getMaskBinDataBigEndian(im, sc).booleanValue();
8826 an = ROI.CreateMask(co, bts, (int)(an.W * physicalSizeX), (int)(an.H * physicalSizeY), new PointD(stageSizeX, stageSizeY), physicalSizeX, physicalSizeY);
8827 an.Text = meta.getMaskText(im, sc);
8828 an.id = meta.getMaskID(im, sc);
8829 ome.xml.model.primitives.NonNegativeInteger nz = meta.getMaskTheZ(im, sc);
8830 if (nz != null)
8831 co.Z = nz.getNumberValue().intValue();
8832 ome.xml.model.primitives.NonNegativeInteger nc = meta.getMaskTheC(im, sc);
8833 if (nc != null)
8834 co.C = nc.getNumberValue().intValue();
8835 ome.xml.model.primitives.NonNegativeInteger nt = meta.getMaskTheT(im, sc);
8836 if (nt != null)
8837 co.T = nt.getNumberValue().intValue();
8838 an.coord = co;
8839
8840 ome.units.quantity.Length fl = meta.getMaskFontSize(im, sc);
8841 if (fl != null)
8842 an.fontSize = fl.value().intValue();
8843 ome.xml.model.enums.FontFamily ff = meta.getMaskFontFamily(im, sc);
8844 if (ff != null)
8845 an.family = ff.name();
8846 ome.xml.model.primitives.Color col = meta.getMaskStrokeColor(im, sc);
8847 if (col != null)
8848 an.strokeColor = Color.FromArgb(col.getAlpha(), col.getRed(), col.getGreen(), col.getBlue());
8849 ome.units.quantity.Length fw = meta.getMaskStrokeWidth(im, sc);
8850 if (fw != null)
8851 an.strokeWidth = (float)fw.value().floatValue();
8852 ome.xml.model.primitives.Color colf = meta.getMaskFillColor(im, sc);
8853 if (colf != null)
8854 an.fillColor = Color.FromArgb(colf.getAlpha(), colf.getRed(), colf.getGreen(), colf.getBlue());
8855 }
8856 }
8857 }
8858
8859 imageReader.close();
8860 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, file, series);
8861 return Annotations;
8862 }

◆ 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.
7580 {
7581 //We wait incase OME has not initialized yet.
7582 if (!initialized)
7583 do
7584 {
7585 Thread.Sleep(100);
7586 //Application.DoEvents();
7587 } while (!Initialized);
7588 var meta = (IMetadata)((OMEXMLService)new ServiceFactory().getInstance(typeof(OMEXMLService))).createOMEXMLMetadata();
7589 reader.setMetadataStore((MetadataStore)meta);
7590 file = file.Replace("\\", "/");
7591 try
7592 {
7593 if (reader.getCurrentFile() != file)
7594 {
7595 Status = "Opening OME Image: " + file;
7596 file = file.Replace("\\", "/");
7597 reader.setId(file);
7598 }
7599 }
7600 catch (Exception e)
7601 {
7602 return null;
7603 }
7604 int count = reader.getSeriesCount();
7605 BioImage[] bs = new BioImage[count];
7606 for (int i = 0; i < count; i++)
7607 {
7608 bs[i] = OpenOME(file, i, tab, addToImages, false, 0, 0, 0, 0);
7609 if (bs[i] == null)
7610 return null;
7611 }
7612 return bs;
7613 }

◆ 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.
4828 {
4829 Tiff image = Tiff.Open(file, "r");
4830 int pages = image.NumberOfDirectories();
4831 FieldValue[] f = image.GetField(TiffTag.IMAGEDESCRIPTION);
4832 int sp = image.GetField(TiffTag.SAMPLESPERPIXEL)[0].ToInt();
4833 ImageJDesc imDesc = new ImageJDesc();
4834 int count = 1;
4835 if (f != null)
4836 {
4837 string desc = f[0].ToString();
4838 if (desc.StartsWith("ImageJ"))
4839 {
4840 imDesc.SetString(desc);
4841 if (imDesc.channels != 0)
4842 count = imDesc.channels;
4843 }
4844 }
4845 int scount = (pages * sp) / count;
4846 BioImage[] bs = new BioImage[pages];
4847 image.Close();
4848 for (int i = 0; i < pages; i++)
4849 {
4850 bs[i] = OpenFile(file, i, tab, true);
4851 }
4852 return bs;
4853 }

◆ 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.
6315 {
6316 try
6317 {
6318 List<NetVips.Image> ims = new List<NetVips.Image>();
6319 for (int i = 0; i < b.seriesCount; i++)
6320 {
6321 b.vipPages.Add(NetVips.Image.Tiffload(b.file, i));
6322 }
6323 b.vipPages = SortImagesBySizeDescending(b.vipPages.ToArray()).ToList();
6324 }
6325 catch (Exception e)
6326 {
6327 Console.WriteLine(e.Message);
6328 }
6329
6330 }

◆ 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.
8470 {
8471 if (!file.EndsWith(".tif"))
8472 return null;
8473 Tiff image = Tiff.Open(file, "r");
8474 FieldValue[] f = image.GetField(TiffTag.IMAGEDESCRIPTION);
8475 Recorder.Record(BioLib.Recorder.GetCurrentMethodInfo(), false, file);
8476 return f[0].ToString();
8477 }

◆ 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
9402 {
9403 for (int i = 0; i < a.Buffers.Count; i++)
9404 {
9405 a.Buffers[i] = a.Buffers[i] * b;
9406 }
9407 return a;
9408 }

◆ operator*() [2/2]

static BioImage BioLib.BioImage.operator* ( BioImage a,
float b )
static
9344 {
9345 for (int i = 0; i < a.Buffers.Count; i++)
9346 {
9347 a.Buffers[i] = a.Buffers[i] / b;
9348 }
9349 return a;
9350 }

◆ 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
9417 {
9418 for (int i = 0; i < a.Buffers.Count; i++)
9419 {
9420 a.Buffers[i] = a.Buffers[i] + b;
9421 }
9422 return a;
9423 }

◆ 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.
9358 {
9359 for (int i = 0; i < a.Buffers.Count; i++)
9360 {
9361 a.Buffers[i] = a.Buffers[i] + b;
9362 }
9363 return a;
9364 }

◆ 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.
9431 {
9432 for (int i = 0; i < a.Buffers.Count; i++)
9433 {
9434 a.Buffers[i] = a.Buffers[i] - b;
9435 }
9436 return a;
9437 }

◆ 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.
9372 {
9373 for (int i = 0; i < a.Buffers.Count; i++)
9374 {
9375 a.Buffers[i] = a.Buffers[i] - b;
9376 }
9377 return a;
9378 }

◆ 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.
9388 {
9389 for (int i = 0; i < a.Buffers.Count; i++)
9390 {
9391 a.Buffers[i] = a.Buffers[i] / b;
9392 }
9393 return a;
9394 }

◆ 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.
9336 {
9337 for (int i = 0; i < a.Buffers.Count; i++)
9338 {
9339 a.Buffers[i] = a.Buffers[i] / b;
9340 }
9341 return a;
9342 }

◆ Rename()

void BioLib.BioImage.Rename ( string name)
8303 {
8304 this.Filename = Path.GetFileName(name);
8305 this.ID = name;
8306 }

◆ 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
8869 {
8870 string s = "";
8871 for (int i = 0; i < Annotations.Count; i++)
8872 {
8873 s += ROIToString(Annotations[i]);
8874 }
8875 return s;
8876 }
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:8883

◆ 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
8884 {
8885 PointD[] points = an.GetPoints();
8886 string pts = "";
8887 for (int j = 0; j < points.Length; j++)
8888 {
8889 if (j == points.Length - 1)
8890 pts += points[j].X.ToString(CultureInfo.InvariantCulture) + "," + points[j].Y.ToString(CultureInfo.InvariantCulture);
8891 else
8892 pts += points[j].X.ToString(CultureInfo.InvariantCulture) + "," + points[j].Y.ToString(CultureInfo.InvariantCulture) + " ";
8893 }
8894 char sep = (char)34;
8895 string sColor = sep.ToString() + an.strokeColor.A.ToString() + ',' + an.strokeColor.R.ToString() + ',' + an.strokeColor.G.ToString() + ',' + an.strokeColor.B.ToString() + sep.ToString();
8896 string bColor = sep.ToString() + an.fillColor.A.ToString() + ',' + an.fillColor.R.ToString() + ',' + an.fillColor.G.ToString() + ',' + an.fillColor.B.ToString() + sep.ToString();
8897
8898 string line = an.roiID + ',' + an.roiName + ',' + an.type.ToString() + ',' + an.id + ',' + an.shapeIndex.ToString() + ',' +
8899 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) + ',' +
8900 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;
8901 return line;
8902 }
PointD[] GetPoints()
Definition ROI.cs:1306

◆ RotateFlip()

void BioLib.BioImage.RotateFlip ( AForge.RotateFlipType rot)
3137 {
3138 for (int i = 0; i < Buffers.Count; i++)
3139 {
3140 Buffers[i].RotateFlip(rot);
3141 }
3142 Volume = new VolumeD(new Point3D(StageSizeX, StageSizeY, StageSizeZ), new Point3D(PhysicalSizeX * SizeX, PhysicalSizeY * SizeY, PhysicalSizeZ * SizeZ));
3143 }

◆ 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.
8340 {
8341 savefile = file;
8342 saveid = id;
8343 some = ome;
8344 await Task.Run(SaveThread);
8345 }

◆ 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.
4716 {
4717 string[] sts = new string[1];
4718 sts[0] = ID;
4719 SaveSeries(sts, file);
4720 }
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:4725

◆ SaveOME() [1/2]

static void BioLib.BioImage.SaveOME ( BioImage image,
string file )
static
5394 {
5395 BioImage[] sts = new BioImage[1];
5396 sts[0] = image;
5397 SaveOMESeries(sts, file, BioImage.Planes);
5398 }
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:5416

◆ SaveOME() [2/2]

static void BioLib.BioImage.SaveOME ( string file,
string ID )
static
5387 {
5388 BioImage[] sts = new BioImage[1];
5389 sts[0] = Images.GetImage(ID);
5390 SaveOMESeries(sts, file, BioImage.Planes);
5391 }

◆ 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.
5869 {
5870 if (File.Exists(file))
5871 File.Delete(file);
5872 Status = "Saving OME Pyramidal";
5873 //We need to go through the images and find the ones belonging to each resolution.
5874 //As well we need to determine the dimensions of the tiles.
5875 Dictionary<double, List<BioImage>> bis = new Dictionary<double, List<BioImage>>();
5876 Dictionary<double, Point3D> min = new Dictionary<double, Point3D>();
5877 Dictionary<double, Point3D> max = new Dictionary<double, Point3D>();
5878 for (int i = 0; i < bms.Length; i++)
5879 {
5880 Resolution res = bms[i].Resolutions[bms[i].Level];
5881 if (bis.ContainsKey(res.PhysicalSizeX))
5882 {
5883 bis[res.PhysicalSizeX].Add(bms[i]);
5884 if (bms[i].StageSizeX < min[res.PhysicalSizeX].X || bms[i].StageSizeY < min[res.PhysicalSizeX].Y)
5885 {
5886 min[res.PhysicalSizeX] = bms[i].Volume.Location;
5887 }
5888 if (bms[i].StageSizeX > max[res.PhysicalSizeX].X || bms[i].StageSizeY > max[res.PhysicalSizeX].Y)
5889 {
5890 max[res.PhysicalSizeX] = bms[i].Volume.Location;
5891 }
5892 }
5893 else
5894 {
5895 bis.Add(res.PhysicalSizeX, new List<BioImage>());
5896 min.Add(res.PhysicalSizeX, new Point3D(double.MaxValue, double.MaxValue, double.MaxValue));
5897 max.Add(res.PhysicalSizeX, new Point3D(double.MinValue, double.MinValue, double.MinValue));
5898 if (bms[i].StageSizeX < min[res.PhysicalSizeX].X || bms[i].StageSizeY < min[res.PhysicalSizeX].Y)
5899 {
5900 min[res.PhysicalSizeX] = bms[i].Volume.Location;
5901 }
5902 if (bms[i].StageSizeX > max[res.PhysicalSizeX].X || bms[i].StageSizeY > max[res.PhysicalSizeX].Y)
5903 {
5904 max[res.PhysicalSizeX] = bms[i].Volume.Location;
5905 }
5906 bis[res.PhysicalSizeX].Add(bms[i]);
5907 }
5908 }
5909 int s = 0;
5910 //We determine the sizes of each resolution.
5911 Dictionary<double, AForge.Size> ss = new Dictionary<double, AForge.Size>();
5912 int minx = int.MaxValue;
5913 int miny = int.MaxValue;
5914 double last = 0;
5915 foreach (double px in bis.Keys)
5916 {
5917 int xs = (1 + (int)Math.Ceiling((max[px].X - min[px].X) / bis[px][0].Resolutions[0].VolumeWidth)) * bis[px][0].SizeX;
5918 int ys = (1 + (int)Math.Ceiling((max[px].Y - min[px].Y) / bis[px][0].Resolutions[0].VolumeHeight)) * bis[px][0].SizeY;
5919 if (minx > xs)
5920 minx = xs;
5921 if (miny > ys)
5922 miny = ys;
5923 ss.Add(px, new AForge.Size(xs, ys));
5924 last = px;
5925 }
5926 s = 0;
5927 string met = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +
5928 "<OME xmlns=\"http://www.openmicroscopy.org/Schemas/OME/2016-06\" " +
5929 "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
5930 "xsi:schemaLocation=\"http://www.openmicroscopy.org/Schemas/OME/2016-06 http://www.openmicroscopy.org/Schemas/OME/2016-06/ome.xsd\">";
5931 NetVips.Image img = null;
5932 int ib = 0;
5933
5934 foreach (double px in bis.Keys)
5935 {
5936 int c = bis[px][s].SizeC;
5937 if (bis[px][s].Buffers[0].isRGB)
5938 c = 3;
5939 string endian = (bis[px][s].Buffers[0].LittleEndian).ToString().ToLower();
5940 met +=
5941 "<Image ID=\"Image:" + ib + "\">" +
5942 "<Pixels BigEndian=\"" + endian + "\" DimensionOrder= \"XYCZT\" ID= \"Pixels:0\" Interleaved=\"true\" " +
5943 "PhysicalSizeX=\"" + bis[px][s].PhysicalSizeX + "\" PhysicalSizeXUnit=\"µm\" PhysicalSizeY=\"" + bis[px][s].PhysicalSizeY + "\" PhysicalSizeYUnit=\"µm\" SignificantBits=\"" + bis[px][s].bitsPerPixel + "\" " +
5944 "SizeC = \"" + c + "\" SizeT = \"" + bis[px][s].SizeT + "\" SizeX =\"" + ss[px].Width +
5945 "\" SizeY= \"" + ss[px].Height + "\" SizeZ=\"" + bis[px][s].SizeZ;
5946 if (bis[px][s].bitsPerPixel > 8) met += "\" Type= \"uint16\">";
5947 else met += "\" Type= \"uint8\">";
5948 int i = 0;
5949 foreach (Channel ch in bis[px][s].Channels)
5950 {
5951 met += "<Channel ID=\"Channel:" + ib + ":" + i + "\" SamplesPerPixel=\"1\"></Channel>";
5952 i++;
5953 }
5954 met += "</Pixels></Image>";
5955 ib++;
5956 }
5957 met += "</OME>";
5958 foreach (double px in bis.Keys)
5959 {
5960 PixelFormat pf = bis[px][0].Buffers[0].PixelFormat;
5961 Bitmap level = new Bitmap(ss[px].Width, ss[px].Height, pf);
5962 int bands = GetBands(pf);
5963 if (bis[px][0].bitsPerPixel > 8)
5964 img = NetVips.Image.NewFromMemory(level.Data, (ulong)level.Length, level.Width, level.Height, bands, Enums.BandFormat.Ushort);
5965 else
5966 img = NetVips.Image.NewFromMemory(level.Data, (ulong)level.Length, level.Width, level.Height, bands, Enums.BandFormat.Uchar);
5967 int i = 0;
5968 foreach (BioImage b in bis[px])
5969 {
5970 Progress = ((float)i / (float)bis[px].Count) * 100;
5971 AForge.Size si = ss[px];
5972 double xs = (-(min[px].X - bis[px][i].Volume.Location.X) / bis[px][i].Resolutions[0].VolumeWidth) * bis[px][i].SizeX;
5973 double ys = (-(min[px].Y - bis[px][i].Volume.Location.Y) / bis[px][i].Resolutions[0].VolumeHeight) * bis[px][i].SizeY;
5974 NetVips.Image tile;
5975 if (b.bitsPerPixel > 8)
5976 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);
5977 else
5978 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);
5979 img = img.Insert(tile, (int)xs, (int)ys);
5980 i++;
5981 };
5982 using var mutated = img.Mutate(mutable =>
5983 {
5984 // Set the ImageDescription tag
5985 mutable.Set(GValue.GStrType, "image-description", met);
5986 mutable.Set(GValue.GIntType, "page-height", ss[last].Height);
5987 });
5988 if (bis[px][0].bitsPerPixel > 8)
5989 mutated.Tiffsave(file, compression, 1, Enums.ForeignTiffPredictor.None, true, ss[px].Width, ss[px].Height, true, false, 16,
5990 Enums.ForeignTiffResunit.Cm, 1000 * bis[px][0].PhysicalSizeX, 1000 * bis[px][0].PhysicalSizeY, true, null, Enums.RegionShrink.Nearest,
5991 compressionLevel, true, Enums.ForeignDzDepth.One, true, false, null, null, ss[px].Height);
5992 else
5993 mutated.Tiffsave(file, compression, 1, Enums.ForeignTiffPredictor.None, true, ss[px].Width, ss[px].Height, true, false, 8,
5994 Enums.ForeignTiffResunit.Cm, 1000 * bis[px][0].PhysicalSizeX, 1000 * bis[px][0].PhysicalSizeY, true, null, Enums.RegionShrink.Nearest,
5995 compressionLevel, true, Enums.ForeignDzDepth.One, true, false, null, null, ss[px].Height);
5996 s++;
5997 }
5998
5999 }
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:5841

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

◆ 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.
8404 {
8405 bms = imgs;
8406 savefile = file;
8407 comp = com;
8408 compLev = compLevel;
8409 await Task.Run(SavePyramidalThread);
8410 }

◆ 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.
4726 {
4727 string desc = "";
4728 int stride = 0;
4729 ImageJDesc j = new ImageJDesc();
4730 BioImage bi = Images.GetImage(IDs[0]);
4731 j.FromImage(bi);
4732 desc = j.GetString();
4733 for (int fi = 0; fi < IDs.Length; fi++)
4734 {
4735 string id = IDs[fi];
4736 BioImage b = Images.GetImage(id);
4737 string fn = Path.GetFileNameWithoutExtension(id);
4738 string dir = Path.GetDirectoryName(file);
4739 stride = b.Buffers[0].Stride;
4740
4741 //Save ROIs to CSV file.
4742 if (b.Annotations.Count > 0)
4743 {
4744 string f = dir + "//" + fn + ".csv";
4745 ExportROIsCSV(f, b.Annotations);
4746 }
4747
4748 //Embed ROI's to image description.
4749 for (int i = 0; i < b.Annotations.Count; i++)
4750 {
4751 desc += "-ROI:" + b.series + ":" + ROIToString(b.Annotations[i]) + NewLine;
4752 }
4753 foreach (Channel c in b.Channels)
4754 {
4755 string cj = JsonConvert.SerializeObject(c.info, Formatting.None);
4756 desc += "-Channel:" + fi + ":" + cj + NewLine;
4757 }
4758 string json = JsonConvert.SerializeObject(b.imageInfo, Formatting.None);
4759 desc += "-ImageInfo:" + fi + ":" + json + NewLine;
4760 }
4761
4762 Tiff image = Tiff.Open(file, "w");
4763 for (int fi = 0; fi < IDs.Length; fi++)
4764 {
4765 int im = 0;
4766 string id = IDs[fi];
4767 BioImage b = Images.GetImage(id);
4768 int sizec = 1;
4769 if (!b.isRGB)
4770 {
4771 sizec = b.SizeC;
4772 }
4773 byte[] buffer;
4774 for (int c = 0; c < sizec; c++)
4775 {
4776 for (int z = 0; z < b.SizeZ; z++)
4777 {
4778 for (int t = 0; t < b.SizeT; t++)
4779 {
4780 image.SetDirectory((short)(im + (b.Buffers.Count * fi)));
4781 image.SetField(TiffTag.IMAGEWIDTH, b.SizeX);
4782 image.SetField(TiffTag.IMAGEDESCRIPTION, desc);
4783 image.SetField(TiffTag.IMAGELENGTH, b.SizeY);
4784 image.SetField(TiffTag.BITSPERSAMPLE, b.bitsPerPixel);
4785 image.SetField(TiffTag.SAMPLESPERPIXEL, b.RGBChannelCount);
4786 image.SetField(TiffTag.ROWSPERSTRIP, b.SizeY);
4787 image.SetField(TiffTag.ORIENTATION, BitMiracle.LibTiff.Classic.Orientation.TOPLEFT);
4788 image.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
4789 image.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK);
4790 image.SetField(TiffTag.ROWSPERSTRIP, image.DefaultStripSize(0));
4791 if (b.PhysicalSizeX != -1 && b.PhysicalSizeY != -1)
4792 {
4793 image.SetField(TiffTag.XRESOLUTION, (b.PhysicalSizeX * b.SizeX) / ((b.PhysicalSizeX * b.SizeX) * b.PhysicalSizeX));
4794 image.SetField(TiffTag.YRESOLUTION, (b.PhysicalSizeY * b.SizeY) / ((b.PhysicalSizeY * b.SizeY) * b.PhysicalSizeY));
4795 image.SetField(TiffTag.RESOLUTIONUNIT, ResUnit.NONE);
4796 }
4797 else
4798 {
4799 image.SetField(TiffTag.XRESOLUTION, 100.0);
4800 image.SetField(TiffTag.YRESOLUTION, 100.0);
4801 image.SetField(TiffTag.RESOLUTIONUNIT, ResUnit.INCH);
4802 }
4803 // specify that it's a page within the multipage file
4804 image.SetField(TiffTag.SUBFILETYPE, FileType.PAGE);
4805 // specify the page number
4806 buffer = b.Buffers[im].GetSaveBytes(true);
4807 image.SetField(TiffTag.PAGENUMBER, im + (b.Buffers.Count * fi), b.Buffers.Count * IDs.Length);
4808 for (int i = 0, offset = 0; i < b.SizeY; i++)
4809 {
4810 image.WriteScanline(buffer, offset, i, 0);
4811 offset += stride;
4812 }
4813 image.WriteDirectory();
4814 im++;
4815 }
4816 }
4817 }
4818 }
4819 image.Dispose();
4820 }

◆ 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
8373 {
8374 sts.Clear();
8375 foreach (BioImage item in imgs)
8376 {
8377 sts.Add(item.ID);
8378 }
8379 savefile = file;
8380 some = ome;
8381 await Task.Run(SaveSeriesThread);
8382 }

◆ SetFrameIndex()

void BioLib.BioImage.SetFrameIndex ( int z,
int c,
int t,
int val )
7237 {
7238 Coords[z, c, t] = val;
7239 }

◆ 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.
4101 {
4102 Buffers[ind].SetValue(x, y, value);
4103 }

◆ 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
4111 {
4112 SetValue(x, y, GetFrameIndex(coord.Z, coord.C, coord.T), value);
4113 }
void SetValue(ZCTXY coord, ushort value)
It takes a coordinate and a value, and sets the value at that coordinate.
Definition Bio.cs:4089

◆ 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
4090 {
4091 int i = GetFrameIndex(coord.Z, coord.C, coord.T);
4092 Buffers[i].SetValue(coord.X, coord.Y, value);
4093 }

◆ 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
4121 {
4122 int ind = GetFrameIndex(coord.Z, coord.C, coord.T);
4123 Buffers[ind].SetValue(coord.X, coord.Y, RGBindex, value);
4124 }

◆ SortByType()

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

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

5403 {
5404 if (annotations == null || annotations.Length == 0)
5405 return Array.Empty<ROI>();
5406
5407 return annotations
5408 .OrderBy<ROI, string>(r => r.type.ToString(), StringComparer.OrdinalIgnoreCase)
5409 .ToArray();
5410 }

◆ 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
3814 {
3815 BioImage[] bms;
3816 if (isRGB)
3817 {
3818 bms = new BioImage[3];
3819 BioImage ri = new BioImage(System.IO.Path.GetFileNameWithoutExtension(ID) + "-1" + System.IO.Path.GetExtension(ID));
3820 BioImage gi = new BioImage(System.IO.Path.GetFileNameWithoutExtension(ID) + "-2" + System.IO.Path.GetExtension(ID));
3821 BioImage bi = new BioImage(System.IO.Path.GetFileNameWithoutExtension(ID) + "-3" + System.IO.Path.GetExtension(ID));
3822 ri.sizeC = 1;
3823 gi.sizeC = 1;
3824 bi.sizeC = 1;
3825 ri.sizeZ = SizeZ;
3826 gi.sizeZ = SizeZ;
3827 bi.sizeZ = SizeZ;
3828 ri.sizeT = SizeT;
3829 gi.sizeT = SizeT;
3830 bi.sizeT = SizeT;
3831
3832 ri.Coords = new int[SizeZ, 1, SizeT];
3833 gi.Coords = new int[SizeZ, 1, SizeT];
3834 bi.Coords = new int[SizeZ, 1, SizeT];
3835 int ind = 0;
3836 for (int i = 0; i < ImageCount; i++)
3837 {
3838 if (Buffers[i].PixelFormat == PixelFormat.Format48bppRgb)
3839 {
3840 //For 48bit images we need to use our own function as AForge won't give us a proper image.
3841 Bitmap[] bfs = Bitmap.RGB48To16(ID, SizeX, SizeY, Buffers[i].Stride, Buffers[i].Bytes, Buffers[i].Coordinate, ind, Buffers[i].Plane);
3842 ind += 3;
3843 ri.Buffers.Add(bfs[0]);
3844 gi.Buffers.Add(bfs[1]);
3845 bi.Buffers.Add(bfs[2]);
3846 bfs[0].Stats = Statistics.FromBytes(bfs[0]);
3847 bfs[1].Stats = Statistics.FromBytes(bfs[1]);
3848 bfs[2].Stats = Statistics.FromBytes(bfs[2]);
3849 ri.SetFrameIndex(Buffers[i].Coordinate.Z, Buffers[i].Coordinate.C, Buffers[i].Coordinate.T, i);
3850 gi.SetFrameIndex(Buffers[i].Coordinate.Z, Buffers[i].Coordinate.C, Buffers[i].Coordinate.T, i);
3851 bi.SetFrameIndex(Buffers[i].Coordinate.Z, Buffers[i].Coordinate.C, Buffers[i].Coordinate.T, i);
3852 }
3853 else
3854 {
3855
3856 Bitmap rImage = extractR.Apply(Buffers[i]);
3857 Bitmap rbf = new Bitmap(ri.ID, rImage, Buffers[i].Coordinate, ind++);
3858 rbf.Stats = Statistics.FromBytes(rbf);
3859 ri.Buffers.Add(rbf);
3860 ri.SetFrameIndex(Buffers[i].Coordinate.Z, Buffers[i].Coordinate.C, Buffers[i].Coordinate.T, i);
3861
3862 Bitmap gImage = extractG.Apply(Buffers[i]);
3863 Bitmap gbf = new Bitmap(gi.ID, gImage, Buffers[i].Coordinate, ind++);
3864 gbf.Stats = Statistics.FromBytes(gbf);
3865 gi.Buffers.Add(gbf);
3866 gi.SetFrameIndex(Buffers[i].Coordinate.Z, Buffers[i].Coordinate.C, Buffers[i].Coordinate.T, i);
3867
3868 Bitmap bImage = extractB.Apply(Buffers[i]);
3869 //Clipboard.SetImage(bImage);
3870 Bitmap bbf = new Bitmap(bi.ID, bImage, Buffers[i].Coordinate, ind++);
3871 bbf.Stats = Statistics.FromBytes(bbf);
3872 bi.Buffers.Add(bbf);
3873 bi.SetFrameIndex(Buffers[i].Coordinate.Z, Buffers[i].Coordinate.C, Buffers[i].Coordinate.T, i);
3874
3875 }
3876 }
3877 //We wait for threshold image statistics calculation
3878 do
3879 {
3880 Thread.Sleep(100);
3881 } while (bi.Buffers[bi.Buffers.Count - 1].Stats == null);
3882 ri.Resolutions.Add(new Resolution(Buffers[0].SizeX, Buffers[0].SizeY, Buffers[0].PixelFormat, PhysicalSizeX, PhysicalSizeY, PhysicalSizeZ, StageSizeX, StageSizeY, StageSizeZ));
3883 gi.Resolutions.Add(new Resolution(Buffers[0].SizeX, Buffers[0].SizeY, Buffers[0].PixelFormat, PhysicalSizeX, PhysicalSizeY, PhysicalSizeZ, StageSizeX, StageSizeY, StageSizeZ));
3884 bi.Resolutions.Add(new Resolution(Buffers[0].SizeX, Buffers[0].SizeY, Buffers[0].PixelFormat, PhysicalSizeX, PhysicalSizeY, PhysicalSizeZ, StageSizeX, StageSizeY, StageSizeZ));
3885 ri.Channels.Add(Channels[0].Copy());
3886 gi.Channels.Add(Channels[0].Copy());
3887 bi.Channels.Add(Channels[0].Copy());
3888 AutoThreshold(ri, false);
3889 AutoThreshold(gi, false);
3890 AutoThreshold(bi, false);
3891 Images.AddImage(ri);
3892 Images.AddImage(gi);
3893 Images.AddImage(bi);
3894 bms[0] = ri;
3895 bms[1] = gi;
3896 bms[2] = bi;
3897 }
3898 else
3899 {
3900 bms = new BioImage[SizeC];
3901 for (int c = 0; c < SizeC; c++)
3902 {
3903 BioImage b = BioImage.Substack(this, 0, 0, SizeZ, c, c + 1, 0, SizeT);
3904 bms[c] = b;
3905 }
3906 }
3907 return bms;
3908 }
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:3599

◆ 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
3915 {
3916 return bb.SplitChannels();
3917 }
BioImage[] SplitChannels()
It takes a single image and splits it into three images, one for each channel.
Definition Bio.cs:3813

◆ 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.
3924 {
3925 return SplitChannels(Images.GetImage(name));
3926 }

◆ 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
7400 {
7401 if (bit16)
7402 {
7403 for (int ch = 0; ch < Channels.Count; ch++)
7404 {
7405 for (int i = 0; i < Channels[ch].range.Length; i++)
7406 {
7407 Channels[ch].range[i].Min = (int)Channels[ch].stats[i].StackMin;
7408 Channels[ch].range[i].Max = (int)Channels[ch].stats[i].StackMax;
7409 }
7410 Channels[ch].BitsPerPixel = 16;
7411 }
7412 bitsPerPixel = 16;
7413 }
7414 else
7415 {
7416 for (int ch = 0; ch < Channels.Count; ch++)
7417 {
7418 for (int i = 0; i < Channels[ch].range.Length; i++)
7419 {
7420 Channels[ch].range[i].Min = (int)Channels[ch].stats[i].StackMin;
7421 Channels[ch].range[i].Max = (int)Channels[ch].stats[i].StackMax;
7422 }
7423 Channels[ch].BitsPerPixel = 8;
7424 }
7425 bitsPerPixel = 8;
7426 }
7427 Recorder.AddLine("BioLib.Images.GetImage(\"" + id + "\").StackThreshold(" + bit16.ToString().ToLower() + ");", true);
7428 }

◆ 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.
8909 {
8910 //Works with either comma or tab separated values.
8911 if (sts.StartsWith("<?xml") || sts.StartsWith("{"))
8912 return null;
8913 ROI an = new ROI();
8914 string val = "";
8915 bool inSep = false;
8916 int col = 0;
8917 double x = 0;
8918 double y = 0;
8919 double w = 0;
8920 double h = 0;
8921 string line = sts;
8922 bool points = false;
8923 char sep = '"';
8924 for (int i = 0; i < line.Length; i++)
8925 {
8926 char c = line[i];
8927 if (c == sep)
8928 {
8929 if (!inSep)
8930 {
8931 inSep = true;
8932 }
8933 else
8934 inSep = false;
8935 continue;
8936 }
8937
8938 if ((c == ',' || c == '\t') && (!inSep || points))
8939 {
8940 //ROIID,ROINAME,TYPE,ID,SHAPEINDEX,TEXT,C,Z,T,X,Y,W,H,POINTS,STROKECOLOR,STROKECOLORW,FILLCOLOR,FONTSIZE
8941 if (col == 0)
8942 {
8943 //ROIID
8944 an.roiID = val;
8945 }
8946 else
8947 if (col == 1)
8948 {
8949 //ROINAME
8950 an.roiName = val;
8951 }
8952 else
8953 if (col == 2)
8954 {
8955 //TYPE
8956 an.type = (ROI.Type)Enum.Parse(typeof(ROI.Type), val);
8957 if (an.type == ROI.Type.Freeform || an.type == ROI.Type.Polygon)
8958 an.closed = true;
8959 }
8960 else
8961 if (col == 3)
8962 {
8963 //ID
8964 an.id = val;
8965 }
8966 else
8967 if (col == 4)
8968 {
8969 //SHAPEINDEX/
8970 an.shapeIndex = int.Parse(val);
8971 }
8972 else
8973 if (col == 5)
8974 {
8975 //TEXT/
8976 an.Text = val;
8977 }
8978 else
8979 if (col == 6)
8980 {
8981 an.serie = int.Parse(val);
8982 }
8983 else
8984 if (col == 7)
8985 {
8986 an.coord.Z = int.Parse(val);
8987 }
8988 else
8989 if (col == 8)
8990 {
8991 an.coord.C = int.Parse(val);
8992 }
8993 else
8994 if (col == 9)
8995 {
8996 an.coord.T = int.Parse(val);
8997 }
8998 else
8999 if (col == 10)
9000 {
9001 x = double.Parse(val, CultureInfo.InvariantCulture);
9002 }
9003 else
9004 if (col == 11)
9005 {
9006 y = double.Parse(val, CultureInfo.InvariantCulture);
9007 }
9008 else
9009 if (col == 12)
9010 {
9011 w = double.Parse(val, CultureInfo.InvariantCulture);
9012 }
9013 else
9014 if (col == 13)
9015 {
9016 h = double.Parse(val, CultureInfo.InvariantCulture);
9017 }
9018 else
9019 if (col == 14)
9020 {
9021 //POINTS
9022 an.AddPoints(an.stringToPoints(val));
9023 points = false;
9024 an.BoundingBox = new RectangleD(x, y, w, h);
9025 }
9026 else
9027 if (col == 15)
9028 {
9029 //STROKECOLOR
9030 string[] st = val.Split(',');
9031 an.strokeColor = Color.FromArgb(int.Parse(st[0]), int.Parse(st[1]), int.Parse(st[2]), int.Parse(st[3]));
9032 }
9033 else
9034 if (col == 16)
9035 {
9036 //STROKECOLORW
9037 an.strokeWidth = double.Parse(val, CultureInfo.InvariantCulture);
9038 }
9039 else
9040 if (col == 17)
9041 {
9042 //FILLCOLOR
9043 string[] st = val.Split(',');
9044 an.fillColor = Color.FromArgb(int.Parse(st[0]), int.Parse(st[1]), int.Parse(st[2]), int.Parse(st[3]));
9045 }
9046 else
9047 if (col == 18)
9048 {
9049 //FONTSIZE
9050 double s = double.Parse(val, CultureInfo.InvariantCulture);
9051 an.fontSize = (float)s;
9052 an.family = "Times New Roman";
9053 }
9054 col++;
9055 val = "";
9056 }
9057 else
9058 val += c;
9059 }
9060
9061 return an;
9062 }

◆ 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.
3600 {
3601 BioImage b = CopyInfo(orig, false, false);
3602 //b.ID = Images.GetImageName(orig.ID);
3603 int i = 0;
3604 b.Coords = new int[ze - zs, ce - cs, te - ts];
3605 b.sizeZ = ze - zs;
3606 b.sizeC = ce - cs;
3607 b.sizeT = te - ts;
3608 for (int ti = 0; ti < b.SizeT; ti++)
3609 {
3610 for (int zi = 0; zi < b.SizeZ; zi++)
3611 {
3612 for (int ci = 0; ci < b.SizeC; ci++)
3613 {
3614 int ind = orig.GetFrameIndex(zs + zi, cs + ci, ts + ti);
3615 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);
3616 bf.Stats = Statistics.FromBytes(bf);
3617 b.Buffers.Add(bf);
3618 b.SetFrameIndex(zi, ci, ti, i);
3619 i++;
3620 }
3621 }
3622 }
3623 for (int ci = cs; ci < ce; ci++)
3624 {
3625 b.Channels.Add(orig.Channels[ci]);
3626 }
3627 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));
3628 AutoThreshold(b, false);
3629 if (b.bitsPerPixel > 8)
3630 b.StackThreshold(true);
3631 else
3632 b.StackThreshold(false);
3633 Images.AddImage(b);
3634 return b;
3635 }

◆ To16Bit()

void BioLib.BioImage.To16Bit ( )

Converts the image to 16 bit.

2836 {
2837 if (Buffers[0].RGBChannelsCount == 4)
2838 To24Bit();
2839 if (Buffers[0].PixelFormat == PixelFormat.Format16bppGrayScale)
2840 return;
2841 bitsPerPixel = 16;
2842 if (Buffers[0].PixelFormat == PixelFormat.Format48bppRgb)
2843 {
2844 List<Bitmap> bfs = new List<Bitmap>();
2845 int index = 0;
2846 for (int i = 0; i < Buffers.Count; i++)
2847 {
2848 Array.Reverse(Buffers[i].Bytes);
2849 Bitmap[] bs = Bitmap.RGB48To16(ID, SizeX, SizeY, Buffers[i].Stride, Buffers[i].Bytes, Buffers[i].Coordinate, index, Buffers[i].Plane);
2850 bfs.AddRange(bs);
2851 index += 3;
2852 }
2853 Buffers = bfs;
2854 UpdateCoords(SizeZ, SizeC * 3, SizeT);
2855 if (Channels[0].SamplesPerPixel == 3)
2856 {
2857 Channel c = Channels[0].Copy();
2858 c.SamplesPerPixel = 1;
2859 c.range = new IntRange[1];
2860 Channels.Clear();
2861 Channels.Add(c);
2862 Channels.Add(c.Copy());
2863 Channels.Add(c.Copy());
2864 Channels[1].Index = 1;
2865 Channels[2].Index = 2;
2866 }
2867 }
2868 else if (Buffers[0].PixelFormat == PixelFormat.Format8bppIndexed)
2869 {
2870 for (int i = 0; i < Buffers.Count; i++)
2871 {
2872 Buffers[i] = AForge.Imaging.Image.Convert8bppTo16bpp(Buffers[i]);
2873 }
2874 for (int c = 0; c < Channels.Count; c++)
2875 {
2876 for (int i = 0; i < Channels[c].range.Length; i++)
2877 {
2878 Channels[c].range[i].Min = (int)(((float)Channels[c].range[i].Min / (float)byte.MaxValue) * ushort.MaxValue);
2879 Channels[c].range[i].Max = (int)(((float)Channels[c].range[i].Max / (float)byte.MaxValue) * ushort.MaxValue);
2880 }
2881 Channels[c].BitsPerPixel = 16;
2882 }
2883 bitsPerPixel = 16;
2884 }
2885 else if (Buffers[0].PixelFormat == PixelFormat.Format24bppRgb)
2886 {
2887 To48Bit();
2888 To16Bit();
2889 }
2890 else if (Buffers[0].PixelFormat == PixelFormat.Float)
2891 {
2892 for (int i = 0; i < Buffers.Count; i++)
2893 {
2894 if (Statistics.StackMax <= 1)
2895 Buffers[i].To16Bit(true);
2896 else
2897 Buffers[i].To16Bit(false);
2898 }
2899 }
2900
2901 foreach (var item in Buffers)
2902 {
2903 item.Stats = Statistics.FromBytes(item);
2904 }
2905 AutoThreshold(this, true);
2906 StackThreshold(true);
2907 }
void To16Bit()
Converts the image to 16 bit.
Definition Bio.cs:2835
void To24Bit()
Converts the image to 24 bit.
Definition Bio.cs:2909
void To48Bit()
Definition Bio.cs:2987

◆ To24Bit()

void BioLib.BioImage.To24Bit ( )

Converts the image to 24 bit.

2910 {
2911 if (Buffers[0].PixelFormat == PixelFormat.Format24bppRgb)
2912 return;
2913 bitsPerPixel = 8;
2914 if (Buffers[0].PixelFormat == PixelFormat.Format32bppArgb || Buffers[0].PixelFormat == PixelFormat.Format32bppRgb)
2915 {
2916 for (int i = 0; i < Buffers.Count; i++)
2917 {
2918 Buffers[i] = Bitmap.To24Bit(Buffers[i]);
2919 }
2920 if (Channels.Count == 4)
2921 {
2922 Channels.RemoveAt(0);
2923 }
2924 else
2925 {
2926 Channels[0].SamplesPerPixel = 3;
2927 }
2928 }
2929 else
2930 if (Buffers[0].PixelFormat == PixelFormat.Format48bppRgb)
2931 {
2932 //We run 8bit so we get 24 bit rgb.
2933 for (int i = 0; i < Buffers.Count; i++)
2934 {
2935 Buffers[i] = AForge.Imaging.Image.Convert16bppTo8bpp(Buffers[i]);
2936 Buffers[i].SwitchRedBlue();
2937 }
2938 }
2939 else
2940 if (Buffers[0].PixelFormat == PixelFormat.Format16bppGrayScale)
2941 {
2942 //We run 8bit so we get 24 bit rgb.
2943 for (int i = 0; i < Buffers.Count; i++)
2944 {
2945 Buffers[i] = AForge.Imaging.Image.Convert16bppTo8bpp(Buffers[i]);
2946 }
2947 To24Bit();
2948 }
2949 else if(Buffers[0].PixelFormat == PixelFormat.Format8bppIndexed)
2950 {
2951 List<Bitmap> bms = new List<Bitmap>();
2952 //We run 8bit so we get 24 bit rgb.
2953 for (int i = 0; i < Buffers.Count; i+=3)
2954 {
2955 bms.Add(Bitmap.RGB8To24(new Bitmap[] { Buffers[i], Buffers[i+1], Buffers[i+2] }));
2956 }
2957 Buffers.Clear();
2958 Buffers.AddRange(bms);
2959 UpdateCoords(SizeZ, 1, SizeT);
2960 }
2961 foreach (var item in Buffers)
2962 {
2963 item.Stats = Statistics.FromBytes(item);
2964 }
2965 AutoThreshold(this, true);
2966 StackThreshold(false);
2967 }

◆ To32Bit()

void BioLib.BioImage.To32Bit ( )

Converts the image to 32 bit.

2970 {
2971 if (Buffers[0].PixelFormat == PixelFormat.Format32bppArgb)
2972 return;
2973 if (Buffers[0].PixelFormat != PixelFormat.Format24bppRgb)
2974 {
2975 To24Bit();
2976 }
2977 for (int i = 0; i < Buffers.Count; i++)
2978 {
2979 UnmanagedImage b = Bitmap.To32Bit(Buffers[i]);
2980 Buffers[i].Image = b;
2981 }
2982 AutoThreshold(this, true);
2983 }

◆ To48Bit()

void BioLib.BioImage.To48Bit ( )

It converts a 16 bit image to a 48 bit image

Returns
A list of Bitmaps.
2988 {
2989 if (Buffers[0].RGBChannelsCount == 4)
2990 To24Bit();
2991 if (Buffers[0].PixelFormat == PixelFormat.Format48bppRgb)
2992 return;
2993 if (Buffers[0].PixelFormat == PixelFormat.Format8bppIndexed || Buffers[0].PixelFormat == PixelFormat.Format16bppGrayScale)
2994 {
2995 if (Buffers[0].PixelFormat == PixelFormat.Format8bppIndexed)
2996 {
2997 for (int i = 0; i < Buffers.Count; i++)
2998 {
2999 Buffers[i].Image = AForge.Imaging.Image.Convert8bppTo16bpp(Buffers[i]);
3000 }
3001 }
3002 List<Bitmap> bfs = new List<Bitmap>();
3003 if (Buffers.Count % 3 != 0 && Buffers.Count % 2 != 0)
3004 for (int i = 0; i < Buffers.Count; i++)
3005 {
3006 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);
3007 Bitmap bbs = Bitmap.RGB16To48(bs);
3008 bs.Dispose();
3009 bs = null;
3010 bfs.Add(bbs);
3011 }
3012 else
3013 for (int i = 0; i < Buffers.Count; i += Channels.Count)
3014 {
3015 Bitmap[] bs = new Bitmap[3];
3016 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);
3017 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);
3018 if (Channels.Count > 2)
3019 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);
3020 Bitmap bbs = Bitmap.RGB16To48(bs);
3021 for (int b = 0; b < 3; b++)
3022 {
3023 if (bs[b] != null)
3024 bs[b].Dispose();
3025 bs[b] = null;
3026 }
3027 bfs.Add(bbs);
3028 }
3029 Buffers = bfs;
3030 UpdateCoords(SizeZ, 1, SizeT);
3031 Channel c = Channels[0].Copy();
3032 c.SamplesPerPixel = 3;
3033 rgbChannels[0] = 0;
3034 rgbChannels[1] = 0;
3035 rgbChannels[2] = 0;
3036 Channels.Clear();
3037 Channels.Add(c);
3038 }
3039 else
3040 if (Buffers[0].PixelFormat == PixelFormat.Format24bppRgb || Buffers[0].PixelFormat == PixelFormat.Format32bppArgb)
3041 {
3042 for (int i = 0; i < Buffers.Count; i++)
3043 {
3044 Buffers[i] = AForge.Imaging.Image.Convert8bppTo16bpp(Buffers[i]);
3045 Buffers[i].SwitchRedBlue();
3046 }
3047 }
3048 else
3049 {
3050 int index = 0;
3051 List<Bitmap> buffers = new List<Bitmap>();
3052 for (int i = 0; i < Buffers.Count; i += 3)
3053 {
3054 Bitmap[] bf = new Bitmap[3];
3055 bf[0] = Buffers[i];
3056 bf[1] = Buffers[i + 1];
3057 bf[2] = Buffers[i + 2];
3058 Bitmap inf = Bitmap.RGB16To48(bf);
3059 buffers.Add(inf);
3060 for (int b = 0; b < 3; b++)
3061 {
3062 bf[b].Dispose();
3063 }
3064 index++;
3065 }
3066 Buffers = buffers;
3067 UpdateCoords(SizeZ, 1, SizeT);
3068 }
3069 bitsPerPixel = 16;
3070 AutoThreshold(this, true);
3071 StackThreshold(true);
3072 }

◆ To8Bit()

void BioLib.BioImage.To8Bit ( )

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

2746 {
2747 if (Buffers[0].RGBChannelsCount == 4)
2748 To24Bit();
2749 PixelFormat px = Buffers[0].PixelFormat;
2750 if (px == PixelFormat.Format8bppIndexed)
2751 return;
2752 if (px == PixelFormat.Format48bppRgb)
2753 {
2754 To24Bit();
2755 List<AForge.Bitmap> bfs = new List<AForge.Bitmap>();
2756 int index = 0;
2757 for (int i = 0; i < Buffers.Count; i++)
2758 {
2759 Bitmap[] bs = Bitmap.RGB24To8(Buffers[i]);
2760 Bitmap br = new Bitmap(ID, bs[2], new ZCT(Buffers[i].Coordinate.Z, 0, Buffers[i].Coordinate.T), index, Buffers[i].Plane);
2761 Bitmap bg = new Bitmap(ID, bs[1], new ZCT(Buffers[i].Coordinate.Z, 1, Buffers[i].Coordinate.T), index + 1, Buffers[i].Plane);
2762 Bitmap bb = new Bitmap(ID, bs[0], new ZCT(Buffers[i].Coordinate.Z, 2, Buffers[i].Coordinate.T), index + 2, Buffers[i].Plane);
2763 for (int b = 0; b < 3; b++)
2764 {
2765 bs[b].Dispose();
2766 }
2767 bs = null;
2768 br.Stats = Statistics.FromBytes(br);
2769 bg.Stats = Statistics.FromBytes(bg);
2770 bb.Stats = Statistics.FromBytes(bb);
2771 bfs.Add(br);
2772 bfs.Add(bg);
2773 bfs.Add(bb);
2774 index += 3;
2775 }
2776 Buffers = bfs;
2777 UpdateCoords(SizeZ, 3, SizeT);
2778 }
2779 else
2780 if (px == PixelFormat.Format24bppRgb)
2781 {
2782 List<Bitmap> bfs = new List<Bitmap>();
2783 int index = 0;
2784 for (int i = 0; i < Buffers.Count; i++)
2785 {
2786 Bitmap[] bs = Bitmap.RGB24To8(Buffers[i]);
2787 Bitmap br = new Bitmap(ID, bs[2], new ZCT(Buffers[i].Coordinate.Z, 0, Buffers[i].Coordinate.T), index, Buffers[i].Plane);
2788 Bitmap bg = new Bitmap(ID, bs[1], new ZCT(Buffers[i].Coordinate.Z, 1, Buffers[i].Coordinate.T), index + 1, Buffers[i].Plane);
2789 Bitmap bb = new Bitmap(ID, bs[0], new ZCT(Buffers[i].Coordinate.Z, 2, Buffers[i].Coordinate.T), index + 2, Buffers[i].Plane);
2790 for (int b = 0; b < 3; b++)
2791 {
2792 bs[b].Dispose();
2793 bs[b] = null;
2794 }
2795 bs = null;
2796 br.Stats = Statistics.FromBytes(br);
2797 bg.Stats = Statistics.FromBytes(bg);
2798 bb.Stats = Statistics.FromBytes(bb);
2799 bfs.Add(br);
2800 bfs.Add(bg);
2801 bfs.Add(bb);
2802 index += 3;
2803 }
2804 Buffers = bfs;
2805 UpdateCoords(SizeZ, 3, SizeT);
2806 Channels.Clear();
2807 Channels.Add(new Channel(0, 8, 1));
2808 Channels.Add(new Channel(0, 8, 1));
2809 Channels.Add(new Channel(0, 8, 1));
2810 }
2811 else
2812 if (px == PixelFormat.Format16bppGrayScale)
2813 {
2814 foreach (var item in Buffers)
2815 {
2816 item.To8Bit();
2817 }
2818 }
2819 else
2820 if (px == PixelFormat.Float)
2821 {
2822 foreach (var item in Buffers)
2823 {
2824 if (Statistics.StackMax <= 1)
2825 item.To8Bit(true);
2826 else
2827 item.To8Bit(false);
2828 }
2829 }
2830 AutoThreshold(this, true);
2831 StackThreshold(false);
2832 bitsPerPixel = 8;
2833 }

◆ ToFloat()

void BioLib.BioImage.ToFloat ( )
3083 {
3084 foreach (var b in Buffers)
3085 {
3086 b.ToFloat();
3087 b.Stats = Statistics.FromBytes(b);
3088 }
3089 AutoThreshold(this, true);
3090 StackThreshold(false);
3091 }

◆ 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.
3352 {
3353 return d / PhysicalSizeX;
3354 }

◆ 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.
3362 {
3363 return d / PhysicalSizeY;
3364 }

◆ 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.
3405 {
3406 PointD[] ps = new PointD[p.Count];
3407 for (int i = 0; i < p.Count; i++)
3408 {
3409 PointD pp = new PointD();
3410 pp.X = ((p[i].X - StageSizeX) / PhysicalSizeX);
3411 pp.Y = ((p[i].Y - StageSizeY) / PhysicalSizeY);
3412 ps[i] = pp;
3413 }
3414 return ps;
3415 }

◆ 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.
7502 {
7503 PointD[] ps = new PointD[p.Count];
7504 for (int i = 0; i < p.Count; i++)
7505 {
7506 PointD pp = new PointD();
7507 pp.X = ((p[i].X - stageSizeX) / physicalSizeX);
7508 pp.Y = ((p[i].Y - stageSizeY) / physicalSizeY);
7509 ps[i] = pp;
7510 }
7511 return ps;
7512 }

◆ 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.
3393 {
3394 PointD pp = new PointD();
3395 pp.X = (float)((p.X - StageSizeX) / PhysicalSizeX);
3396 pp.Y = (float)((p.Y - StageSizeY) / PhysicalSizeY);
3397 return pp;
3398 }

◆ 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[]
3423 {
3424 PointF[] ps = new PointF[p.Length];
3425 for (int i = 0; i < p.Length; i++)
3426 {
3427 PointF pp = new PointF();
3428 pp.X = (float)((p[i].X - StageSizeX) / PhysicalSizeX);
3429 pp.Y = (float)((p[i].Y - StageSizeY) / PhysicalSizeY);
3430 ps[i] = pp;
3431 }
3432 return ps;
3433 }

◆ 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.
3440 {
3441 RectangleF r = new RectangleF();
3442 Point pp = new Point();
3443 r.X = (int)((p.X - StageSizeX) / PhysicalSizeX);
3444 r.Y = (int)((p.Y - StageSizeY) / PhysicalSizeY);
3445 r.Width = (int)(p.W / PhysicalSizeX);
3446 r.Height = (int)(p.H / PhysicalSizeY);
3447 return r;
3448 }

◆ 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.
3371 {
3372 if (isPyramidal)
3373 return x;
3374 return (float)((x - StageSizeX) / PhysicalSizeX);
3375 }

◆ 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.
3382 {
3383 if (isPyramidal)
3384 return y;
3385 return (float)((y - StageSizeY) / PhysicalSizeY);
3386 }

◆ ToShort()

void BioLib.BioImage.ToShort ( )
3074 {
3075 foreach (var b in Buffers)
3076 {
3077 b.ToShort();
3078 }
3079 AutoThreshold(this, true);
3080 StackThreshold(false);
3081 }

◆ 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.
3455 {
3456 PointD pp = new PointD();
3457 if (isPyramidal)
3458 {
3459 pp.X = ((p.X * Resolutions[Level].PhysicalSizeX) + Volume.Location.X);
3460 pp.Y = ((p.Y * Resolutions[Level].PhysicalSizeY) + Volume.Location.Y);
3461 return pp;
3462 }
3463 else
3464 {
3465 pp.X = ((p.X * PhysicalSizeX) + Volume.Location.X);
3466 pp.Y = ((p.Y * PhysicalSizeY) + Volume.Location.Y);
3467 return pp;
3468 }
3469 }

◆ 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.
3494 {
3495 PointD pp = new PointD();
3496 pp.X = ((p.X * physicalSizeX) + volumeX);
3497 pp.Y = ((p.Y * physicalSizeY) + volumeY);
3498 return pp;
3499 }

◆ 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.
3477 {
3478 PointD pp = new PointD();
3479 pp.X = ((p.X * Resolutions[resolution].PhysicalSizeX) + Volume.Location.X);
3480 pp.Y = ((p.Y * Resolutions[resolution].PhysicalSizeY) + Volume.Location.Y);
3481 return pp;
3482 }

◆ 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.
3541 {
3542 PointD[] ps = new PointD[p.Length];
3543 for (int i = 0; i < p.Length; i++)
3544 {
3545 PointD pp = new PointD();
3546 pp.X = ((p[i].X * PhysicalSizeX) + Volume.Location.X);
3547 pp.Y = ((p[i].Y * PhysicalSizeY) + Volume.Location.Y);
3548 ps[i] = pp;
3549 }
3550 return ps;
3551 }

◆ 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.
3564 {
3565 PointD[] ps = new PointD[p.Length];
3566 for (int i = 0; i < p.Length; i++)
3567 {
3568 PointD pp = new PointD();
3569 pp.X = ((p[i].X * physicalSizeX) + volumeX);
3570 pp.Y = ((p[i].Y * physicalSizeY) + volumeY);
3571 ps[i] = pp;
3572 }
3573 return ps;
3574 }

◆ 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.
3507 {
3508 RectangleD r = new RectangleD();
3509 r.X = ((p.X * PhysicalSizeX) + Volume.Location.X);
3510 r.Y = ((p.Y * PhysicalSizeY) + Volume.Location.Y);
3511 r.W = (p.W * PhysicalSizeX);
3512 r.H = (p.H * PhysicalSizeY);
3513 return r;
3514 }

◆ 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.
3526 {
3527 RectangleD r = new RectangleD();
3528 r.X = ((p.X * physicalSizeX) + volumeX);
3529 r.Y = ((p.Y * physicalSizeY) + volumeY);
3530 r.W = (p.W * physicalSizeX);
3531 r.H = (p.H * physicalSizeY);
3532 return r;
3533 }

◆ 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.
9319 {
9320 return "BioLib.Images.GetImage(\"" + id + "\")";
9321 }

◆ Update() [1/2]

void BioLib.BioImage.Update ( )

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

8298 {
8299 Update(this);
8300 }
void Update()
Definition Bio.cs:8297

◆ 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.
7699 {
7700 b = OpenFile(b.file);
7701 }

◆ UpdateBuffersPyramidal()

async Task BioLib.BioImage.UpdateBuffersPyramidal ( int level)

Updates the Buffers based on current pyramidal origin and resolution.

7725 {
7726 try
7727 {
7728 if (Type != ImageType.pyramidal)
7729 return;
7730 for (int i = 0; i < Buffers.Count; i++)
7731 {
7732 Buffers[i].Dispose();
7733 }
7734 Buffers.Clear();
7735 for (int z = 0; z < SizeZ; z++)
7736 {
7737 for (int c = 0; c < SizeC; c++)
7738 {
7739 for (int t = 0; t < SizeT; t++)
7740 {
7741 ZCT co = new ZCT(z, c, t);
7742 if (openSlideImage != null)
7743 {
7744 startos:
7745 double minX = PyramidalOrigin.X * Resolution;
7746 double worldY = -PyramidalOrigin.Y * Resolution; // Top of viewport in world coords (negative)
7747 double width = PyramidalSize.Width * Resolution;
7748 double height = PyramidalSize.Height * Resolution;
7749 // In OSM, extent goes from bottom-Y to top-Y, so:
7750 var extent = new Extent(minX, worldY - height, minX + width, worldY);
7751 var slicep = new OpenSlideGTK.SliceParame();
7752 slicep.DstPixelWidth = PyramidalSize.Width;
7753 slicep.DstPixelHeight = PyramidalSize.Height;
7754 slicep.Quality = 100;
7755 var sliceInfo = new OpenSlideGTK.SliceInfo
7756 {
7757 Extent = extent,
7759 Parame = slicep,
7760 };
7761 byte[] bts = await openslideBase.GetSliceAsync(sliceInfo, level, Coordinate);
7762 if (bts == null)
7763 {
7764 pyramidalOrigin = new PointD(0, 0);
7765 resolution = this.OpenSlideBase.Schema.Resolutions.Last().Value.UnitsPerPixel;
7766 goto startos;
7767 }
7768 Bitmap bmp = new Bitmap((int)Math.Round(OpenSlideBase.destExtent.Width), (int)Math.Round(OpenSlideBase.destExtent.Height), PixelFormat.Format32bppArgb, bts, co, "");
7769 Buffers.Add(bmp);
7770 }
7771 else
7772 {
7773 start:
7774 double minX = PyramidalOrigin.X;
7775 double minY = PyramidalOrigin.Y;
7776 double width = PyramidalSize.Width * Resolution;
7777 double height = PyramidalSize.Height * Resolution;
7778 double maxX = minX + width;
7779 double maxY = minY + height;
7780 var extent = new Extent(minX, minY, maxX, maxY);
7781 var slicep = new SliceParame();
7782 slicep.DstPixelWidth = PyramidalSize.Width;
7783 slicep.DstPixelHeight = PyramidalSize.Height;
7784 slicep.Quality = 100;
7785 var sliceInfo = new SliceInfo
7786 {
7787 Extent = extent,
7788 Resolution = resolution,
7789 Coordinate = co,
7790 Parame = slicep,
7791 };
7792 byte[] bts = await SlideBase.GetSlice(sliceInfo, PyramidalOrigin, PyramidalSize);
7793 if (bts == null)
7794 {
7795 pyramidalOrigin = new PointD(0, 0);
7796 resolution = this.OpenSlideBase.Schema.Resolutions.Last().Value.UnitsPerPixel;
7797 goto start;
7798 }
7799 //SlideBase.SetSliceInfo(level, this.Resolutions[0].PixelFormat, Coordinate);
7800 Bitmap bmp = new Bitmap((int)Math.Round(SlideBase.destExtent.Width), (int)Math.Round(SlideBase.destExtent.Height), PixelFormat.Format32bppArgb, bts, co, "");
7801 Buffers.Add(bmp);
7802 }
7803 }
7804 }
7805 }
7806 BioImage.AutoThreshold(this, false);
7807 if (bitsPerPixel > 8)
7808 StackThreshold(true);
7809 else
7810 StackThreshold(false);
7811 }
7812 catch (Exception e)
7813 {
7814 Console.WriteLine(e.Message);
7815 }
7816 }
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:9141
Slice info.
Definition ISlideSource.cs:697
Definition ISlideSource.cs:744
async Task< byte[]> GetSlice(SliceInfo sliceInfo, PointD PyramidalOrign, AForge.Size PyramidalSize)
Get slice.
Definition ISlideSource.cs:344

◆ UpdateBuffersWells()

void BioLib.BioImage.UpdateBuffersWells ( )
8257 {
8258 try
8259 {
8260 if (Type != ImageType.well)
8261 return;
8262 for (int i = 0; i < Buffers.Count; i++)
8263 {
8264 Buffers[i].Dispose();
8265 }
8266 Buffers.Clear();
8267 if (imRead.getSeries() != Level)
8268 this.imRead.setSeries(Level);
8269 int w = imRead.getSizeX();
8270 int h = imRead.getSizeY();
8271 for (int z = 0; z < SizeZ; z++)
8272 {
8273 for (int c = 0; c < SizeC; c++)
8274 {
8275 for (int t = 0; t < SizeT; t++)
8276 {
8277 byte[] bm = this.imRead.openBytes(Coords[z, c, t]);
8278 Bitmap bmp = new Bitmap(w, h, Resolutions[Level].PixelFormat, bm, new ZCT(z, c, t), "");
8279 bmp.Stats = Statistics.FromBytes(bmp);
8280 Buffers.Add(bmp);
8281 }
8282 }
8283 }
8284 BioImage.AutoThreshold(this, false);
8285 if (bitsPerPixel > 8)
8286 StackThreshold(true);
8287 else
8288 StackThreshold(false);
8289 }
8290 catch (Exception e)
8291 {
8292 Console.WriteLine(e.Message);
8293 }
8294 }

◆ UpdateCoords() [1/3]

void BioLib.BioImage.UpdateCoords ( )

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

3190 {
3191 int z = 0;
3192 int c = 0;
3193 int t = 0;
3194 Coords = new int[SizeZ, SizeC, SizeT];
3195 for (int im = 0; im < Buffers.Count; im++)
3196 {
3197 ZCT co = new ZCT(z, c, t);
3198 SetFrameIndex(co.Z, co.C, co.T, im);
3199 Buffers[im].Coordinate = co;
3200 if (c < SizeC - 1)
3201 c++;
3202 else
3203 {
3204 c = 0;
3205 if (z < SizeZ - 1)
3206 z++;
3207 else
3208 {
3209 z = 0;
3210 if (t < SizeT - 1)
3211 t++;
3212 else
3213 t = 0;
3214 }
3215 }
3216 }
3217 }

◆ 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
3225 {
3226 int z = 0;
3227 int c = 0;
3228 int t = 0;
3229 sizeZ = sz;
3230 sizeC = sc;
3231 sizeT = st;
3232 Coords = new int[sz, sc, st];
3233 for (int im = 0; im < Buffers.Count; im++)
3234 {
3235 ZCT co = new ZCT(z, c, t);
3236 SetFrameIndex(co.Z, co.C, co.T, im);
3237 Buffers[im].Coordinate = co;
3238 if (c < SizeC - 1)
3239 c++;
3240 else
3241 {
3242 c = 0;
3243 if (z < SizeZ - 1)
3244 z++;
3245 else
3246 {
3247 z = 0;
3248 if (t < SizeT - 1)
3249 t++;
3250 else
3251 t = 0;
3252 }
3253 }
3254 }
3255 }

◆ 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
3263 {
3264 int z = 0;
3265 int c = 0;
3266 int t = 0;
3267 sizeZ = sz;
3268 sizeC = sc;
3269 sizeT = st;
3270 Coords = new int[sz, sc, st];
3271 int fr = sz * sc * st;
3272 if (order == Order.CZT)
3273 {
3274 for (int im = 0; im < fr; im++)
3275 {
3276 ZCT co = new ZCT(z, c, t);
3277 SetFrameIndex(co.Z, co.C, co.T, im);
3278 if (c < SizeC - 1)
3279 c++;
3280 else
3281 {
3282 c = 0;
3283 if (z < SizeZ - 1)
3284 z++;
3285 else
3286 {
3287 z = 0;
3288 if (t < SizeT - 1)
3289 t++;
3290 else
3291 t = 0;
3292 }
3293 }
3294 }
3295 }
3296 else if (order == Order.ZCT)
3297 {
3298 for (int im = 0; im < fr; im++)
3299 {
3300 ZCT co = new ZCT(z, c, t);
3301 SetFrameIndex(co.Z, co.C, co.T, im);
3302 if (z < SizeZ - 1)
3303 z++;
3304 else
3305 {
3306 z = 0;
3307 if (c < SizeC - 1)
3308 c++;
3309 else
3310 {
3311 c = 0;
3312 if (t < SizeT - 1)
3313 t++;
3314 else
3315 t = 0;
3316 }
3317 }
3318 }
3319 }
3320 else
3321 {
3322 //Order.TZC
3323 for (int im = 0; im < fr; im++)
3324 {
3325 ZCT co = new ZCT(z, c, t);
3326 SetFrameIndex(co.Z, co.C, co.T, im);
3327 if (t < SizeT - 1)
3328 t++;
3329 else
3330 {
3331 t = 0;
3332 if (z < SizeZ - 1)
3333 z++;
3334 else
3335 {
3336 z = 0;
3337 if (c < SizeC - 1)
3338 c++;
3339 else
3340 c = 0;
3341 }
3342 }
3343 }
3344 }
3345 }

◆ 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.
8433 {
8434
8435 try
8436 {
8437 if (isOME(file))
8438 {
8439 return true;
8440 }
8441 netim = NetVips.Image.Tiffload(file);
8442 Settings.AddSettings("VipsSupport", "true");
8443 netim.Close();
8444 netim.Dispose();
8445 }
8446 catch (Exception e)
8447 {
8448 Console.WriteLine(e.ToString());
8449 return false;
8450 }
8451 return true;
8452 }

Member Data Documentation

◆ rgbChannels

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

Property Documentation

◆ AnnotationsB

List<ROI> BioLib.BioImage.AnnotationsB
get
2477 {
2478 get
2479 {
2480 return GetAnnotations(Coordinate.Z, BChannel.Index, Coordinate.T);
2481 }
2482 }

◆ AnnotationsG

List<ROI> BioLib.BioImage.AnnotationsG
get
2469 {
2470 get
2471 {
2472 return GetAnnotations(Coordinate.Z, GChannel.Index, Coordinate.T);
2473 }
2474 }

◆ AnnotationsR

List<ROI> BioLib.BioImage.AnnotationsR
get
2461 {
2462 get
2463 {
2464 return GetAnnotations(Coordinate.Z, RChannel.Index, Coordinate.T);
2465 }
2466 }

◆ BChannel

Channel BioLib.BioImage.BChannel
get
2450 {
2451 get
2452 {
2453 if (Channels.Count >= 3)
2454 return Channels[rgbChannels[2]];
2455 else
2456 return Channels[0];
2457 }
2458 }

◆ BRange

IntRange BioLib.BioImage.BRange
get
2668 {
2669 get
2670 {
2671 return BChannel.RangeB;
2672 }
2673 }

◆ Coordinate

ZCT BioLib.BioImage.Coordinate
getset
1936 {
1937 get
1938 {
1939 return coordinate;
1940 }
1941 set
1942 {
1943 coordinate = value;
1944 }
1945 }

◆ Filename

string BioLib.BioImage.Filename
getset
1987 {
1988 get
1989 {
1990 if (filename == null || filename == "")
1991 return Type.ToString() + ".ome.tif";
1992 return filename;
1993 }
1994 set
1995 {
1996 filename = value;
1997 }
1998 }

◆ GChannel

Channel BioLib.BioImage.GChannel
get
2440 {
2441 get
2442 {
2443 if (Channels.Count >= 3)
2444 return Channels[rgbChannels[1]];
2445 else
2446 return Channels[0];
2447 }
2448 }

◆ GRange

IntRange BioLib.BioImage.GRange
get
2661 {
2662 get
2663 {
2664 return GChannel.RangeG;
2665 }
2666 }

◆ ID

string BioLib.BioImage.ID
getset
2261 {
2262 get { return id; }
2263 set { id = value; }
2264 }

◆ ImageCount

int BioLib.BioImage.ImageCount
get
2266 {
2267 get
2268 {
2269 return Buffers.Count;
2270 }
2271 }

◆ Initialized

bool BioLib.BioImage.Initialized
staticget
2738 {
2739 get
2740 {
2741 return initialized;
2742 }
2743 }

◆ isPyramidal

bool BioLib.BioImage.isPyramidal
get
2713 {
2714 get
2715 {
2716 if (Type == ImageType.pyramidal)
2717 return true;
2718 else
2719 return false;
2720 }
2721 }

◆ isRGB

bool BioLib.BioImage.isRGB
get
2683 {
2684 get
2685 {
2686 if (RGBChannelCount == 3 || RGBChannelCount == 4)
2687 return true;
2688 else
2689 return false;
2690 }
2691 }

◆ isSeries

bool BioLib.BioImage.isSeries
get
2703 {
2704 get
2705 {
2706 if (seriesCount > 1)
2707 return true;
2708 else
2709 return false;
2710 }
2711 }

◆ isTime

bool BioLib.BioImage.isTime
get
2693 {
2694 get
2695 {
2696 if (SizeT > 1)
2697 return true;
2698 else
2699 return false;
2700 }
2701 }

◆ LabelResolution

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

◆ Level

int BioLib.BioImage.Level
getset
1960 {
1961 get
1962 {
1963 if (Type == ImageType.well)
1964 return level;
1965 int l = 0;
1966 if (openslideBase != null)
1967 l = OpenSlideGTK.TileUtil.GetLevel(openslideBase.Schema.Resolutions, Resolution);
1968 else
1969 if (slideBase != null)
1971 if (l < 0)
1972 return 0;
1973 return l;
1974 }
1975 set
1976 {
1977 if (value < 0)
1978 return;
1979 level = value;
1980 }
1981 }
int LevelFromResolution(double Resolution)
Returns the level of a given resolution.
Definition Bio.cs:2229

◆ MacroResolution

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

◆ Magnification

double BioLib.BioImage.Magnification
getset
2645 {
2646 get; set;
2647 }

◆ OpenSlideBase

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

◆ PhysicalSizeX

double BioLib.BioImage.PhysicalSizeX
get
2273 {
2274 get
2275 {
2276 if (isPyramidal)
2277 return Resolutions[Level].PhysicalSizeX;
2278 else
2279 if (Plate != null)
2280 return Resolutions[serie].PhysicalSizeX;
2281 else if (Resolutions.Count > 0)
2282 return Resolutions[0].PhysicalSizeX;
2283 else
2284 return 0;
2285 }
2286 }

◆ PhysicalSizeY

double BioLib.BioImage.PhysicalSizeY
get
2288 {
2289 get
2290 {
2291 if (isPyramidal)
2292 return Resolutions[Level].PhysicalSizeY;
2293 else
2294 if (Plate != null)
2295 return Resolutions[serie].PhysicalSizeY;
2296 else if (Resolutions.Count > 0)
2297 return Resolutions[0].PhysicalSizeY;
2298 else
2299 return 0;
2300 }
2301 }

◆ PhysicalSizeZ

double BioLib.BioImage.PhysicalSizeZ
get
2303 {
2304 get
2305 {
2306 if (isPyramidal)
2307 return Resolutions[Level].PhysicalSizeZ;
2308 else
2309 if (Plate != null)
2310 return Resolutions[serie].PhysicalSizeZ;
2311 else if (Resolutions.Count > 0)
2312 return Resolutions[0].PhysicalSizeZ;
2313 else
2314 return 0;
2315 }
2316 }

◆ PyramidalOrigin

PointD BioLib.BioImage.PyramidalOrigin
getset
2364 {
2365 get
2366 {
2367 // Clamp X within the image width boundaries
2368 if (pyramidalOrigin.X >= Resolutions[Level].SizeX)
2369 pyramidalOrigin.X = Resolutions[Level].SizeX - 1;
2370 if (pyramidalOrigin.X < 0)
2371 pyramidalOrigin.X = 0;
2372
2373 // Clamp Y only if we are NOT using OSM Negative Y logic
2374 if (!UseOSMNegativeY)
2375 {
2376 if (pyramidalOrigin.Y >= Resolutions[Level].SizeY)
2377 pyramidalOrigin.Y = Resolutions[Level].SizeY - 1;
2378 if (pyramidalOrigin.Y < 0)
2379 pyramidalOrigin.Y = 0;
2380 }
2381
2382 return pyramidalOrigin;
2383 }
2384 set
2385 {
2386 if (UseOSMNegativeY)
2387 {
2388 // In OSM/BruTile mode, we allow Y to be negative and don't clamp the top
2389 // Just pass the values through, perhaps still clamping X width if desired
2390 pyramidalOrigin.X = Math.Max(0, Math.Min(value.X, Resolutions[Level].SizeX - 1));
2391 pyramidalOrigin.Y = value.Y;
2392 }
2393 else
2394 {
2395 // Standard Y-positive clamping logic
2396 if (value.X >= 0 && value.X < Resolutions[Level].SizeX)
2397 pyramidalOrigin.X = value.X;
2398 else if (value.X >= Resolutions[Level].SizeX)
2399 pyramidalOrigin.X = Resolutions[Level].SizeX - 1;
2400 else
2401 pyramidalOrigin.X = 0;
2402
2403 if (value.Y >= 0 && value.Y < Resolutions[Level].SizeY)
2404 pyramidalOrigin.Y = value.Y;
2405 else if (value.Y >= Resolutions[Level].SizeY)
2406 pyramidalOrigin.Y = Resolutions[Level].SizeY - 1;
2407 else
2408 pyramidalOrigin.Y = 0;
2409 }
2410 }
2411 }

◆ PyramidalSize

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

◆ RChannel

Channel BioLib.BioImage.RChannel
get
2430 {
2431 get
2432 {
2433 if(Channels.Count >= 3)
2434 return Channels[rgbChannels[0]];
2435 else
2436 return Channels[0];
2437 }
2438 }

◆ Resolution

double BioLib.BioImage.Resolution
getset
2031 {
2032 get { return resolution; }
2033 set
2034 {
2035 if (value <= 0)
2036 return;
2037 if (OpenSlideBase != null)
2038 {
2039 if (value >= OpenSlideBase.Schema.Resolutions.Last().Value.UnitsPerPixel)
2040 return;
2041 }
2042 else
2043 {
2044 if (value >= SlideBase.Schema.Resolutions.Last().Value.UnitsPerPixel)
2045 return;
2046 }
2047 resolution = value;
2048 }
2049 }

◆ RGBChannelCount

int BioLib.BioImage.RGBChannelCount
get
2001 {
2002 get
2003 {
2004 return Buffers[0].RGBChannelsCount;
2005 }
2006 }

◆ RRange

IntRange BioLib.BioImage.RRange
get
2654 {
2655 get
2656 {
2657 return RChannel.RangeR;
2658 }
2659 }

◆ SelectedBuffer

Bitmap BioLib.BioImage.SelectedBuffer
get
2675 {
2676 get
2677 {
2678 return Buffers[GetFrameIndex(Coordinate.Z, Coordinate.C, Coordinate.T)];
2679 }
2680 }

◆ series

int BioLib.BioImage.series
getset
2413 {
2414 get
2415 {
2416 return imageInfo.Series;
2417 }
2418 set
2419 {
2420 imageInfo.Series = value;
2421 }
2422 }

◆ SizeC

int BioLib.BioImage.SizeC
get
2630 {
2631 get { return sizeC; }
2632 }

◆ SizeT

int BioLib.BioImage.SizeT
get
2634 {
2635 get { return sizeT; }
2636 }

◆ SizeX

int BioLib.BioImage.SizeX
get
2608 {
2609 get
2610 {
2611 if (Buffers.Count > 0)
2612 return Buffers[0].SizeX;
2613 else return 0;
2614 }
2615 }

◆ SizeY

int BioLib.BioImage.SizeY
get
2617 {
2618 get
2619 {
2620 if (Buffers.Count > 0)
2621 return Buffers[0].SizeY;
2622 else return 0;
2623 }
2624 }

◆ SizeZ

int BioLib.BioImage.SizeZ
get
2626 {
2627 get { return sizeZ; }
2628 }

◆ SlideBase

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

◆ StackOrder

Order BioLib.BioImage.StackOrder
getset
2649 {
2650 get; set;
2651 }

◆ StageSizeX

double BioLib.BioImage.StageSizeX
get
2318 {
2319 get
2320 {
2321 if (isPyramidal)
2322 return Resolutions[Level].StageSizeX;
2323 else
2324 if (Plate != null)
2325 return Resolutions[serie].StageSizeX;
2326 else
2327 return Resolutions[0].StageSizeX;
2328 }
2329
2330 }

◆ StageSizeY

double BioLib.BioImage.StageSizeY
get
2332 {
2333 get
2334 {
2335 if (isPyramidal)
2336 return Resolutions[Level].StageSizeY;
2337 else
2338 if (Plate != null)
2339 return Resolutions[serie].StageSizeY;
2340 else
2341 return Resolutions[0].StageSizeY;
2342 }
2343
2344 }

◆ StageSizeZ

double BioLib.BioImage.StageSizeZ
get
2346 {
2347 get
2348 {
2349 if (isPyramidal)
2350 return Resolutions[Level].StageSizeZ;
2351 else
2352 if (Plate != null)
2353 return Resolutions[serie].StageSizeZ;
2354 else
2355 return Resolutions[0].StageSizeZ;
2356 }
2357 }

◆ Statistics

Statistics BioLib.BioImage.Statistics
getset
2017 {
2018 get
2019 {
2020 return statistics;
2021 }
2022 set
2023 {
2024 statistics = value;
2025 }
2026 }

◆ Status

string BioLib.BioImage.Status
staticgetset
2725 {
2726 get
2727 {
2728 return stat;
2729 }
2730 set
2731 {
2732 stat = value;
2733 Console.WriteLine(stat);
2734 }
2735 }

◆ Tag

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

◆ Type

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

◆ UseOSMNegativeY

bool BioLib.BioImage.UseOSMNegativeY = true
getset
2361{ get; set; } = true;

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