public void FlipXY()
        {
            ImageSpatialTransform transform = CreateTransform();

            transform.FlipX = true;
            transform.FlipY = true;

            Assert.AreEqual(-1.0f, transform.Transform.Elements[0]);
            Assert.AreEqual(0.0f, transform.Transform.Elements[1]);
            Assert.AreEqual(0.0f, transform.Transform.Elements[2]);
            Assert.AreEqual(-1.0f, transform.Transform.Elements[3]);
            Assert.AreEqual(transform.Scale, 1.0f);
            Assert.AreEqual(transform.ScaleX, 1.0f);
            Assert.AreEqual(transform.ScaleY, 1.0f);
        }
예제 #2
0
        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 DestinationToSourceRoundtrip()
        {
            // be sure to covert back and forth
            CompositeImageGraphic graphic   = new CompositeImageGraphic(3062, 3732);
            ImageSpatialTransform transform = (ImageSpatialTransform)graphic.SpatialTransform;

            transform.ClientRectangle = new Rectangle(6, 6, 493, 626);

            PointF dstPt1 = new Point(100, 200);
            PointF srcPt  = transform.ConvertToSource(dstPt1);

            PointF dstPt2 = transform.ConvertToDestination(srcPt);

            Assert.IsTrue(FloatComparer.AreEqual(dstPt1, dstPt2));
        }
예제 #4
0
        public static Bitmap CreatePresentationImageIcon(IPresentationImage image, double tileRatio)
        {
            ISpatialTransformProvider provider = image as ISpatialTransformProvider;

            if (provider == null)
            {
                throw new Exception(SR.ConvertTransformProviderFailed);
            }
            ImageSpatialTransform spatialTransform = provider.SpatialTransform as ImageSpatialTransform;
            object memento = spatialTransform.CreateMemento();
            Size   size    = CalculateSize(image.ClientRectangle.Size, tileRatio);
            Bitmap bitmap  = new Bitmap(image.DrawToBitmap(size.Width, size.Height), _iconWidth, Convert.ToInt32((float)(_iconWidth * Convert.ToSingle(tileRatio))));

            spatialTransform.SetMemento(memento);
            return(bitmap);
        }
예제 #5
0
        private static float GetDisplayedWidth(IPresentationImage presentationImage, RectangleF referenceDisplayedRectangle)
        {
            ImageSpatialTransform transform = GetImageTransform(presentationImage);
            Frame frame = GetFrame(presentationImage);

            //Convert the displayed width to source dimensions
            SizeF sourceSize = transform.ConvertToSource(new SizeF(referenceDisplayedRectangle.Width, 0));
            float x          = Math.Abs(sourceSize.Width);
            float y          = Math.Abs(sourceSize.Height);

            //The displayed width is the magnitude of the line in source coordinates,
            //but one of xLength or yLength will always be zero, so we can optimize.
            if (x > y)
            {
                return(x * (float)frame.NormalizedPixelSpacing.Column);
            }

            return(y * (float)frame.NormalizedPixelSpacing.Row);
        }
        private void CreateImageLayer(ImageTypes imageType)
        {
            if (imageType == ImageTypes.Mono16)
            {
                _image = new GrayscaleImageGraphic(_srcHeight, _srcWidth, 16, 16, 15, false, false, 1.9, 3, new byte[2 * _srcWidth * _srcHeight]);
            }
            else if (imageType == ImageTypes.Mono8)
            {
                _image = new GrayscaleImageGraphic(_srcHeight, _srcWidth, 8, 8, 7, false, false, 1.0, 0, new byte[_srcWidth * _srcHeight]);
            }
            if (imageType == ImageTypes.Mono16Signed)
            {
                _image = new GrayscaleImageGraphic(_srcHeight, _srcWidth, 16, 16, 15, true, false, 2.0, -630, new byte[2 * _srcWidth * _srcHeight]);
            }
            else if (imageType == ImageTypes.Mono8Signed)
            {
                _image = new GrayscaleImageGraphic(_srcHeight, _srcWidth, 8, 8, 7, true, false, 0.5, 4, new byte[_srcWidth * _srcHeight]);
            }
            else
            {
                _image = new ColorImageGraphic(_srcHeight, _srcWidth, new byte[4 * _srcWidth * _srcHeight]);
            }

            if (_image is GrayscaleImageGraphic)
            {
                (_image as IColorMapInstaller).InstallColorMap(new GrayscaleColorMap());
            }

            _containerGraphic = new CompositeImageGraphic(_image.Rows, _image.Columns);
            _containerGraphic.Graphics.Add(_image);

            ImageSpatialTransform transform = (ImageSpatialTransform)_containerGraphic.SpatialTransform;

            transform.Initialize();
            transform.ClientRectangle = new Rectangle(0, 0, _dstWidth, _dstHeight);
            transform.ScaleToFit      = _scaleToFit;
            transform.Scale           = _scale;
            transform.FlipX           = _flipHorizontal;
            transform.FlipY           = _flipVertical;
            transform.RotationXY      = _rotation;
            transform.TranslationX    = _translationX;
            transform.TranslationY    = _translationY;
        }
