Сжатие изображения, взятого с устройства или выбранного из библиотеки, iOS - PullRequest
4 голосов
/ 02 апреля 2012

В моем приложении пользователь может сделать фотографию с устройства или загрузить ее из библиотеки, чтобы установить ее в качестве своего профиля. Теперь, когда пользователь закончил, мне нужно загрузить это изображение на сервер. Обычно изображение, полученное с устройства, имеет размер 5-6 МБ. Мне нужно сжать до 25 КБ перед загрузкой на сервер. Поэтому я использую следующий метод к этому

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [picker dismissModalViewControllerAnimated:YES];
    [picker release];
    profilePicImageView.image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    NSData* pngData = UIImagePNGRepresentation(profilePicImageView.image);
    NSLog(@"image size of png is %d", [pngData length]);
    NSData *imageData = UIImageJPEGRepresentation(profilePicImageView.image, 0.00001);
    NSLog(@"image size is %d", [imageData length]);
}

Проблема с этим методом заключается в том, что независимо от того, как мало я установил параметр масштабирования, размер сжатого файла не опускается ниже ~ 230 КБ, что почти в 10 раз больше, чем мне нужно.

Что не так с вышеуказанным методом? Я не могу сжать изображение до 25 КБ?

Любая помощь, предложение будет принята с благодарностью.

Ответы [ 3 ]

4 голосов
/ 29 апреля 2014

Вот альтернативный ответ, и я думаю, что он намного более лаконичен. Это из другого ответа о переполнении стека, но это было в моем коде некоторое время. Я получаю изображения размером ~ 15 КБ, и это с изменением размера от стандартного изображения, снятого камерой на 4 с (2,5 К на 3,5 К пикселей) до более полезного разрешения: (400 на 600). Затем сжатие UIImageJPEGRepresentation (рис. 0,1).

CGRect rect = CGRectMake(0,0,capturedImage.size.width/6,capturedImage.size.height/6);
UIGraphicsBeginImageContext( rect.size );
[capturedImage drawInRect:rect];
UIImage *picture1 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

NSData *imageDataForResize = UIImageJPEGRepresentation(picture1,0.1);
UIImage *img=[UIImage imageWithData:imageDataForResize];
capturedImage = img; // reassigning to original image as to prevent changing things later in the code

Спасибо! Я надеюсь, что это помогает другим людям! Эта проблема важна, когда вы пытаетесь выполнить быстрый просмотр коллекции, когда изображения загружаются с сервера.

3 голосов
/ 01 июня 2015

Swift:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
    var capturedImage = info[UIImagePickerControllerEditedImage] as! UIImage
    let rect = CGRectMake(0, 0, capturedImage.size.width/6, capturedImage.size.height/6)
    UIGraphicsBeginImageContext(rect.size)
    capturedImage.drawInRect(rect)
    let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    let compressedImageData = UIImageJPEGRepresentation(resizedImage, 0.1)
    capturedImage = UIImage(data: compressedImageData)!
}
1 голос
/ 02 апреля 2012

Я думаю, что приведенный ниже код может помочь вам сделать то, что вы хотите, пожалуйста, удалите часть моего кода перед использованием в вашем приложении.

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{
  [appDelegate.objList setHidden:FALSE];    
  [self dismissModalViewControllerAnimated:YES];

UIImage *capturedImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
[self performSelector:@selector(waitUntillImageCaptured:) withObject:capturedImage afterDelay:0.2];
}

-(void)waitUntillImageCaptured:(UIImage *)originalImage
{
UIImage *tempimg = originalImage;
//UIImageWriteToSavedPhotosAlbum(tempimg,nil,nil,nil);

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

CGSize newSize = CGSizeMake(320, 480);
UIGraphicsBeginImageContext(newSize);

[tempimg drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
// Get the new image from the context
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
// End the context
UIGraphicsEndImageContext();

NSString *strUser = [NSString stringWithFormat:@"%@",[imgDictName objectForKey:@"UsersName"]];
strUser = [strUser stringByReplacingOccurrencesOfString:@" " withString:@""];
[strUser retain];
NSString * strUserLocal = [strUser stringByAppendingString:@"temp.png"];

NSString *imagePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:strUserLocal];
UIImageView *tempView = [[UIImageView alloc] initWithImage:newImage];
NSData *data = [NSData dataWithData:UIImagePNGRepresentation(tempView.image)];
[tempView release];

if(data != nil) {
    [data writeToFile:imagePath atomically:YES];
}
else{
    [[NSFileManager defaultManager] removeItemAtPath:imagePath error:NULL];
}

[pool release];

[self performSelector:@selector(thumbWithSideOfLength:) withObject:strUser afterDelay:0.3];
}

- (void)thumbWithSideOfLength:(NSString*)strImgName 
{    
[self onEditing];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];

NSString *fullPathToThumbImage = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@temp.png", strImgName]];

UIImage *thumbnail;

UIImage *mainImage = [UIImage imageWithContentsOfFile:fullPathToThumbImage];

UIImageView *mainImageView = [[UIImageView alloc] initWithImage:mainImage];

CGRect clippedRect = CGRectMake(0, 0, mainImage.size.width,  mainImage.size.height);

CGFloat scaleFactor = 0.8;

UIGraphicsBeginImageContext(CGSizeMake(mainImage.size.width * scaleFactor, mainImage.size.height * scaleFactor));
CGContextRef currentContext = UIGraphicsGetCurrentContext();

CGContextClipToRect(currentContext, clippedRect);   

CGContextScaleCTM(currentContext, scaleFactor, scaleFactor);

[mainImageView.layer renderInContext:currentContext];

thumbnail = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();
NSData *imageData = UIImagePNGRepresentation(thumbnail);

[imageData writeToFile:fullPathToThumbImage atomically:YES];
userImageView.backgroundColor = [UIColor clearColor];
[userImageView imageFromImagePath:fullPathToThumbImage];

[mainImageView release];
}

Это, безусловно, решит ваши проблемы с изображением и позволит использовать этот общий метод в нескольких видах ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...