public void DrawImage(IImage image, float x, float y, float width, float height, Xamarin.Forms.Aspect aspect) { if (image != null) { CGImage cgImage = ((Image)image).NativeImage; if (cgImage != null) { if (aspect == Xamarin.Forms.Aspect.Fill) { context.DrawImage(new CGRect(x, y, width, height), cgImage); } else { Xamarin.Forms.Size bounding = new Xamarin.Forms.Size(width, height); if (aspect == Xamarin.Forms.Aspect.AspectFill) { Xamarin.Forms.Rectangle imageBox = MathHelper.Fill(new Xamarin.Forms.Rectangle(Xamarin.Forms.Point.Zero, image.Size), bounding); using (CGImage newImage = cgImage.WithImageInRect(new CGRect(imageBox.X, imageBox.Y, imageBox.Width, imageBox.Height))) context.DrawImage(new CGRect(x, y, width, height), newImage); } else { Xamarin.Forms.Rectangle boundingBox = MathHelper.Fit(image.Size, new Xamarin.Forms.Rectangle(x, y, width, height)); context.DrawImage(new CGRect(boundingBox.X, boundingBox.Y, boundingBox.Width, boundingBox.Height), cgImage); } } } context.DrawImage(new CGRect(x, y, width, height), cgImage); } }
public IBitmap Crop(Rectangle rectangle) { var cropped = _cgImage.WithImageInRect(new CGRect(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height)); UIImage image = new UIImage(cropped); return(new IOSBitmap(image, _graphics)); }
static CGImage Crop(CGImage rawImage) { // Crops from top and bottom evenly var h = rawImage.Height; var w = rawImage.Width; if (h > w) { var offset = (h - w) / 2; return(rawImage.WithImageInRect(new CGRect(0, offset, w, w))); } else { var offset = (w - h) / 2; return(rawImage.WithImageInRect(new CGRect(offset, 0, h, h))); } }
static CGImage Crop (CGImage rawImage) { // Crops from top and bottom evenly var h = rawImage.Height; var w = rawImage.Width; if (h > w) { var offset = (h - w) / 2; return rawImage.WithImageInRect (new CGRect (0, offset, w, w)); } else { var offset = (w - h) / 2; return rawImage.WithImageInRect (new CGRect (offset, 0, h, h)); } }
public IBitmapImplementation Crop(IntRectangle cropArea) { var rect = new CGRect(cropArea.Left, cropArea.Top, cropArea.Width, cropArea.Height); return(new BitmapImplementation(cgImage.WithImageInRect(rect))); }
static CGImage ScaleAndCrop (CGImage image, Size targetSize, ScaledDescription.ScaleMode mode, CancellationToken token) { token.ThrowIfCancellationRequested (); bool crop = (mode == ScaledDescription.ScaleMode.ScaleAspectFill); var toWidth = targetSize.Width; var toHeight = targetSize.Height; if (image.Width == toWidth && image.Height == toHeight) return image; if (image.Width < toWidth && image.Height < toHeight && !crop) return image; var widthScale = (double) toWidth / image.Width; var heightScale = (double) toHeight / image.Height; var scale = (crop) ? Math.Max (widthScale, heightScale) : Math.Min (widthScale, heightScale); var sizeAfterScale = (scale == widthScale) ? new Size (toWidth, (int) (image.Height * widthScale)) : new Size ((int) (image.Width * heightScale), toHeight); if (!crop) { targetSize = sizeAfterScale; } var offsetSize = new Size ( (sizeAfterScale.Width - targetSize.Width) / 2, (sizeAfterScale.Height - targetSize.Height) / 2 ); if (scale < 1.0) { var drawRect = new Rectangle ( Point.Subtract (Point.Empty, offsetSize), sizeAfterScale ); return ImageHelper.Scale (image, drawRect, targetSize); } else { var scaledCropRect = new Rectangle ( (int) (offsetSize.Width / scale), (int) (offsetSize.Height / scale), (int) (targetSize.Width / scale), (int) (targetSize.Height / scale) ); return image.WithImageInRect (scaledCropRect); } }
UIImage CropImage(UIImage sourceImage, CGRect cropDimension) { // step one, transform the crop region into image space. // (So pixelX is a pixel in the actual image, not the scaled screen) // convert our position on screen to where it should be in the image float pixelX = (float)(cropDimension.X * ScreenToImageScalar); float pixelY = (float)(cropDimension.Y * ScreenToImageScalar); // same for height, since the image was scaled down to fit the screen. float width = (float)cropDimension.Width * ScreenToImageScalar; float height = (float)cropDimension.Height * ScreenToImageScalar; // Now we're going to rotate the image to actually be "up" as the user // sees it. To do that, we simply rotate it according to the apple documentation. float rotationDegrees = 0.0f; switch (sourceImage.Orientation) { case UIImageOrientation.Up: { // don't do anything. The image space and the user space are 1:1 break; } case UIImageOrientation.Left: { // the image space is rotated 90 degrees from user space, // so do a CCW 90 degree rotation rotationDegrees = 90.0f; break; } case UIImageOrientation.Right: { // the image space is rotated -90 degrees from user space, // so do a CW 90 degree rotation rotationDegrees = -90.0f; break; } case UIImageOrientation.Down: { rotationDegrees = 180; break; } } // Now get a transform so we can rotate the image to be oriented the same as when the user previewed it CGAffineTransform fullImageTransform = GetImageTransformAboutCenter(rotationDegrees, sourceImage.Size); // apply to the image CIImage ciCorrectedImage = new CIImage(sourceImage.CGImage); CIImage ciCorrectedRotatedImage = ciCorrectedImage.ImageByApplyingTransform(fullImageTransform); // create a context and render it back out to a CGImage. CIContext ciContext = CIContext.FromOptions(null); CGImage rotatedCGImage = ciContext.CreateCGImage(ciCorrectedRotatedImage, ciCorrectedRotatedImage.Extent); // now the image is properly orientated, so we can crop it. CGRect cropRegion = new CGRect(pixelX, pixelY, width, height); CGImage croppedImage = rotatedCGImage.WithImageInRect(cropRegion); return(new UIImage(croppedImage)); }
// create a NinePatch from file public NinePatchImage(string fileName, ResizeMethod resizeMethod) { _resizeMethod = resizeMethod; const uint BLACK_PIXEL_FULL_ALPHA = 0x000000FF; // base image UIImage ninePatchIamge = UIImage.FromFile(fileName); // get lower level representaton so we can test pixels for blackness CGImage dataImage = ninePatchIamge.CGImage; IntPtr dataPointer = Marshal.AllocHGlobal(dataImage.Width * dataImage.Height * 4); CGBitmapContext context = new CGBitmapContext(dataPointer, dataImage.Width, dataImage.Height, dataImage.BitsPerComponent, dataImage.BytesPerRow, dataImage.ColorSpace, CGImageAlphaInfo.PremultipliedFirst); context.SetFillColorWithColor(UIColor.White.CGColor); context.FillRect(new RectangleF(0, 0, dataImage.Width, dataImage.Height)); context.DrawImage(new RectangleF(0, 0, dataImage.Width, dataImage.Height), dataImage); int topStart = 0; int topEnd = dataImage.Width; int leftStart = 0; int leftEnd = dataImage.Height; int bottomStart = 0; int bottomEnd = dataImage.Width; int rightStart = 0; int rightEnd = dataImage.Height; bool noPaddingSpecified = false; int centerHeight = 0; int centerWidth = 0; unsafe { // calculate top stretch line int firstPixel = dataImage.Width; int lastPixel = 0; uint *imagePointer = (uint *)(void *)dataPointer; for (int xx = 0; xx < dataImage.Width; xx++, imagePointer++) { uint thisValue = *imagePointer; if (*imagePointer == BLACK_PIXEL_FULL_ALPHA) { if (xx < firstPixel) { firstPixel = xx; } if (xx > lastPixel) { lastPixel = xx; } } } topStart = firstPixel; topEnd = lastPixel; _leftWidth = topStart - 1; _rightWidth = (dataImage.Width - 2) - topEnd; // assumes padding lines (-1 if not)! centerWidth = (dataImage.Width - 2) - (_leftWidth + _rightWidth); // calculate left side stretch line firstPixel = dataImage.Height; lastPixel = 0; imagePointer = (uint *)(void *)dataPointer; for (int xx = 0; xx < dataImage.Height; xx++, imagePointer += dataImage.Width) { uint thisValue = *imagePointer; if (thisValue == BLACK_PIXEL_FULL_ALPHA) { if (xx < firstPixel) { firstPixel = xx; } if (xx > lastPixel) { lastPixel = xx; } } } leftStart = firstPixel; leftEnd = lastPixel; _upperHeight = leftStart - 1; _lowerHeight = (dataImage.Height - 2) - leftEnd; centerHeight = (dataImage.Height - 2) - (_upperHeight + _lowerHeight); // calculate right side padding line firstPixel = dataImage.Height; lastPixel = 0; imagePointer = ((uint *)(void *)dataPointer) + (dataImage.Width - 1); for (int xx = 0; xx < dataImage.Height; xx++, imagePointer += dataImage.Width) { uint thisValue = *imagePointer; if (thisValue == BLACK_PIXEL_FULL_ALPHA) { if (xx < firstPixel) { firstPixel = xx; } if (xx > lastPixel) { lastPixel = xx; } } } if (lastPixel == 0) { noPaddingSpecified = true; } rightStart = firstPixel; rightEnd = lastPixel; // calculate bottom padding line firstPixel = dataImage.Width; lastPixel = 0; imagePointer = ((uint *)(void *)dataPointer) + (dataImage.Width * (dataImage.Height - 1)); for (int xx = 0; xx < dataImage.Width; xx++, imagePointer++) { uint thisValue = *imagePointer; if (*imagePointer == BLACK_PIXEL_FULL_ALPHA) { if (xx < firstPixel) { firstPixel = xx; } if (xx > lastPixel) { lastPixel = xx; } } } if (lastPixel == 0) { noPaddingSpecified = true; } bottomStart = firstPixel; bottomEnd = lastPixel; } Marshal.FreeHGlobal(dataPointer); // upper section bitmaps Rectangle imageRect = new Rectangle(1, 1, _leftWidth, _upperHeight); //Debug.WriteLine("Upper Left: " + imageRect.ToString()); _upperLeft = IsRect(imageRect) ? UIImage.FromImage(dataImage.WithImageInRect(imageRect)): null; imageRect = new Rectangle(topStart, 1, centerWidth, _upperHeight); //Debug.WriteLine("Upper: " + imageRect.ToString()); _upper = IsRect(imageRect) ? UIImage.FromImage(dataImage.WithImageInRect(imageRect)) : null; imageRect = new Rectangle(topEnd + 1, 1, _rightWidth, _upperHeight); //Debug.WriteLine("Upper Right: " + imageRect.ToString()); _upperRight = IsRect(imageRect) ? UIImage.FromImage(dataImage.WithImageInRect(imageRect)) : null; // center section bitmaps imageRect = new Rectangle(1, leftStart, _leftWidth, centerHeight); //Debug.WriteLine("Left: " + imageRect.ToString()); _left = IsRect(imageRect) ? UIImage.FromImage(dataImage.WithImageInRect(imageRect)) : null; imageRect = new Rectangle(topStart, leftStart, centerWidth, centerHeight); //Debug.WriteLine("Center: " + imageRect.ToString()); _center = IsRect(imageRect) ? UIImage.FromImage(dataImage.WithImageInRect(imageRect)) : null; imageRect = new Rectangle(topEnd + 1, leftStart, _rightWidth, centerHeight); //Debug.WriteLine("Right: " + imageRect.ToString()); _right = IsRect(imageRect) ? UIImage.FromImage(dataImage.WithImageInRect(imageRect)) : null; // lower section bitmaps imageRect = new Rectangle(1, leftEnd + 1, _leftWidth, _lowerHeight); //Debug.WriteLine("Lower Left: " + imageRect.ToString()); _lowerLeft = IsRect(imageRect) ? UIImage.FromImage(dataImage.WithImageInRect(imageRect)) : null; imageRect = new Rectangle(topStart, leftEnd + 1, centerWidth, _lowerHeight); //Debug.WriteLine("Lower: " + imageRect.ToString()); _lower = IsRect(imageRect) ? UIImage.FromImage(dataImage.WithImageInRect(imageRect)) : null; imageRect = new Rectangle(topEnd + 1, leftEnd + 1, _rightWidth, _lowerHeight); //Debug.WriteLine("Lower Right: " + imageRect.ToString()); _lowerRight = IsRect(imageRect) ? UIImage.FromImage(dataImage.WithImageInRect(imageRect)) : null; if (noPaddingSpecified) { // uses the center area defined by the top and left margins _paddingBounds = new Rectangle(_upperLeft.CGImage.Width, _upperLeft.CGImage.Height, _center.CGImage.Width, _center.CGImage.Height); } else { // uses the area defined by the bottom and right margins _paddingBounds = new Rectangle(bottomStart - 1, rightStart - 1, bottomEnd - bottomStart, rightEnd - rightStart); } //Debug.WriteLine("Content/Padding: " + _paddingBounds.ToString()); }