Ejemplo n.º 1
0
            private Bitmap ReadRegion(SizeL location, int level, SizeL size)
            {
                Stopwatch sw = new Stopwatch();

                sw.Start();
                OpenSlide.TraceMsg("start ReadRegion " + level + "/" + location.Height + "_" + location.Width + ": " + GetBytesReadable(size.Width * size.Height * 3));
                Bitmap bmp = new Bitmap((int)size.Width, (int)size.Height);

                bmp.SetPixel(0, 0, Color.AliceBlue);
                var bmpdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

                OpenSlide.TraceMsg("bmp locked " + level + "/" + location.Height + "_" + location.Width);
                unsafe
                {
                    void *p = bmpdata.Scan0.ToPointer();
                    openslide_read_region(handle, p, location.Width, location.Height, level, size.Width, size.Height);
                }
                OpenSlide.TraceMsg("read finished " + level + "/" + location.Height + "_" + location.Width + ": " + GetBytesReadable(size.Width * size.Height * 3 / Math.Max(sw.ElapsedMilliseconds, 1)) + "/ms");
                bmp.UnlockBits(bmpdata);
                OpenSlide.TraceMsg("unlock bits " + level + "/" + location.Height + "_" + location.Width);
                if (bmp.GetPixel(0, 0) == Color.Black)
                {
                    var error = CheckForLastError();
                    if (error != null)
                    {
                        throw new ArgumentException($"error reading region loc:{location}, level:{level}, size:{size}" + error);
                    }
                    //else just a black image?
                }
                OpenSlide.TraceMsg("end ReadRegion " + level + "/" + location.Height + "_" + location.Width);
                return(bmp);
            }
Ejemplo n.º 2
0
            private SKBitmap ReadRegion(SizeL location, int level, SizeL size)
            {
                Stopwatch sw = new Stopwatch();

                sw.Start();
                OpenSlide.TraceMsg("start ReadRegion " + level + "/" + location.Height + "_" + location.Width + ": " + GetBytesReadable(size.Width * size.Height * 3));
                SKBitmap bmp = new SKBitmap((int)size.Width, (int)size.Height);

                bmp.SetPixel(0, 0, SKColors.AliceBlue);
                bmp.LockPixels();
                var bmpdata = bmp.GetPixels();

                OpenSlide.TraceMsg("bmp locked " + level + "/" + location.Height + "_" + location.Width);
                unsafe
                {
                    void *p = bmpdata.ToPointer();
                    Import.openslide_read_region(handle, p, location.Width, location.Height, level, size.Width, size.Height);
                }
                OpenSlide.TraceMsg("read finished " + level + "/" + location.Height + "_" + location.Width + ": " + GetBytesReadable(size.Width * size.Height * 3 / Math.Max(sw.ElapsedMilliseconds, 1)) + "/ms");
                bmp.UnlockPixels();
                OpenSlide.TraceMsg("unlock bits " + level + "/" + location.Height + "_" + location.Width);
                if (bmp.GetPixel(0, 0) == SKColors.Black)
                {
                    var error = CheckForLastError();
                    if (error != null)
                    {
                        throw new ArgumentException($"error reading region loc:{location}, level:{level}, size:{size}" + error);
                    }
                    //else just a black image?
                }
                OpenSlide.TraceMsg("end ReadRegion " + level + "/" + location.Height + "_" + location.Width);
                return(bmp);
            }
Ejemplo n.º 3
0
        private IList <SizeL> GetLimitedLevelDimensions()
        {
            //Slide level dimensions scale factor in each axis
            float.TryParse(Osr.Properties[OpenSlide.PROPERTY_NAME_BOUNDS_WIDTH], out float scaledWidth);
            float.TryParse(Osr.Properties[OpenSlide.PROPERTY_NAME_BOUNDS_HEIGHT], out float scaledHeight);

            var level0Limits = Osr.LevelDimensions[0];

            scaledWidth  = scaledWidth / level0Limits.Width;
            scaledHeight = scaledHeight / level0Limits.Height;

            var sizeScale = new SizeF(scaledWidth, scaledHeight);

            // Dimensions of active area
            var levelDimensions = new List <SizeL>();

            foreach (var levelSize in Osr.LevelDimensions)
            {
                var newScaledWidth  = (long)Math.Ceiling((double)levelSize.Width * sizeScale.Width);
                var newScaledHeight = (long)Math.Ceiling((double)levelSize.Height * sizeScale.Height);
                var scaledLevelSize = new SizeL(newScaledWidth, newScaledHeight);
                levelDimensions.Add(scaledLevelSize);
            }
            return(levelDimensions);
        }
