private static Image <Bgra32> GenerateThumbnail(OpenSlideImage image, int maxWidth, int maxHeight) { if (image == null) { throw new ArgumentNullException(nameof(image)); } (long width, long height) = image.Dimensions; // 决定合适的level double downsampleWidth = width / (double)maxWidth; double downsampleHeight = height / (double)maxHeight; double downsample = Math.Max(downsampleWidth, downsampleHeight); int level = image.GetBestLevelForDownsample(downsample); (long levelWidth, long levelHeight) = image.GetLevelDimensions(level); // 计算目标大小 int targetWidth, targetHeight; if (downsampleWidth > downsampleHeight) { // width缩小较大,将maxWidth作为标准 targetWidth = maxWidth; targetHeight = (int)(height / downsampleWidth); } else { // height缩小较大,将maxHeight作为标准 targetWidth = (int)(width / downsampleHeight); targetHeight = maxHeight; } Image <Bgra32> output; checked { output = new Image <Bgra32>((int)levelWidth, (int)levelHeight); } output.Mutate(ctx => { ctx.Apply(img => { var frame = img.Frames.RootFrame; image.DangerousReadRegion( level, 0, 0, levelWidth, levelHeight, ref Unsafe.As <Bgra32, byte>(ref frame.DangerousGetPinnableReferenceToPixelBuffer())); }); ctx.Resize(targetWidth, targetHeight); }); return(output); }
/// <summary> /// Initialize a <see cref="DeepZoomGenerator"/> instance with the specified parameters. /// </summary> /// <param name="image">The OpenSlide image.</param> /// <param name="tileSize">The tile size paramter.</param> /// <param name="overlap">The overlap paramter.</param> /// <param name="limitBounds">Whether image bounds should be respected.</param> /// <param name="disposeImage">Whether the OpenSlide image instance should be disposed when this <see cref="DeepZoomGenerator"/> instance is disposed.</param> public DeepZoomGenerator(OpenSlideImage image, int tileSize = 254, int overlap = 1, bool limitBounds = true, bool disposeImage = false) { _image = image ?? throw new ArgumentNullException(nameof(image)); _disposeImage = disposeImage; long width, height; if (limitBounds) { _boundX = image.BoundsX ?? 0; _boundY = image.BoundsY ?? 0; _width = width = image.BoundsWidth ?? image.Width; _height = height = image.BoundsHeight ?? image.Height; } else { _boundX = 0; _boundY = 0; _width = width = image.Width; _height = height = image.Height; } DeepZoomLayer[] dzLayers = DeepZoomHelper.CalculateDeepZoomLayers(width, height); DeepZoomLayerInformation[] layers = new DeepZoomLayerInformation[dzLayers.Length]; for (int i = 0; i < layers.Length; i++) { DeepZoomLayer dzLayer = dzLayers[i]; int layerDownsample = 1 << (dzLayers.Length - i - 1); int level = image.GetBestLevelForDownsample(layerDownsample); (long levelWidth, long levelHeight) = image.GetLevelDimensions(level); layers[i] = new DeepZoomLayerInformation { Level = level, LevelDownsample = image.GetLevelDownsample(level), LevelWidth = levelWidth, LevelHeight = levelHeight, LayerDownsample = layerDownsample, LayerWidth = dzLayer.Width, LayerHeight = dzLayer.Height }; } _layers = layers; _tileSize = tileSize; _overlap = overlap; }
private static Image <Bgra32> GenerateThumbnail(OpenSlideImage image, int maxWidth, int maxHeight) { if (image == null) { throw new ArgumentNullException(nameof(image)); } (long width, long height) = image.Dimensions; // Find the appropriate level double downsampleWidth = width / (double)maxWidth; double downsampleHeight = height / (double)maxHeight; double downsample = Math.Max(downsampleWidth, downsampleHeight); int level = image.GetBestLevelForDownsample(downsample); (long levelWidth, long levelHeight) = image.GetLevelDimensions(level); // Calculate target size int targetWidth, targetHeight; if (downsampleWidth > downsampleHeight) { targetWidth = maxWidth; targetHeight = (int)(height / downsampleWidth); } else { targetWidth = (int)(width / downsampleHeight); targetHeight = maxHeight; } using Bgra32ImageBuffer buffer = image.ReadImageBuffer(level, 0, 0, levelWidth, levelHeight); return(buffer.GetImage().Clone(ctx => { ctx.Resize(targetWidth, targetHeight); })); }