예제 #7
0
        private static CompositeGraphic CreateTestSceneGraph()
        {
            CompositeGraphic      sceneGraph     = new CompositeGraphic();
            ImageSpatialTransform imageTransform = CreateTransform();

            sceneGraph.Graphics.Add(imageTransform.OwnerGraphic);

            CompositeGraphic composite = new CompositeGraphic();
            Graphic          leaf      = new LinePrimitive();

            composite.Graphics.Add(leaf);
            ((CompositeImageGraphic)imageTransform.OwnerGraphic).Graphics.Add(composite);

            RoiGraphic roiGraphic = new RoiGraphic(new EllipsePrimitive());

            ((CompositeImageGraphic)imageTransform.OwnerGraphic).Graphics.Add(roiGraphic);

            return(sceneGraph);
        }
예제 #8
0
        private static Bitmap DrawWysiwygImageToBitmap(IPresentationImage image, Rectangle displayRectangle, float scale, float dpi)
        {
            ImageSpatialTransform transform = (ImageSpatialTransform)((ISpatialTransformProvider)image).SpatialTransform;
            object restoreMemento           = transform.CreateMemento();

            try
            {
                int width  = (int)(displayRectangle.Width * scale);
                int height = (int)(displayRectangle.Height * scale);

                transform.Scale *= scale;

                return(ImageDrawToBitmap(image, width, height, dpi));
            }
            finally
            {
                transform.SetMemento(restoreMemento);
            }
        }
예제 #9
0
        public static Bitmap CreatePresentationImagePrintData(IPresentationImage image, RectangleF destRange, double tileRatio, float scale, bool withAnnotation)
        {
            ISpatialTransformProvider provider = image as ISpatialTransformProvider;

            if (provider == null)
            {
                Platform.Log(LogLevel.Error, "RectangleF 转换失败");
                throw new Exception("转换失败");
            }
            ImageSpatialTransform spatialTransform = provider.SpatialTransform as ImageSpatialTransform;
            object memento = spatialTransform.CreateMemento();
            float  num     = scale / spatialTransform.Scale;

            spatialTransform.MoveTo(destRange, scale);
            Size   destSize = new Size(Convert.ToInt32((float)(destRange.Width * num)), Convert.ToInt32((float)(destRange.Height * num)));
            Bitmap bitmap   = DrawToFilmSizeBitmap(destSize, image, tileRatio, withAnnotation);

            spatialTransform.SetMemento(memento);
            return(bitmap);
        }
예제 #10
0
        public void Rotate2()
        {
            ImageSpatialTransform transform = CreateTransform();

            transform.ScaleToFit = false;

            transform.RotationXY = 0;
            Assert.AreEqual(0, transform.RotationXY);
            transform.RotationXY = 90;
            Assert.AreEqual(90, transform.RotationXY);
            transform.RotationXY = 360;
            Assert.AreEqual(0, transform.RotationXY);
            transform.RotationXY = 450;
            Assert.AreEqual(90, transform.RotationXY);
            transform.RotationXY = -90;
            Assert.AreEqual(270, transform.RotationXY);
            transform.RotationXY = -270;
            Assert.AreEqual(90, transform.RotationXY);
            transform.RotationXY = -450;
            Assert.AreEqual(270, transform.RotationXY);
        }
예제 #11
0
        public void Apply(IPresentationImage image)
        {
            if (image == ReferenceImage)
            {
                return;
            }

            //Turn off scale to fit and start with scale=1, then adjust it.
            //We do this because images that have been "scaled to fit", but have not been shown yet,
            //have no client rectangle and their scale is often very small.  This is safer
            //and could produce a more accurate result.
            ImageSpatialTransform matchTransform = GetImageTransform(image);

            matchTransform.ScaleToFit = false;
            matchTransform.Scale      = 1;

            //get the displayed width (in mm) for the same size display rectangle in the image to be matched.
            float matchDisplayedWidth = GetDisplayedWidth(image, _referenceDisplayRectangle);
            float rescaleAmount       = matchDisplayedWidth / _referenceDisplayedWidth;

            matchTransform.Scale *= rescaleAmount;
        }
예제 #12
0
        public static Bitmap CreatePresentationImageIcon(IPresentationImage image, RectangleF destRange, double tileRatio)
        {
            if (destRange == RectangleF.Empty)
            {
                return(null);
            }
            ISpatialTransformProvider provider = image as ISpatialTransformProvider;

            if (provider == null)
            {
                throw new Exception(SR.ConvertTransformProviderFailed);
            }
            ImageSpatialTransform spatialTransform = provider.SpatialTransform as ImageSpatialTransform;
            object memento = spatialTransform.CreateMemento();

            spatialTransform.MoveTo(destRange);
            Size   destSize = new Size(Convert.ToInt32(destRange.Width), Convert.ToInt32(destRange.Height));
            Bitmap original = DrawToFilmSizeBitmap(destSize, image, tileRatio, true);
            Bitmap bitmap2  = new Bitmap(original, _iconWidth, (int)(_iconWidth * tileRatio));

            original.Dispose();
            spatialTransform.SetMemento(memento);
            return(bitmap2);
        }
예제 #13
0
        public void CumulativeTransform()
        {
            //this will cause a non-1:1 scale in y
            CompositeImageGraphic composite = new CompositeImageGraphic(512, 384, 0, 0, 3, 4);
            ImageSpatialTransform transform = (ImageSpatialTransform)composite.SpatialTransform;

            transform.ClientRectangle = new Rectangle(0, 0, 384, 512);
            transform.ScaleToFit      = false;
            transform.Scale           = 2;

            CompositeGraphic graphic = new CompositeGraphic();

            composite.Graphics.Add(graphic);
            graphic.SpatialTransform.RotationXY = 30;

            Assert.AreEqual(graphic.SpatialTransform.Transform.Elements[0], 0.8660, 0.0001F);
            Assert.AreEqual(graphic.SpatialTransform.Transform.Elements[1], 0.5, 0.0001F);
            Assert.AreEqual(graphic.SpatialTransform.Transform.Elements[2], -0.5, 0.0001F);
            Assert.AreEqual(graphic.SpatialTransform.Transform.Elements[3], 0.866, 0.0001F);
            Assert.AreEqual(graphic.SpatialTransform.CumulativeTransform.Elements[0], 1.7321, 0.0001F);
            Assert.AreEqual(graphic.SpatialTransform.CumulativeTransform.Elements[1], 1.3333, 0.0001F);
            Assert.AreEqual(graphic.SpatialTransform.CumulativeTransform.Elements[2], -1, 0.0001F);
            Assert.AreEqual(graphic.SpatialTransform.CumulativeTransform.Elements[3], 2.3094, 0.0001F);
        }
예제 #14
0
        private void RenderImage()
        {
            if (!Visible)
            {
                return;
            }

            if (_firstRender)
            {
                // the first time we try to render a freshly cloned image, we need to draw it twice
                // this is to make sure the client rectangle is updated when we try to compute the correct point of interest
                _firstRender = false;
                RenderImage();
            }

            using (System.Drawing.Graphics graphics = base.CreateGraphics())
            {
                _renderingSurface.WindowID        = Handle;
                _renderingSurface.ContextID       = graphics.GetHdc();
                _renderingSurface.ClientRectangle = ClientRectangle;
                _renderingSurface.ClipRectangle   = ClientRectangle;

                try
                {
                    ImageSpatialTransform sourceTransform = (ImageSpatialTransform)((ISpatialTransformProvider)_sourceImage).SpatialTransform;
                    ImageSpatialTransform transform       = (ImageSpatialTransform)((ISpatialTransformProvider)_magnificationImage).SpatialTransform;

                    float scale = sourceTransform.Scale * _magnificationFactor;
                    transform.ScaleToFit   = false;
                    transform.Scale        = scale;
                    transform.TranslationX = 0;
                    transform.TranslationY = 0;

                    // compute translation required to move the point of interest on the magnified image to the centre of the client area
                    var translation = transform.ConvertToSource(new PointF(ClientSize.Width / 2f, ClientSize.Height / 2f)) - new SizeF(_sourcePointOfInterest);
                    transform.TranslationX = translation.X;
                    transform.TranslationY = translation.Y;

                    WinFormsScreenProxy screen = new WinFormsScreenProxy(Screen.FromControl(this));
                    DrawArgs            args   = new DrawArgs(_renderingSurface, screen, ClearCanvas.ImageViewer.Rendering.DrawMode.Render);
                    _magnificationImage.Draw(args);

                    // clear the rendering exception message
                    _lastRenderExceptionMessage = null;
                }
                catch (Exception ex)
                {
                    Platform.Log(LogLevel.Error, ex, "An error has occured while rendering the magnified contents of the tile.");

                    // a rendering exception was encountered, so set the message field
                    _lastRenderExceptionMessage = ex is RenderingException ? ((RenderingException)ex).UserMessage : ex.Message;

                    // we cannot simply pass the existing Graphics because we haven't released its hDC yet
                    // if we do, we'll get a "Object is currently in use elsewhere" exception
                    DrawErrorMessage(_lastRenderExceptionMessage, _renderingSurface.ContextID, ClientRectangle);
                }
                finally
                {
                    graphics.ReleaseHdc(_renderingSurface.ContextID);
                }
            }

            Refresh();
        }
