将图像调整为特定尺寸,同时保持纵横比,必要时裁剪图像(iOS)

时间:2015-07-30 14:08:45

标签: ios

我正在使用UIImagePickerController从我的相机胶卷中选择一张图像并在将其上传到Parse之前调整它的大小。

我希望在保留原始图像宽高比的同时将图像调整到一定的大小(比方说750x1000)。如有必要,我想裁剪图像。我还希望它可以很容易地拥有不同版本的图像(完整大小,缩略图大小)。现在我只调整图像的高度。我怎样才能实现我的目标?

感谢。

NewProductViewController.h

- (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"];
}

NewProductViewController.m

Add android-support-multidex.jar to your project. The jar can be found in your Android SDK folder /sdk/extras/android/support/multidex/library/libs

5 个答案:

答案 0 :(得分:5)

尝试这个,它按比例裁剪源图像,然后将其缩放到必要的大小:

- (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;
}

答案 1 :(得分:1)

此代码可以帮助您:

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];

让我知道它是否适合你:)

答案 2 :(得分:1)

缩放到精确的宽度或高度时,可能会丢失图像分辨率。所以我的解决方案是裁剪到纵横比:

Swift 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
}

答案 3 :(得分:0)

这是我创建的一个简单方法

    -(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是一个常量浮点值,您可以为最大宽度/高度定义该值。将保持图像的纵横比。变量divideFactor会处理它并且是自我解释的。

答案 4 :(得分:0)

我使用了下面的UIImage类别。希望这对你也有用。

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];