UIImage: Resize, then Crop

后端 未结 16 2270
夕颜
夕颜 2020-11-22 11:51

I\'ve been bashing my face into this one for literally days now and even though I feel constantly that I am right on the edge of revelation, I simply cannot achieve my goal.

相关标签:
16条回答
  • 2020-11-22 12:09
    + (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)targetSize {
        //If scaleFactor is not touched, no scaling will occur      
        CGFloat scaleFactor = 1.0;
    
        //Deciding which factor to use to scale the image (factor = targetSize / imageSize)
        if (image.size.width > targetSize.width || image.size.height > targetSize.height)
            if (!((scaleFactor = (targetSize.width / image.size.width)) > (targetSize.height / image.size.height))) //scale to fit width, or
                scaleFactor = targetSize.height / image.size.height; // scale to fit heigth.
    
        UIGraphicsBeginImageContext(targetSize); 
    
        //Creating the rect where the scaled image is drawn in
        CGRect rect = CGRectMake((targetSize.width - image.size.width * scaleFactor) / 2,
                                 (targetSize.height -  image.size.height * scaleFactor) / 2,
                                 image.size.width * scaleFactor, image.size.height * scaleFactor);
    
        //Draw the image into the rect
        [image drawInRect:rect];
    
        //Saving the image, ending image context
        UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return scaledImage;
    }
    

    I propose this one. Isn't she a beauty? ;)

    0 讨论(0)
  • 2020-11-22 12:09
    - (UIImage*)imageScale:(CGFloat)scaleFactor cropForSize:(CGSize)targetSize
    {
        targetSize = !targetSize.width?self.size:targetSize;
        UIGraphicsBeginImageContext(targetSize); // this will crop
    
        CGRect thumbnailRect = CGRectZero;
    
        thumbnailRect.size.width  = targetSize.width*scaleFactor;
        thumbnailRect.size.height = targetSize.height*scaleFactor;
        CGFloat xOffset = (targetSize.width- thumbnailRect.size.width)/2;
        CGFloat yOffset = (targetSize.height- thumbnailRect.size.height)/2;
        thumbnailRect.origin = CGPointMake(xOffset,yOffset);
    
        [self drawInRect:thumbnailRect];
    
        UIImage *newImage  = UIGraphicsGetImageFromCurrentImageContext();
    
        if(newImage == nil)
        {
            NSLog(@"could not scale image");
        }
    
        UIGraphicsEndImageContext();
    
        return newImage;
    }
    

    Below the example of work: Left image - (origin image) ; Right image with scale x2

    enter image description here

    If you want to scale image but retain its frame(proportions), call method this way:

    [yourImage imageScale:2.0f cropForSize:CGSizeZero];
    
    0 讨论(0)
  • 2020-11-22 12:11

    Xamarin.iOS version for accepted answer on how to resize and then crop UIImage (Aspect Fill) is below

        public static UIImage ScaleAndCropImage(UIImage sourceImage, SizeF targetSize)
        {
            var imageSize = sourceImage.Size;
            UIImage newImage = null;
            var width = imageSize.Width;
            var height = imageSize.Height;
            var targetWidth = targetSize.Width;
            var targetHeight = targetSize.Height;
            var scaleFactor = 0.0f;
            var scaledWidth = targetWidth;
            var scaledHeight = targetHeight;
            var thumbnailPoint = PointF.Empty;
            if (imageSize != targetSize)
            {
                var widthFactor = targetWidth / width;
                var heightFactor = targetHeight / height;
                if (widthFactor > heightFactor)
                {
                    scaleFactor = widthFactor;// scale to fit height
                }
                else
                {
                    scaleFactor = heightFactor;// scale to fit width
                }
                scaledWidth = width * scaleFactor;
                scaledHeight = height * scaleFactor;
                // center the image
                if (widthFactor > heightFactor)
                {
                    thumbnailPoint.Y = (targetHeight - scaledHeight) * 0.5f;
                }
                else
                {
                    if (widthFactor < heightFactor)
                    {
                        thumbnailPoint.X = (targetWidth - scaledWidth) * 0.5f;
                    }
                }
            }
            UIGraphics.BeginImageContextWithOptions(targetSize, false, 0.0f);
            var thumbnailRect = new RectangleF(thumbnailPoint, new SizeF(scaledWidth, scaledHeight));
            sourceImage.Draw(thumbnailRect);
            newImage = UIGraphics.GetImageFromCurrentImageContext();
            if (newImage == null)
            {
                Console.WriteLine("could not scale image");
            }
            //pop the context to get back to the default
            UIGraphics.EndImageContext();
    
            return newImage;
        }
    
    0 讨论(0)
  • 2020-11-22 12:13
    scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0,0.0,ScreenWidth,ScreenHeigth)];
        [scrollView setBackgroundColor:[UIColor blackColor]];
        [scrollView setDelegate:self];
        [scrollView setShowsHorizontalScrollIndicator:NO];
        [scrollView setShowsVerticalScrollIndicator:NO];
        [scrollView setMaximumZoomScale:2.0];
        image=[image scaleToSize:CGSizeMake(ScreenWidth, ScreenHeigth)];
        imageView = [[UIImageView alloc] initWithImage:image];
        UIImageView* imageViewBk = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]];
        [self.view addSubview:imageViewBk];
        CGRect rect;
        rect.origin.x=0;
        rect.origin.y=0;
        rect.size.width = image.size.width;
        rect.size.height = image.size.height;
    
        [imageView setFrame:rect];
    
        [scrollView setContentSize:[imageView frame].size];
        [scrollView setMinimumZoomScale:[scrollView frame].size.width / [imageView frame].size.width];
        [scrollView setZoomScale:[scrollView minimumZoomScale]];
        [scrollView addSubview:imageView];
    
        [[self view] addSubview:scrollView];
    

    then you can take screen shots to your image by this

    float zoomScale = 1.0 / [scrollView zoomScale];
    CGRect rect;
    rect.origin.x = [scrollView contentOffset].x * zoomScale;
    rect.origin.y = [scrollView contentOffset].y * zoomScale;
    rect.size.width = [scrollView bounds].size.width * zoomScale;
    rect.size.height = [scrollView bounds].size.height * zoomScale;
    
    CGImageRef cr = CGImageCreateWithImageInRect([[imageView image] CGImage], rect);
    
    UIImage *cropped = [UIImage imageWithCGImage:cr];
    
    CGImageRelease(cr);
    
    0 讨论(0)
  • 2020-11-22 12:15

    I needed the same thing - in my case, to pick the dimension that fits once scaled, and then crop each end to fit the rest to the width. (I'm working in landscape, so might not have noticed any deficiencies in portrait mode.) Here's my code - it's part of a categeory on UIImage. Target size in my code is always set to the full screen size of the device.

    @implementation UIImage (Extras)
    
    #pragma mark -
    #pragma mark Scale and crop image
    
    - (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize
    {
        UIImage *sourceImage = self;
        UIImage *newImage = nil;    
        CGSize imageSize = sourceImage.size;
        CGFloat width = imageSize.width;
        CGFloat height = imageSize.height;
        CGFloat targetWidth = targetSize.width;
        CGFloat targetHeight = targetSize.height;
        CGFloat scaleFactor = 0.0;
        CGFloat scaledWidth = targetWidth;
        CGFloat scaledHeight = targetHeight;
        CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
    
        if (CGSizeEqualToSize(imageSize, targetSize) == NO) 
        {
            CGFloat widthFactor = targetWidth / width;
            CGFloat heightFactor = targetHeight / height;
    
            if (widthFactor > heightFactor) 
            {
                scaleFactor = widthFactor; // scale to fit height
            }
            else
            {
                scaleFactor = heightFactor; // scale to fit width
            }
    
            scaledWidth  = width * scaleFactor;
            scaledHeight = height * scaleFactor;
    
            // center the image
            if (widthFactor > heightFactor)
            {
                thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 
            }
            else
            {
                if (widthFactor < heightFactor)
                {
                    thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
                }
            }
        }   
    
        UIGraphicsBeginImageContext(targetSize); // this will crop
    
        CGRect thumbnailRect = CGRectZero;
        thumbnailRect.origin = thumbnailPoint;
        thumbnailRect.size.width  = scaledWidth;
        thumbnailRect.size.height = scaledHeight;
    
        [sourceImage drawInRect:thumbnailRect];
    
        newImage = UIGraphicsGetImageFromCurrentImageContext();
    
        if(newImage == nil)
        {
            NSLog(@"could not scale image");
        }
    
        //pop the context to get back to the default
        UIGraphicsEndImageContext();
    
        return newImage;
    }
    
    0 讨论(0)
  • 2020-11-22 12:15

    I modified Brad Larson's Code. It will aspect fill the image in given rect.

    -(UIImage*) scaleAndCropToSize:(CGSize)newSize;
    {
        float ratio = self.size.width / self.size.height;
    
        UIGraphicsBeginImageContext(newSize);
    
        if (ratio > 1) {
            CGFloat newWidth = ratio * newSize.width;
            CGFloat newHeight = newSize.height;
            CGFloat leftMargin = (newWidth - newHeight) / 2;
            [self drawInRect:CGRectMake(-leftMargin, 0, newWidth, newHeight)];
        }
        else {
            CGFloat newWidth = newSize.width;
            CGFloat newHeight = newSize.height / ratio;
            CGFloat topMargin = (newHeight - newWidth) / 2;
            [self drawInRect:CGRectMake(0, -topMargin, newSize.width, newSize.height/ratio)];
        }
    
        UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return newImage;
    }
    
    0 讨论(0)
提交回复
热议问题