예제 #15
0
        public static Bitmap CreatePresentationImagePrintData(IPresentationImage image, double tileRatio, bool withAnnotation)
        {
            Size size;
            ISpatialTransformProvider provider = image as ISpatialTransformProvider;

            if (provider == null)
            {
                Platform.Log(LogLevel.Error, " 转换失败");
                throw new Exception("转换失败");
            }
            ImageSpatialTransform spatialTransform = provider.SpatialTransform as ImageSpatialTransform;
            object memento = spatialTransform.CreateMemento();

            if (!spatialTransform.ScaleToFit)
            {
                //Platform.Log(LogLevel.Error, "!spatialTransform.ScaleToFit");
                float num    = 1f / spatialTransform.Scale;
                int   width  = Convert.ToInt32((float)(image.ClientRectangle.Width * num));
                int   height = Convert.ToInt32((float)(image.ClientRectangle.Height * num));
                //if ((width > spatialTransform.SourceWidth) || (height > spatialTransform.SourceHeight))
                //{
                //    float num4 = ((float)image.ClientRectangle.Width) / ((float)image.ClientRectangle.Height);
                //    float num5 = ((float)spatialTransform.SourceWidth) / ((float)spatialTransform.SourceHeight);
                //    if (num4 > num5)
                //    {
                //        size = new Size(spatialTransform.SourceWidth, Convert.ToInt32((float)(((float)spatialTransform.SourceWidth) / num4)));
                //        spatialTransform.Scale = (spatialTransform.Scale * spatialTransform.SourceWidth) / ((float)image.ClientRectangle.Width);
                //    }
                //    else
                //    {
                //        size = new Size(Convert.ToInt32((float)(spatialTransform.SourceHeight * num4)), spatialTransform.SourceHeight);
                //        spatialTransform.Scale = (spatialTransform.Scale * spatialTransform.SourceHeight) / ((float)image.ClientRectangle.Height);
                //    }
                //}
                //else
                {
                    if (width >= 3000 || height >= 3000)
                    {
                        width  = (int)(width * 0.3);
                        height = (int)(height * 0.3);
                    }

                    size = new Size(width, height);
                    spatialTransform.Scale = (spatialTransform.Scale * width) / ((float)image.ClientRectangle.Width);
                }
            }
            else
            {
                if (spatialTransform.SourceWidth > 3000 || spatialTransform.SourceHeight > 3000)
                {
                    size = new Size((int)(spatialTransform.SourceWidth * 0.3), (int)(spatialTransform.SourceHeight * 0.3));
                }
                else
                {
                    size = new Size(spatialTransform.SourceWidth, spatialTransform.SourceHeight);
                }
            }


            Size size2 = CalculateSize(size, tileRatio);

            if (!withAnnotation)
            {
                HideAnnotation(image);
            }
            Bitmap bitmap = image.DrawToBitmap(size2.Width, size2.Height);

            if (!withAnnotation)
            {
                ShowAnnotation(image);
            }
            spatialTransform.SetMemento(memento);
            return(bitmap);
        }
        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"))));
        }