Ejemplo n.º 4
0
        public override Image GetThumbnail(SizeL maxSize)
        {
            var thumbSize = image.GetProportionateResize(maxSize.ToSize());
            var callback  = new Image.GetThumbnailImageAbort(ThumbnailCallback);
            var thumbnail = image.GetThumbnailImage(thumbSize.Width, thumbSize.Height,
                                                    callback, new IntPtr());

            return(thumbnail);
        }
Ejemplo n.º 5
0
            public MemoryStream GetTile(int level, long row, long col)
            {
                OpenSlide.TraceMsg("start gettile " + level + "/" + col + "_" + row);
                if (level < 0 || level >= max_dz_level)
                {
                    throw new ArgumentException($"wrong level level {level}, row {row}, col {col}");
                }
                if (t_dimensions[level].Width <= col || t_dimensions[level].Height <= row ||
                    0 > col || 0 > row)
                {
                    throw new ArgumentException($"wrong address level {level}, row {row}, col {col}");
                }
                var os_level = os_level_for_dz_level[level];
                //Calculate top/ left and bottom/ right overlap
                var z_overlap_tl = new SizeL(col == 0 ? 0 : 1,
                                             row == 0 ? 0 : 1);
                var z_overlap_br = new SizeL(col == t_dimensions[level].Width ? 0 : 1,
                                             row == t_dimensions[level].Height ? 0 : 1);

                var z_size = new SizeL(Math.Min(TILE_DOWNSAMPLE, z_dimensions[level].Width - TILE_DOWNSAMPLE * col) + z_overlap_tl.Width + z_overlap_br.Width,
                                       Math.Min(TILE_DOWNSAMPLE, z_dimensions[level].Height - TILE_DOWNSAMPLE * row) + z_overlap_tl.Height + z_overlap_br.Height);

                if (z_size.Width < 0 || z_size.Height < 0)
                {
                    throw new ArgumentException($"out of bounds level {level}, row {row}, col {col}");
                }
                var z_location = new SizeL(TILE_DOWNSAMPLE * col, TILE_DOWNSAMPLE * row);
                var l_location = new System.Drawing.SizeF((float)l_z_downsamples[level] * (z_location.Width - z_overlap_tl.Width),
                                                          (float)l_z_downsamples[level] * (z_location.Height - z_overlap_tl.Height));
                //Round location down and size up, and add offset of active area
                var l0_location = new SizeL((long)(downsamples[os_level] * l_location.Width),
                                            (long)(downsamples[os_level] * l_location.Height));
                var l_size = new SizeL((long)Math.Min(Math.Ceiling(l_z_downsamples[level] * z_size.Width), dimensions[os_level].Width),
                                       (long)Math.Min(Math.Ceiling(l_z_downsamples[level] * z_size.Height), dimensions[os_level].Height));

                OpenSlide.TraceMsg("calcs done " + level + "/" + col + "_" + row);
                var bmp = ReadRegion(l0_location, os_level, l_size);

                if (l_size.Width != z_size.Width || l_size.Height != z_size.Height)
                { //only resize when necessary
                    OpenSlide.TraceMsg("resize " + level + "/" + col + "_" + row);
                    var oldbmp = bmp;
                    bmp = new SKBitmap((int)z_size.Width, (int)z_size.Height);
                    oldbmp.Resize(bmp, SKBitmapResizeMethod.Box);
                }
                OpenSlide.TraceMsg("new bmp " + level + "/" + col + "_" + row);
                var stream = new MemoryStream();

                //Prints tile coords for testing
                //var g = Graphics.FromImage(resizedbmp);
                //g.DrawString(level + "/" + col + "_" + row, new Font(FontFamily.GenericSansSerif, 18), new SolidBrush(Color.Black), resizedbmp.Width / 2, resizedbmp.Height / 2);
                bmp.Encode(new SKManagedWStream(stream), SKEncodedImageFormat.Jpeg, 80);
                OpenSlide.TraceMsg("end gettile " + level + "/" + col + "_" + row);
                stream.Position = 0;
                return(stream);
            }
Ejemplo n.º 6
0
            private void InitZDimensions()
            {
                ///size on a current dz_level
                var z_size = dimensions[0];

                z_dimensions.Add(z_size);
                while (z_size.Width > 1 || z_size.Height > 1)
                {
                    z_size = new SizeL((long)Math.Max(1, Math.Ceiling(z_size.Width / 2.0)),
                                       (long)Math.Max(1, Math.Ceiling(z_size.Height / 2.0)));
                    z_dimensions.Add(z_size);
                }
                z_dimensions.Reverse();
            }
