/// <summary> /// Computes the maximum bounds for scales on a given <see cref="IPresentationImage"/>. /// </summary> /// <param name="presentationImage">The image to compute bounds for.</param> /// <param name="horizontalReduction">The percentage of width to subtract from both the client bounds and the source image bounds.</param> /// <param name="verticalReduction">The percentage of height to subtract from both the client bounds and the source image bounds.</param> /// <returns>The maximum scale bounds.</returns> private static Rectangle ComputeScaleBounds(IPresentationImage presentationImage, float horizontalReduction, float verticalReduction) { RectangleF clientBounds = presentationImage.ClientRectangle; float hReduction = horizontalReduction * Math.Min(1000f, clientBounds.Width); float vReduction = verticalReduction * Math.Min(1000f, clientBounds.Height); clientBounds = new RectangleF(clientBounds.X + hReduction, clientBounds.Y + vReduction, clientBounds.Width - 2 * hReduction, clientBounds.Height - 2 * vReduction); if (presentationImage is IImageGraphicProvider) { ImageGraphic imageGraphic = ((IImageGraphicProvider)presentationImage).ImageGraphic; Rectangle srcRectangle = new Rectangle(0, 0, imageGraphic.Columns, imageGraphic.Rows); RectangleF imageBounds = imageGraphic.SpatialTransform.ConvertToDestination(srcRectangle); imageBounds = RectangleUtilities.ConvertToPositiveRectangle(imageBounds); hReduction = horizontalReduction * imageBounds.Width; vReduction = verticalReduction * imageBounds.Height; imageBounds = new RectangleF(imageBounds.X + hReduction, imageBounds.Y + vReduction, imageBounds.Width - 2 * hReduction, imageBounds.Height - 2 * vReduction); return(Rectangle.Round(RectangleUtilities.Intersect(imageBounds, clientBounds))); } else { return(Rectangle.Round(clientBounds)); } }
//internal for unit testing only. internal static void CalculateVisibleRectangles( ImageGraphic imageGraphic, Rectangle clientRectangle, out Rectangle dstVisibleRectangle, out RectangleF srcVisibleRectangle) { Rectangle srcRectangle = new Rectangle(0, 0, imageGraphic.Columns, imageGraphic.Rows); RectangleF dstRectangle = imageGraphic.SpatialTransform.ConvertToDestination(srcRectangle); // Find the intersection between the drawable client rectangle and // the transformed destination rectangle dstRectangle = RectangleUtilities.RoundInflate(dstRectangle); dstRectangle = RectangleUtilities.Intersect(clientRectangle, dstRectangle); if (dstRectangle.IsEmpty) { dstVisibleRectangle = Rectangle.Empty; srcVisibleRectangle = RectangleF.Empty; return; } // Figure out what portion of the image is visible in source coordinates srcVisibleRectangle = imageGraphic.SpatialTransform.ConvertToSource(dstRectangle); //dstRectangle is already rounded, this is just a conversion to Rectangle. dstVisibleRectangle = Rectangle.Round(dstRectangle); }
public void NoIntersection() { RectangleF rect1 = new RectangleF(0, 0, 10, 10); RectangleF rect2 = new RectangleF(-20, 0, 10, 10); RectangleF intersectRect = RectangleUtilities.Intersect(rect1, rect2); Assert.IsTrue(intersectRect.IsEmpty); }
public void IntersectOn2Sides() { RectangleF rect1 = new RectangleF(0, 0, 10, 10); RectangleF rect2 = new RectangleF(-2, -2, 5, 5); RectangleF intersectRect = RectangleUtilities.Intersect(rect1, rect2); Assert.AreEqual(new RectangleF(0, 0, 3, 3), intersectRect); }
public void Containment() { RectangleF rect1 = new RectangleF(0, 0, 10, 10); RectangleF rect2 = new RectangleF(2, 2, 5, 5); RectangleF intersectRect = RectangleUtilities.Intersect(rect1, rect2); Assert.AreEqual(rect2, intersectRect); }
protected void SerializeDisplayedArea(DisplayedAreaModuleIod displayedAreaModule, DicomPresentationImageCollection <T> images) { displayedAreaModule.InitializeAttributes(); List <DisplayedAreaModuleIod.DisplayedAreaSelectionSequenceItem> displayedAreas = new List <DisplayedAreaModuleIod.DisplayedAreaSelectionSequenceItem>(); foreach (T image in images) { DisplayedAreaModuleIod.DisplayedAreaSelectionSequenceItem displayedArea = new DisplayedAreaModuleIod.DisplayedAreaSelectionSequenceItem(); displayedArea.InitializeAttributes(); displayedArea.ReferencedImageSequence = new[] { CreateImageSopInstanceReference(image.Frame) }; ImageGraphic imageGraphic = ((IImageGraphicProvider)image).ImageGraphic; Size imageSize = new Size(imageGraphic.Columns, imageGraphic.Rows); // compute the visible area of the image as a rectangle oriented positively in screen space RectangleF visibleImageArea = imageGraphic.SpatialTransform.ConvertToSource(image.ClientRectangle); visibleImageArea = RectangleUtilities.ConvertToPositiveRectangle(visibleImageArea); visibleImageArea = RectangleUtilities.RoundInflate(visibleImageArea); visibleImageArea = RectangleUtilities.Intersect(visibleImageArea, new Rectangle(new Point(0, 0), imageSize)); // compute the pixel addresses of the visible area by intersecting area with actual pixel addresses available Rectangle visiblePixels = ConvertToPixelAddressRectangle(Rectangle.Truncate(visibleImageArea)); displayedArea.DisplayedAreaTopLeftHandCorner = visiblePixels.Location; displayedArea.DisplayedAreaBottomRightHandCorner = visiblePixels.Location + visiblePixels.Size; ISpatialTransform spatialTransform = image.SpatialTransform; switch (_displayAreaSerializationOption) { case DisplayAreaSerializationOption.SerializeAsMagnification: displayedArea.PresentationSizeMode = DisplayedAreaModuleIod.PresentationSizeMode.Magnify; displayedArea.PresentationPixelMagnificationRatio = spatialTransform.Scale; break; case DisplayAreaSerializationOption.SerializeAsTrueSize: displayedArea.PresentationSizeMode = DisplayedAreaModuleIod.PresentationSizeMode.TrueSize; displayedArea.PresentationPixelSpacing = image.Frame.NormalizedPixelSpacing; break; case DisplayAreaSerializationOption.SerializeAsDisplayedArea: default: displayedArea.PresentationSizeMode = DisplayedAreaModuleIod.PresentationSizeMode.ScaleToFit; break; } displayedArea.PresentationPixelAspectRatio = PixelAspectRatio.FromString(image.Frame.NormalizedPixelSpacing.GetPixelAspectRatioString()); displayedAreas.Add(displayedArea); } displayedAreaModule.DisplayedAreaSelectionSequence = displayedAreas.ToArray(); }
private void CalculateReferenceDisplayValues() { ImageSpatialTransform transform = GetImageTransform(ReferenceImage); Frame frame = GetFrame(ReferenceImage); //calculate the width (in mm) of the portion of the image that is visible on the display, //as well as the display rectangle it occupies. RectangleF sourceRectangle = new RectangleF(0, 0, frame.Columns, frame.Rows); _referenceDisplayRectangle = transform.ConvertToDestination(sourceRectangle); _referenceDisplayRectangle = RectangleUtilities.Intersect(_referenceDisplayRectangle, ReferenceImage.ClientRectangle); _referenceDisplayedWidth = GetDisplayedWidth(ReferenceImage, _referenceDisplayRectangle); }
public void IntersectOn1Side() { RectangleF rect1 = new RectangleF(2, -2, 5, 5); RectangleF rect2 = new RectangleF(0, 0, 10, 10); RectangleF intersectRect = RectangleUtilities.Intersect(rect1, rect2); Assert.AreEqual(new RectangleF(2, 0, 5, 3), intersectRect); rect1 = new RectangleF(0, 0, -10, 10); rect2 = new RectangleF(-8, -2, 5, 5); intersectRect = RectangleUtilities.Intersect(rect1, rect2); Assert.AreEqual(new RectangleF(-3, 0, -5, 3), intersectRect); rect1 = new RectangleF(0, 0, -10, 10); rect2 = new RectangleF(-3, -2, -5, 5); intersectRect = RectangleUtilities.Intersect(rect1, rect2); Assert.AreEqual(new RectangleF(-3, 0, -5, 3), intersectRect); }
public override string GetAnnotationText(IPresentationImage presentationImage) { if (presentationImage == null) { return(String.Empty); } IImageSopProvider imageSopProvider = presentationImage as IImageSopProvider; if (imageSopProvider == null) { return(String.Empty); } ISpatialTransformProvider spatialTransformProvider = presentationImage as ISpatialTransformProvider; if (spatialTransformProvider == null) { return(String.Empty); } ImageSpatialTransform transform = spatialTransformProvider.SpatialTransform as ImageSpatialTransform; if (transform == null) { return(String.Empty); } if (transform.RotationXY % 90 != 0) { return(SR.ValueNotApplicable); } Frame frame = imageSopProvider.Frame; PixelSpacing normalizedPixelSpacing = frame.NormalizedPixelSpacing; if (normalizedPixelSpacing.IsNull) { return(String.Empty); } RectangleF sourceRectangle = new RectangleF(0, 0, frame.Columns, frame.Rows); RectangleF destinationRectangle = transform.ConvertToDestination(sourceRectangle); destinationRectangle = RectangleUtilities.Intersect(destinationRectangle, presentationImage.ClientRectangle); //Convert the displayed width and height to source dimensions SizeF widthInSource = transform.ConvertToSource(new SizeF(destinationRectangle.Width, 0)); SizeF heightInSource = transform.ConvertToSource(new SizeF(0, destinationRectangle.Height)); //The displayed FOV is given by the magnitude of each line in source coordinates, but //for each of the 2 lines, one of x or y will be zero, so we can optimize. float x1 = Math.Abs(widthInSource.Width); float y1 = Math.Abs(widthInSource.Height); float x2 = Math.Abs(heightInSource.Width); float y2 = Math.Abs(heightInSource.Height); double displayedFieldOfViewX, displayedFieldOfViewY; if (x1 > y1) //the image is not rotated { displayedFieldOfViewX = x1 * normalizedPixelSpacing.Column / 10; displayedFieldOfViewY = y2 * normalizedPixelSpacing.Row / 10; } else //the image is rotated by 90 or 270 degrees { displayedFieldOfViewX = x2 * normalizedPixelSpacing.Column / 10; displayedFieldOfViewY = y1 * normalizedPixelSpacing.Row / 10; } return(String.Format(SR.FormatCentimeters, String.Format(SR.Format2Dimensions, displayedFieldOfViewX.ToString("F1"), displayedFieldOfViewY.ToString("F1")))); }