예제 #17
0
        public static Bitmap DrawToBitmap(IPresentationImage image, ExportImageParams exportParams)
        {
            Platform.CheckForNullReference(image, "image");
            Platform.CheckForNullReference(exportParams, "exportParams");

            if (!(image is ISpatialTransformProvider) || !(image is IImageGraphicProvider))
            {
                throw new ArgumentException("The image must implement IImageGraphicProvider and have a valid ImageSpatialTransform in order to be exported.");
            }

            if (exportParams.ExportOption == ExportOption.TrueSize)
            {
                var imageSopProvider = image as IImageSopProvider;
                var pixelSpacing     = imageSopProvider == null ? null : imageSopProvider.Frame.NormalizedPixelSpacing;
                if (pixelSpacing == null || pixelSpacing.IsNull)
                {
                    throw new ArgumentException("The image does not contain pixel spacing information.  TrueSize export is not possible.");
                }
            }

            ImageSpatialTransform transform = ((ISpatialTransformProvider)image).SpatialTransform as ImageSpatialTransform;

            if (transform == null)
            {
                throw new ArgumentException("The image must have a valid ImageSpatialTransform in order to be exported.");
            }

            if (exportParams.ExportOption == ExportOption.TrueSize)
            {
                return(DrawTrueSizeImageToBitmap(image, exportParams.OutputSize, exportParams.Dpi));
            }

            if (exportParams.SizeMode == SizeMode.Scale)
            {
                // TODO: Refactor ImageExporter, so there only the displayRectangle and OutputRectangle are provided
                //		Scale can be automatically figured out.
                //		A "Padded" option can be provided to distinguish between the current Fixed and ScaleToFit options
                // TODO: Refactor ImageExporter, so there are separate exporters for each ExportOption.
                //		The ExportImageParams is getting too many options and not all of them are applicable to each exporter
                //		Instead, each exporter should have its own parameters.

                if (exportParams.ExportOption == ExportOption.Wysiwyg)
                {
                    return(DrawWysiwygImageToBitmap(image, exportParams.DisplayRectangle, exportParams.Scale, exportParams.Dpi));
                }
                else
                {
                    return(DrawCompleteImageToBitmap(image, exportParams.Scale, exportParams.Dpi));
                }
            }
            else if (exportParams.SizeMode == SizeMode.ScaleToFit)
            {
                if (exportParams.ExportOption == ExportOption.Wysiwyg)
                {
                    var scale = ScaleToFit(exportParams.DisplayRectangle.Size, exportParams.OutputSize);
                    return(DrawWysiwygImageToBitmap(image, exportParams.DisplayRectangle, scale, exportParams.Dpi));
                }
                else
                {
                    var sourceImage = (IImageGraphicProvider)image;
                    var scale       = ScaleToFit(new Size(sourceImage.ImageGraphic.Columns, sourceImage.ImageGraphic.Rows), exportParams.OutputSize);
                    return(DrawCompleteImageToBitmap(image, scale, exportParams.Dpi));
                }
            }
            else
            {
                Bitmap paddedImage = new Bitmap(exportParams.OutputSize.Width, exportParams.OutputSize.Height);
                using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(paddedImage))
                {
                    // paint background
                    using (Brush b = new SolidBrush(exportParams.BackgroundColor))
                    {
                        graphics.FillRectangle(b, new Rectangle(Point.Empty, exportParams.OutputSize));
                    }

                    // paint image portion
                    Bitmap bmp;
                    if (exportParams.ExportOption == ExportOption.Wysiwyg)
                    {
                        float scale = ScaleToFit(exportParams.DisplayRectangle.Size, exportParams.OutputSize);
                        bmp = DrawWysiwygImageToBitmap(image, exportParams.DisplayRectangle, scale, exportParams.Dpi);
                    }
                    else
                    {
                        IImageGraphicProvider sourceImage = (IImageGraphicProvider)image;
                        float scale = ScaleToFit(new Size(sourceImage.ImageGraphic.Columns, sourceImage.ImageGraphic.Rows), exportParams.OutputSize);
                        bmp = DrawCompleteImageToBitmap(image, scale, exportParams.Dpi);
                    }
                    graphics.DrawImageUnscaledAndClipped(bmp, new Rectangle(CenterRectangles(bmp.Size, exportParams.OutputSize), bmp.Size));
                    bmp.Dispose();
                }

                return(paddedImage);
            }
        }
예제 #18
0
 private void NewTransform()
 {
     _transform = new ImageSpatialTransform(new CalloutGraphic(""), 10, 10, 0, 0, 0, 0);
     _transform.ClientRectangle = new Rectangle(0, 0, 15, 25);
 }