예제 #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);
            }
예제 #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);
            }
예제 #3
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);
            }
예제 #4
0
        public MemoryStream GetJpg(string filename, string path)
        {
            //url = '/<ID>_files/<int:level>/<int:col>_<int:row>.<format>'
            OpenSlide.TraceMsg("start getjpg " + path);
            var m = rxDZ.Match(path);

            if (m.Success)
            {
                var ost = GetOpenSlide(filename);
                OpenSlide.TraceMsg("open os " + path);
                var level = Int32.Parse(m.Groups[1].Value);
                var col   = Int64.Parse(m.Groups[2].Value);
                var row   = Int64.Parse(m.Groups[3].Value);
                var ret   = ost.GetTile(level, row, col);
                OpenSlide.TraceMsg("end getjpg " + path);
                return(ret);
            }
            return(null);
        }
예제 #5
0
            public Openslide(string filename)
            {
                OpenSlide.TraceMsg("start openslide " + filename);
                origfile = filename;
                if (!File.Exists(filename))
                {
                    throw new ArgumentException($"File '{filename}' can't be opened");
                }
                handle = openslide_open(filename);
                unsafe
                {
                    if (handle == null || handle[0] == 0)
                    {
                        var vendor = openslide_detect_vendor(filename);
                        //GetLastError();
                        if (vendor.ToInt32() != 0)
                        {
                            throw new ArgumentException("Vendor " + Marshal.PtrToStringAnsi(vendor) + " unsupported?");
                        }
                        else
                        {
                            throw new ArgumentException("File unrecognized");
                        }
                    }
                }
                OpenSlide.TraceMsg("opened openslide " + filename);
                max_os_level = openslide_get_level_count(handle);
                if (max_os_level == -1)
                {
                    GetLastError();
                }
                for (int level = 0; level < max_os_level; level++)
                {
                    long w = 0, h = 0;
                    openslide_get_level_dimensions(handle, level, out w, out h);
                    if (w == -1 || h == -1)
                    {
                        GetLastError();
                    }
                    dimensions.Add(new SizeL(w, h));
                    var downsample = openslide_get_level_downsample(handle, level);
                    if (downsample == -1.0)
                    {
                        GetLastError();
                    }
                    downsamples.Add(downsample);
                }
                InitZDimensions();
                t_dimensions = z_dimensions.Select(x => new SizeL((long)Math.Ceiling(x.Width / (double)TILE_DOWNSAMPLE),
                                                                  (long)Math.Ceiling(x.Height / (double)TILE_DOWNSAMPLE))).ToArray();

                max_dz_level          = z_dimensions.Count;
                l0_z_downsamples      = Enumerable.Range(0, max_dz_level).Select(x => (int)Math.Pow(2, max_dz_level - x - 1)).ToArray();
                os_level_for_dz_level = l0_z_downsamples.Select(x =>
                {
                    var best_level = openslide_get_best_level_for_downsample(handle, x * 1.01);
                    if (best_level == -1)
                    {
                        GetLastError();
                    }
                    return(best_level);
                }).ToArray();
                l_z_downsamples = Enumerable.Range(0, max_dz_level).Select(l => l0_z_downsamples[l] / downsamples[os_level_for_dz_level[l]]).ToArray();
                InitEasyLevels();
                OpenSlide.TraceMsg("end openslide " + filename);
            }