CreateGeometricTransform() static private method

This method initializes the new CGAffineTransform such that it represents the geometric transform that maps the rectangle specified by the rect parameter to the parallelogram defined by the three points in the plgpts parameter. The upper-left corner of the rectangle is mapped to the first point in the plgpts array, the upper-right corner is mapped to the second point, and the lower-left corner is mapped to the third point. The lower-right point of the parallelogram is implied by the first three.
static private CreateGeometricTransform ( RectangleF rect, Point points ) : CGAffineTransform
rect RectangleF Rectangle.
points Point Points.
return CGAffineTransform
Esempio n. 1
0
        /// <summary>
        /// Draws the specified Image at the specified location and with the specified shape and size.
        ///
        /// The destPoints parameter specifies three points of a parallelogram. The three PointF structures
        /// represent the upper-left, upper-right, and lower-left corners of the parallelogram. The fourth point
        /// is extrapolated from the first three to form a parallelogram.
        ///
        /// The image represented by the image object is scaled and sheared to fit the shape of the parallelogram
        /// specified by the destPoints parameter.
        /// </summary>
        /// <param name="image">Image.</param>
        /// <param name="destPoints">Destination points.</param>
        public void DrawImage(Image image, PointF [] destPoints)
        {
            if (image == null)
            {
                throw new ArgumentNullException("image");
            }
            if (destPoints == null)
            {
                throw new ArgumentNullException("destPoints");
            }
            if (destPoints.Length < 3)
            {
                throw new ArgumentException("Destination points must be an array with a length of 3 or 4. " +
                                            "A length of 3 defines a parallelogram with the upper-left, upper-right, " +
                                            "and lower-left corners. A length of 4 defines a quadrilateral with the " +
                                            "fourth element of the array specifying the lower-right coordinate.");
            }

            // Windows throws a Not Implemented error if the points are more than 3
            if (destPoints.Length > 3)
            {
                throw new NotImplementedException();
            }
            if (image.nativeMetafilePage != null)
            {
                throw new NotImplementedException();
            }

            // create our rectangle.  Offset is 0 because the CreateGeometricTransform bakes our x,y offset in there.
            var rect = new CGRect(0, 0, destPoints [1].X - destPoints [0].X, destPoints [2].Y - destPoints [0].Y);

            // We need to flip our Y axis so the image appears right side up
            var geoTransform = new CGAffineTransform(1, 0, 0, -1, 0, rect.Height);

            //var geott = GeomUtilities.CreateGeometricTransform (rect, destPoints);
            geoTransform.Multiply(GeomUtilities.CreateGeometricTransform(rect, destPoints));

            // Apply our transform to the context
            context.ConcatCTM(geoTransform);

            // now we draw our image.
            context.DrawImage(rect, image.NativeCGImage);

            // Now we revert our image transform from the context
            var revert = CGAffineTransform.CGAffineTransformInvert(geoTransform);

            context.ConcatCTM(revert);
        }
        /// <summary>
        /// Draws the specified portion of the specified Image at the specified location and with the specified size.
        ///
        /// The destPoints specifies a parallelogram with the first point specifying the upper left corner,
        /// second point specifying the upper right corner and the third point specifying the lower left corner.
        ///
        /// The srcRect parameter specifies a rectangular portion of the image object to draw. This portion is scaled
        /// up or down (in the case where source rectangle overruns the bounds of the image) to fit inside the rectangle
        /// specified by the destRect parameter.
        /// </summary>
        /// <param name="image">Image.</param>
        /// <param name="destPoints">Destination points.</param>
        /// <param name="srcRect">Source rect.</param>
        /// <param name="srcUnit">Source unit.</param>
        public void DrawImage(Image image, PointF [] destPoints, RectangleF srcRect, GraphicsUnit srcUnit)
        {
            if (image == null)
            {
                throw new ArgumentNullException("image");
            }
            if (destPoints == null)
            {
                throw new ArgumentNullException("destPoints");
            }

            if (destPoints.Length < 3)
            {
                throw new ArgumentException("Destination points must be an array with a length of 3 or 4. " +
                                            "A length of 3 defines a parallelogram with the upper-left, upper-right, " +
                                            "and lower-left corners. A length of 4 defines a quadrilateral with the " +
                                            "fourth element of the array specifying the lower-right coordinate.");
            }

            // Windows throws a Not Implemented error if the points are more than 3
            if (destPoints.Length > 3)
            {
                throw new NotImplementedException();
            }

            var srcRect1 = srcRect;

            // If the source units are not the same we need to convert them
            // The reason we check for Pixel here is that our graphics already has the Pixel's baked into the model view transform
            if (srcUnit != graphicsUnit && srcUnit != GraphicsUnit.Pixel)
            {
                ConversionHelpers.GraphicsUnitConversion(srcUnit, graphicsUnit, image.HorizontalResolution, image.VerticalResolution, ref srcRect1);
            }

            if (srcRect1.Location == Point.Empty && srcRect1.Size == image.Size)
            {
                DrawImage(image, destPoints);
                return;
            }
            if (image.NativeCGImage == null)
            {
                throw new NotImplementedException();
            }

            // Obtain the subImage
            var subImage = image.NativeCGImage.WithImageInRect(srcRect1.ToCGRect());

            // If we do not have anything to draw then we exit here
            if (subImage.Width == 0 || subImage.Height == 0)
            {
                return;
            }

            // create our rectangle.  Offset is 0 because the CreateGeometricTransform bakes our x,y offset in there.
            var rect = new RectangleF(0, 0, destPoints [1].X - destPoints [0].X, destPoints [2].Y - destPoints [0].Y);

            // We need to flip our Y axis so the image appears right side up
            var geoTransform = new CGAffineTransform(1, 0, 0, -1, 0, rect.Height);

            // Make sure we scale the image in case the source rectangle
            // overruns our subimage bounds (width and/or height)
            float scaleX = subImage.Width / srcRect1.Width;
            float scaleY = subImage.Height / srcRect1.Height;

            geoTransform.Scale(scaleX, scaleY);

            //var geott = GeomUtilities.CreateGeometricTransform (rect, destPoints);
            geoTransform.Multiply(GeomUtilities.CreateGeometricTransform(rect, destPoints));

            // Apply our transform to the context
            context.ConcatCTM(geoTransform);

            // now we draw our image.
            context.DrawImage(rect.ToCGRect(), subImage);

            // Now we revert our image transform from the context
            var revert = CGAffineTransform.CGAffineTransformInvert(geoTransform);

            context.ConcatCTM(revert);

            subImage.Dispose();
        }