Ejemplo n.º 7
0
        private void CheckParameters(int level, SizeL adress)
        {
            var col = adress.Width;
            var row = adress.Height;

            if (level < 0 || level >= LevelCount)
            {
                throw new ArgumentException($"wrong level level {level}, row {row}, col {col}");
            }

            if (TileDimensions[level].Width <= col || TileDimensions[level].Height <= row ||
                0 > col || 0 > row)
            {
                throw new ArgumentException($"wrong address level {level}, row {row}, col {col}");
            }
        }
Ejemplo n.º 8
0
 public Header(MetafileReader reader)
 {
     Bounds                         = new RectL(reader);
     Frame                          = new RectL(reader);
     Signature                      = reader.ReadUInt32();
     Version                        = reader.ReadUInt32();
     NumberOfBytes                  = reader.ReadUInt32();
     NumberOfRecords                = reader.ReadUInt32();
     NumberOfObjects                = reader.ReadUInt16();
     Reserved                       = reader.ReadUInt16();
     DescriptionLength              = reader.ReadUInt32();
     DescriptionOffset              = reader.ReadUInt32();
     NumberOfPaletteEntries         = reader.ReadUInt32();
     ReferenceDeviceSizePixels      = new SizeL(reader);
     ReferenceDeviceSizeMillimeters = new SizeL(reader);
 }
Ejemplo n.º 9
0
        private IList <SizeL> GetDeepZoomLevels()
        {
            var deepZoomSize      = Level0Dimensions;
            var dzLevelDimensions = new List <SizeL> {
                deepZoomSize
            };

            while (deepZoomSize.Width > 1 || deepZoomSize.Height > 1)
            {
                var width  = (long)Math.Max(1, Math.Ceiling(deepZoomSize.Width / 2.0));
                var height = (long)Math.Max(1, Math.Ceiling(deepZoomSize.Height / 2.0));

                deepZoomSize = new SizeL(width, height);
                dzLevelDimensions.Add(deepZoomSize);
            }
            dzLevelDimensions.Reverse();
            return(dzLevelDimensions);
        }
Ejemplo n.º 10
0
        /*Returns an image containing the contents of the region.
         *              location: (x, y) tuple giving the top left pixel in the level 0 reference frame.
         *              level:    the level number.
         *              maxSize:     (width, height) tuple giving the region maxSize.*/
        public override Image ReadRegion(SizeL location, int level, SizeL size)
        {
            if (image == null)
            {
                throw new ArgumentNullException();
            }
            if (level != 0)
            {
                throw new OpenSlideException("Invalid level");
            }
            if (size.Width < 0 || size.Height < 0)
            {
                throw new OpenSlideException($"Size {size} must be non-negative");
            }

            /*	Any corner of the requested region may be outside the bounds of
             *                  the image. Create a transparent tile of the correct maxSize and
             *                  paste the valid part of the region into the correct location.*/
            var imageTopLeft = new SizeL(Math.Max(0, Math.Min(location.Width, Dimensions.Width)),
                                         Math.Max(0, Math.Min(location.Height, Dimensions.Height)));
            var imageBottomRight = new SizeL(Math.Max(0, Math.Min(location.Width + size.Width - 1, Dimensions.Width - 1)),
                                             Math.Max(0, Math.Min(location.Height + size.Height - 1, Dimensions.Height - 1)));

            var tile = new Bitmap((int)size.Width, (int)size.Height);

            // Crop maxSize is greater than zero in both dimensions.
            if (imageBottomRight.Width - imageTopLeft.Width < 0 &&
                imageBottomRight.Height - imageTopLeft.Height < 0)
            {
                return(tile);
            }

            var crop = new Rectangle((int)imageTopLeft.Width, (int)imageTopLeft.Height,
                                     (int)(imageTopLeft.Width + imageBottomRight.Width + 1),
                                     (int)(imageTopLeft.Height + imageBottomRight.Height + 1));

            var g = Graphics.FromImage(tile);

            g.DrawImage(image, 0, 0, crop, GraphicsUnit.Pixel);
            return(tile);
        }
