简体   繁体   English

在保留宽高比的同时将图像调整为一定大小,并在必要时裁剪图像(iOS)

[英]Resize Image to certain size while retaining aspect ratio, crop image if necessary (iOS)

I'm using UIImagePickerController to choose an image from my Camera Roll and resizing it before uploading it to Parse. 我正在使用UIImagePickerController从我的相机胶卷中选择一个图像并调整其大小,然后再将其上载到Parse。

I want to resize an image to certain size (let's say 750x1000) while retaining the aspect ratio of the original image. 我想将图像调整为特定大小(例如750x1000),同时保留原始图像的长宽比。 If necessary, I want to crop the image. 如有必要,我想裁剪图像。 I also want it to be easy to have different versions of the image (full size, thumbnail size). 我还希望轻松拥有不同版本的图像(完整尺寸,缩略图尺寸)。 Right now I'm resizing only the height of the image. 现在,我只调整图像的高度。 How can I achieve what I'm looking for? 我如何才能找到想要的?

Thanks. 谢谢。

NewProductViewController.h NewProductViewController.h

@interface NewProductViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITextFieldDelegate>

@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) UIImagePickerController *imagePicker;
@property (nonatomic, weak) IBOutlet UIImageView *imageView;

- (UIImage *)imageWithImage:(UIImage *)sourceImage scaledToHeight:(float) i_height;

@end

NewProductViewController.m NewProductViewController.m

- (IBAction)addImage:(id)sender {
    self.imagePicker = [[UIImagePickerController alloc] init];
    self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    self.imagePicker.delegate = self;
    self.imagePicker.allowsEditing = NO;

    [self presentViewController:self.imagePicker animated:NO completion:nil];
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];

    if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
        // A photo was selected
        self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
        if (self.imagePicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
            // Save the image!
            UIImageWriteToSavedPhotosAlbum(self.image, nil, nil, nil);
        }
    }

    [self.imageView setImage:self.image];

    [self dismissViewControllerAnimated:YES completion:nil];
}
- (UIImage *)imageWithImage:(UIImage *)sourceImage scaledToHeight:(float) i_height {
    float oldHeight = sourceImage.size.height;
    float scaleFactor = i_height / oldHeight;

    float newWidth = sourceImage.size.width* scaleFactor;
    float newHeight = oldHeight * scaleFactor;

    UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
    [sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

- (IBAction)createProduct:(id)sender {
    PFObject *newProduct = [PFObject objectWithClassName:@"Product"];

    UIImage *newImage = [self imageWithImage:self.image scaledToHeight:1000.f];
    UIImage *thumbnailImage = [self imageWithImage:self.image scaledToHeight:410.f];

    NSData *imageData = UIImageJPEGRepresentation(newImage, 0.8f);
    NSData *thumbnailData = UIImageJPEGRepresentation(thumbnailImage, 0.8f);

    PFFile *imageFile = [PFFile fileWithName:@"image.jpg" data:imageData];
    PFFile *thumbnailFile = [PFFile fileWithName:@"thumbnail.jpg" data:thumbnailData];

    newProduct[@"imageFile"] = imageFile;
    newProduct[@"thumbnailFile"] = thumbnailFile;

    [newProduct setObject:[PFUser currentUser] forKey:@"user"];
}

Try this one, it crops source image proportionally and then scales it to necessary size: 尝试这一操作,它将按比例裁剪源图像,然后将其缩放到必要的大小:

- (UIImage *)imageWithImage:(UIImage *)sourceImage size:(CGSize)size {
    CGSize newSize = CGSizeZero;
    if ((sourceImage.size.width / size.width) < (sourceImage.size.height / size.height)) {
        newSize = CGSizeMake(sourceImage.size.width, size.height * (sourceImage.size.width / size.width));
    } else {
        newSize = CGSizeMake(size.width * (sourceImage.size.height / size.height), sourceImage.size.height);
    }

    CGRect cropRect = CGRectZero;
    cropRect.origin.x = (sourceImage.size.width - newSize.width) / 2.0f;
    cropRect.origin.y = (sourceImage.size.height - newSize.height) / 2.0f;
    cropRect.size = newSize;

    CGImageRef croppedImageRef = CGImageCreateWithImageInRect([sourceImage CGImage], cropRect);
    UIImage *croppedImage = [UIImage imageWithCGImage:croppedImageRef];
    CGImageRelease(croppedImageRef);

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width, size.height), NO, 0.0);
    [croppedImage drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height)];
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return scaledImage;
}

This code can help you: 此代码可以帮助您:

UIImage *originalImage = [UIImage imageNamed:@"minions.png"];
CGSize destination = CGSizeMake(750, 1000);
UIGraphicsBeginImageContext(destination);
[originalImage drawInRect:CGRectMake(0,0,destination.width,destination.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *new = [[UIImageView alloc] initWithFrame:CGRectMake(40, 40, 750, 1000)];
new.image = newImage;
[self.view addSubview:New];

Let me know if it works for you :) 请让我知道这对你有没有用 :)

When scaling to precise width or height you may lose image resolution. 当缩放到精确的宽度或高度时,您可能会失去图像分辨率。 So my solution is to crop to aspect ratio: 所以我的解决方案是裁剪长宽比:

Swift 3 迅捷3

func cropImage(image: UIImage, to aspectRatio: CGFloat) -> UIImage {

    let imageAspectRatio = image.size.height/image.size.width

    var newSize = image.size

    if imageAspectRatio > aspectRatio {
        newSize.height = image.size.width * aspectRatio
    } else if imageAspectRatio < aspectRatio {
        newSize.width = image.size.height / aspectRatio
    } else {
        return image
    }

    let center = CGPoint(x: image.size.width/2, y: image.size.height/2)
    let origin = CGPoint(x: center.x - newSize.width/2, y: center.y - newSize.height/2)

    let cgCroppedImage = image.cgImage!.cropping(to: CGRect(origin: origin, size: CGSize(width: newSize.width, height: newSize.height)))!
    let croppedImage = UIImage(cgImage: cgCroppedImage, scale: image.scale, orientation: image.imageOrientation)

    return croppedImage
}

This is a simple method I created 这是我创建的一种简单方法

    -(UIImage *)getRescaledImage:(UIImage *)image{
    int height = image.size.height;
    int width = image.size.width;
    int max = MOImageMaxHeightWidth;
    float divideFactor = 0;

    if(!(height > max) || !(width > max)){
        return image;
    }

    if(height > width){
        divideFactor = height/max;
    }else{
        divideFactor = width/max;
    }

    height = height/divideFactor;
    width = width/divideFactor;

    return [self imageWithImage:image scaledToSize:CGSizeMake(width, height)];
}


+ (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize {
    UIGraphicsBeginImageContext( newSize );
    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

MOImageMaxHeightWidth is a constant float value which you can give define for the max width/height. MOImageMaxHeightWidth是一个常量浮点值,您可以为它定义最大宽度/高度。 The aspect ratio of the image will be maintained. 图像的纵横比将保持不变。 The variable divideFactor will take care of it and is self explanatory. 变量divideFactor会处理这个问题,这很容易说明。

I have used below UIImage Categories. 我在下面使用了UIImage类别。 Hope this will work for you too. 希望这也对您有用。

https://github.com/mbcharbonneau/UIImage-Categories https://github.com/mbcharbonneau/UIImage-Categories

CGFloat scale = .5f;

CGFloat maxSize = 1632 * 1224;
CGFloat currentSize = croppedImage.size.width * croppedImage.size.height;

if ((currentSize / 2) > maxSize) {
    scale = maxSize / currentSize;
}

CGSize size = CGSizeMake(croppedImage.size.width * scale, croppedImage.size.height * scale);
__block UIImage *imageToSave = [croppedImage resizedImageWithContentMode:UIViewContentModeScaleAspectFill bounds:size interpolationQuality:kCGInterpolationLow];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 调整ImageView的大小(图像填充其边界),同时保持UIImage的宽高比 - Resize ImageView (Image filling its bounds) while retaining UIImage aspect ratio 在iOS中调整图像大小并保持其纵横比 - Resize image and maintain its aspect ratio in iOS 如何使用 Cordova/Ionic 将图像裁剪为特定的纵横比? - How to crop an image to a certain aspect ratio with Cordova/Ionic? 如何在保持图像的纵横比的同时调整 UIButton 中的图像大小? - How to resize an image in a UIButton while keeping the image's aspect ratio? 调整图像保持宽高比的大小 - Resize image maintaining aspect ratio 如何使用宽高比调整图像大小? - How to resize image with aspect ratio? Swift 如何以始终 1:1 的宽高比裁剪图像 - Swift how to crop image with always 1:1 aspect ratio 使用drawInRect调整图像大小,同时保持像Scale Aspect Fill一样的宽高比? - Resize an image with drawInRect while maintaining the aspect ratio like Scale Aspect Fill? 调整大小和设置JPEG图像的质量,同时在iOS中保留EXIF - Resize and set quality on JPEG image while retaining EXIF in iOS 缩放uiscrollview时出现问题,该问题用于在iOS中调整大小和裁剪图像 - Issue while zooming uiscrollview which is used to resize and crop Image in IOS
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM