private void CropToolStripMenuItem_click(ROI roi, string dir)
        {
            if (checkBox_Tracking.Checked && roi.Type == 1)
            {
                TrackCropToolStripMenuItem_click(roi, dir);
                return;
            }

            fi.available = false;
            TifFileInfo newFI = null;

            Rectangle rect = Rectangle.Empty;

            //find rectangles

            switch (roi.Type)
            {
            case 0:
                if (roi.Shape == 1 | roi.Shape == 0)
                {
                    Point p    = roi.GetLocation(fi.cValue)[0];
                    Size  size = new Size(roi.Width, roi.Height);

                    rect = new Rectangle(p, size);
                }
                else if (roi.Shape == 2 || roi.Shape == 3 || roi.Shape == 4 || roi.Shape == 5)
                {
                    Point[] pList = roi.GetLocation(fi.cValue);

                    int X = int.MaxValue;
                    int Y = int.MaxValue;
                    int W = int.MinValue;
                    int H = int.MinValue;

                    foreach (Point p1 in pList)
                    {
                        if (p1.X < X)
                        {
                            X = p1.X;
                        }
                        if (p1.Y < Y)
                        {
                            Y = p1.Y;
                        }
                        if (p1.X > W)
                        {
                            W = p1.X;
                        }
                        if (p1.Y > H)
                        {
                            H = p1.Y;
                        }
                    }

                    Point p    = new Point(X, Y);
                    Size  size = new Size(W - X, H - Y);

                    rect = new Rectangle(p, size);
                }
                break;

            case 1:
                if (roi.Shape == 1 | roi.Shape == 0)
                {
                    Point[] pList = roi.GetLocationAll()[0];

                    int X = int.MaxValue;
                    int Y = int.MaxValue;
                    int W = int.MinValue;
                    int H = int.MinValue;

                    for (int i = fi.cValue; i < fi.imageCount; i += fi.sizeC)
                    {
                        Point p1 = pList[i];
                        if (p1 != null)
                        {
                            if (p1.X < X)
                            {
                                X = p1.X;
                            }
                            if (p1.Y < Y)
                            {
                                Y = p1.Y;
                            }
                            if (p1.X > W)
                            {
                                W = p1.X;
                            }
                            if (p1.Y > H)
                            {
                                H = p1.Y;
                            }
                        }
                    }

                    Point p    = new Point(X, Y);
                    Size  size = new Size(W - X + roi.Width, H - Y + roi.Height);

                    rect = new Rectangle(p, size);
                }
                else if (roi.Shape == 2 || roi.Shape == 3 || roi.Shape == 4 || roi.Shape == 5)
                {
                    int     X = int.MaxValue;
                    int     Y = int.MaxValue;
                    int     W = int.MinValue;
                    int     H = int.MinValue;
                    Point[] pList;

                    for (int i = fi.cValue; i < fi.imageCount; i += fi.sizeC)
                    {
                        pList = roi.GetLocation(i);

                        foreach (Point p1 in pList)
                        {
                            if (p1.X < X)
                            {
                                X = p1.X;
                            }
                            if (p1.Y < Y)
                            {
                                Y = p1.Y;
                            }
                            if (p1.X > W)
                            {
                                W = p1.X;
                            }
                            if (p1.Y > H)
                            {
                                H = p1.Y;
                            }
                        }
                    }

                    Point p    = new Point(X, Y);
                    Size  size = new Size(W - X, H - Y);

                    rect = new Rectangle(p, size);
                }
                break;
            }

            //crop the rectangle
            newFI     = DuplicateFI(fi);
            newFI.Dir = newFI.Dir.Substring(0, newFI.Dir.LastIndexOf(".")) + "_ROI"
                        + (fi.roiList[fi.cValue].IndexOf(roi) + 1).ToString() + ".tif";

            newFI.sizeX = rect.Width;
            newFI.sizeY = rect.Height;

            newFI.xCompensation = rect.X;
            newFI.yCompensation = rect.Y;

            newFI.imageCount   = fi.imageCount;
            newFI.openedImages = newFI.imageCount;
            AddEmptyArraysToFI(newFI);

            switch (fi.bitsPerPixel)
            {
            case 8:
                byte[][][] image8bit = new byte[fi.imageCount][][];
                Parallel.For(0, fi.imageCount, frame =>
                {
                    image8bit[frame] = new byte[rect.Height][];
                    for (int y = rect.Y, yNew = 0; y < rect.Y + rect.Height; y++, yNew++)
                    {
                        image8bit[frame][yNew] = new byte[rect.Width];

                        for (int x = rect.X, xNew = 0; x < rect.X + rect.Width; x++, xNew++)
                        {
                            if (x >= 0 && y >= 0 && x < fi.sizeX && y < fi.sizeY)
                            {
                                image8bit[frame][yNew][xNew] = fi.image8bit[frame][y][x];
                            }
                        }
                    }
                });
                newFI.image8bit       = image8bit;
                newFI.image8bitFilter = newFI.image8bit;
                break;

            case 16:
                ushort[][][] image16bit = new ushort[fi.imageCount][][];
                Parallel.For(0, fi.imageCount, frame =>
                {
                    image16bit[frame] = new ushort[rect.Height][];
                    for (int y = rect.Y, yNew = 0; y < rect.Y + rect.Height; y++, yNew++)
                    {
                        image16bit[frame][yNew] = new ushort[rect.Width];

                        for (int x = rect.X, xNew = 0; x < rect.X + rect.Width; x++, xNew++)
                        {
                            if (x >= 0 && y >= 0 && x < fi.sizeX && y < fi.sizeY)
                            {
                                image16bit[frame][yNew][xNew] = fi.image16bit[frame][y][x];
                            }
                        }
                    }
                });
                newFI.image16bit       = image16bit;
                newFI.image16bitFilter = newFI.image16bit;
                break;
            }

            newFI.loaded   = true;
            newFI.original = false;
            if (CropRoi)
            {
                ROI roi1 = roi.Duplicate();
                RecalculateOriginalROI(roi1, newFI);
            }
            fi.available = true;
            FileEncoder.SaveTif(newFI, dir);
        }
        private void TrackCropToolStripMenuItem_click(ROI roi, string dir)
        {
            ROI roi1 = roi.Duplicate();

            roi = ROITransformer.ROIEditor.TransformToRect(fi, roi);
            if (roi == null)
            {
                return;
            }

            fi.available = false;
            TifFileInfo newFI = null;

            //crop the rectangle
            newFI     = DuplicateFI(fi);
            newFI.Dir = newFI.Dir.Substring(0, newFI.Dir.LastIndexOf(".")) + "_ROI"
                        + (fi.roiList[fi.cValue].IndexOf(roi) + 1).ToString() + ".tif";
            Size size = new Size(roi.Width, roi.Height);

            newFI.sizeX         = roi.Width;
            newFI.sizeY         = roi.Height;
            newFI.xCompensation = 0;
            newFI.yCompensation = 0;

            newFI.imageCount   = fi.imageCount;
            newFI.openedImages = newFI.imageCount;
            AddEmptyArraysToFI(newFI);

            Point[] locs = roi.GetLocationAll()[0];

            switch (fi.bitsPerPixel)
            {
            case 8:

                byte[][][] image8bit = new byte[fi.imageCount][][];
                Parallel.For(0, fi.imageCount, frame =>
                {
                    Point location = locs[frame];
                    Rectangle rect = new Rectangle(location, size);

                    image8bit[frame] = new byte[rect.Height][];
                    for (int y = rect.Y, yNew = 0; y < rect.Y + rect.Height; y++, yNew++)
                    {
                        image8bit[frame][yNew] = new byte[rect.Width];

                        for (int x = rect.X, xNew = 0; x < rect.X + rect.Width; x++, xNew++)
                        {
                            if (x >= 0 && y >= 0 && x < fi.sizeX && y < fi.sizeY)
                            {
                                image8bit[frame][yNew][xNew] = fi.image8bit[frame][y][x];
                            }
                        }
                    }
                });
                newFI.image8bit       = image8bit;
                newFI.image8bitFilter = newFI.image8bit;
                break;

            case 16:
                ushort[][][] image16bit = new ushort[fi.imageCount][][];
                Parallel.For(0, fi.imageCount, frame =>
                {
                    Point location = locs[frame];

                    Rectangle rect    = new Rectangle(location, size);
                    image16bit[frame] = new ushort[rect.Height][];
                    for (int y = rect.Y, yNew = 0; y < rect.Y + rect.Height; y++, yNew++)
                    {
                        image16bit[frame][yNew] = new ushort[rect.Width];

                        for (int x = rect.X, xNew = 0; x < rect.X + rect.Width; x++, xNew++)
                        {
                            if (x >= 0 && y >= 0 && x < fi.sizeX && y < fi.sizeY)
                            {
                                image16bit[frame][yNew][xNew] = fi.image16bit[frame][y][x];
                            }
                        }
                    }
                });
                newFI.image16bit       = image16bit;
                newFI.image16bitFilter = newFI.image16bit;
                break;
            }

            newFI.loaded   = true;
            newFI.original = false;

            if (CropRoi)
            {
                RecalculateOriginalROI(roi1, newFI, locs);
            }

            FileEncoder.SaveTif(newFI, dir);
            fi.available = true;
        }