Ejemplo n.º 11
0
        static void Main(string[] args)
        {
            string filename  = "CMU-1-Small-Region";
            var    openSlide = new OpenSlide();

            //var test = openSlide.GetMPP("CMU-1-Small-Region.svs"); //MPP = microns per pixel


            SizeL[] levels = openSlide.Levels($"{filename}.svs");

            List <SizeL> dimensions = openSlide.Dimensions($"{filename}.svs");

            SizeL maxDimensions = dimensions[dimensions.Count - 1];


            //Loads DZI file
            GetDZI(openSlide, maxDimensions.Width, maxDimensions.Height, $"{filename}.svs", filename);

            for (int level = 0; level < levels.Length; level++)
            {
                Directory.CreateDirectory($"{filename}_files/{level}");

                SizeL levelInfo = levels[level];

                for (int row = 0; row < levelInfo.Width; row++)
                {
                    for (int col = 0; col < levelInfo.Height; col++)
                    {
                        GetJpg(openSlide, level, row, col, $"{filename}.svs", $"{filename}_files/{level}/{row}_{col}");
                    }
                }
            }

            Console.WriteLine("Done");
            Console.ReadLine();
        }
Ejemplo n.º 12
0
 public Image GetThumbnail(SizeL size)
 {
     return(GetThumbnail(size.ToSize()));
 }
Ejemplo n.º 13
0
 public abstract Image GetThumbnail(SizeL maxSize);
Ejemplo n.º 14
0
 /*Returns an Image containing the contents of the region.
  * location: (x, y) tuple giving the top left pixel in the level 0 reference frame.
  * level:    the level number.
  * maxSize:     (width, height) tuple giving the region maxSize.*/
 public abstract Image ReadRegion(SizeL location, int level, SizeL size);
Ejemplo n.º 15
0
        public Image GetTile(int level, SizeL address)
        {
            // Read tile
            CheckParameters(level, address);
            var col = address.Width;
            var row = address.Height;

            // Get preferred slide level
            var preferedSlideLevel = BestSlideLevelForDeepZoomLevel[level];

            // Calculate top left and bottom right overlap
            var topLeftOverlap = new SizeL(col == 0 ? 0 : DeepZoomOverlap,
                                           row == 0 ? 0 : DeepZoomOverlap);

            var bottomRightOverlap = new SizeL(col == TileDimensions[level].Width - 1 ? 0 : DeepZoomOverlap,
                                               row == TileDimensions[level].Height - 1 ? 0 : DeepZoomOverlap);

            // Get final size of the tile
            var finalTileWidth = Math.Min(TileSize, DeepZoomLevelDimensions[level].Width - TileSize * col) +
                                 topLeftOverlap.Width + bottomRightOverlap.Width;
            var finalTileHeight = Math.Min(TileSize, DeepZoomLevelDimensions[level].Height - TileSize * row) +
                                  topLeftOverlap.Height + bottomRightOverlap.Height;
            var finalTileSize = new SizeL(finalTileWidth, finalTileHeight);

            if (finalTileSize.Width < 0 || finalTileSize.Height < 0)
            {
                throw new ArgumentException($"out of bounds level {level}, row {row}, col {col}");
            }

            // Obtain the region coordinates
            var deepZoomLocation = new SizeL(TileSize * col, TileSize * row);

            var levelLocation = new SizeF(
                (float)DeepZoomLevelDownsamples[level] * (deepZoomLocation.Width - topLeftOverlap.Width),
                (float)DeepZoomLevelDownsamples[level] * (deepZoomLocation.Height - topLeftOverlap.Height));

            // Round location down and size up, and add offset of active area
            var level0Location = new SizeL(
                (long)(Osr.LevelDownsamples[preferedSlideLevel] * levelLocation.Width + Level0Offset.Width),
                (long)(Osr.LevelDownsamples[preferedSlideLevel] * levelLocation.Height + Level0Offset.Height));

            var regionWidth = (long)Math.Min(Math.Ceiling(DeepZoomLevelDownsamples[level] * finalTileSize.Width),
                                             LevelDimensions[preferedSlideLevel].Width - Math.Ceiling(levelLocation.Width));
            var regionHeight = (long)Math.Min(Math.Ceiling(DeepZoomLevelDownsamples[level] * finalTileSize.Height),
                                              LevelDimensions[preferedSlideLevel].Height - Math.Ceiling(levelLocation.Height));
            var regionSize = new SizeL(regionWidth, regionHeight);

            var tileBmp = Osr.ReadRegion(level0Location, preferedSlideLevel, regionSize);

            //Apply on background color (composite)
            tileBmp = ApplyOnBackgroundColor(tileBmp);

            // Scale to the correct size
            var deepZoomSize = finalTileSize;

            if (regionSize.Width == deepZoomSize.Width &&
                regionSize.Height == deepZoomSize.Height)
            {
                return(tileBmp);
            }

            tileBmp = new Bitmap(tileBmp, deepZoomSize.ToSize());
            return(tileBmp);
        }