Когда я использую представление UIImagePNGR или представление UIImageJPEGR для преобразования UIImage в NSdata, размер изображения слишком сильно увеличивается

Когда я использую UIImagePNGRпредпредставление или UIImageJPEGRепредставление для преобразования UIImage в NSdata, размер изображения слишком сильно увеличивается.

Действия по воспроизведению:

1) Откройте Xcode и выберите новый проект как приложение с одним представлением

2) Откройте ViewController.xib и добавьте две кнопки с именем i) Test Online Image ii) Проверьте локальное изображение

3) Добавить два IBActions

  i)  -(IBAction)ClickLocalImageTest:(id)sender;

  ii) -(IBAction)ClickOnLineImageTest:(id)sender;

4) Подключите "Test Online Image" к " -(IBAction)ClickOnLineImageTest:(id)sender "

и "Проверить локальное изображение" на " -(IBAction)ClickLocalImageTest:(id)sender ;"

5) impalment " -(IBAction)ClickLocalImageTest:(id)sender как -(IBAction)ClickLocalImageTest:(id)sender ниже

- (IBAction)ClickLocalImageTest:(id)sender {
    NSLog(@"*************Test Local Image****************\n");
    NSString *path=[[NSBundle mainBundle] pathForResource:@"hero_ipad_retina" ofType:@"jpg"];
    NSLog(@"Before testing image size is :<---- %u kb",[[NSData dataWithContentsOfFile:path] length]/1024);
    UIImage *img  = [UIImage imageNamed:@"hero_ipad_retina.jpg"];
     NSLog(@"UIImagePNGRepresentation: image size is---->: %u kb",[UIImagePNGRepresentation(img) length]/1024);
    NSLog(@"UIImageJPEGRepresentation with scale 1.0: image size is---->: %u kb \n",[UIImageJPEGRepresentation(img, 1.0) length]/1024);
    NSLog(@"*************Completed test****************\n\n\n\n");
} 

6) impalment " - (IBAction)ClickOnLineImageTest:(id)sender в следующем порядке

- (IBAction)ClickOnLineImageTest:(id)sender {
     NSLog(@"*************Test Online Image****************\n");
NSLog(@"Before testing image size is :<---- %u kb",[[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://images.apple.com/home/images/hero_ipad_retina.jpg"]] length]/1024);
UIImage *img  = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://images.apple.com/home/images/hero_ipad_retina.jpg"]]];
NSLog(@"UIImagePNGRepresentation: image size is---->: %u kb",[UIImagePNGRepresentation(img) length]/1024);
NSLog(@"UIImageJPEGRepresentation with scale 1.0: image size is---->: %u kb \n",[UIImageJPEGRepresentation(img, 1.0) length]/1024);
NSLog(@"*************Completed test****************\n\n\n\n");
}

7) Пожалуйста, скачайте изображение "hero_ipad_retina.jpg" здесь и сохраните в своих ресурсах под названием "hero_ipad_retina.jpg"

7) Теперь запустите этот проект на Xcode 4.0 позже и IOS3.0 выше SDK

**

Expected Results:
1)Click on "Test Online Image" button result should be as following 
*************Test Online Image****************
Before testing image size is :<---- 78 kb
UIImagePNGRepresentation: image size is---->: 78 kb
UIImageJPEGRepresentation with scale 1.0: image size is---->: 78 kb
*************Completed test****************
2)1)Click on "Test Local image" button result should be as following
*************Test Local Image****************
Before testing image size is :<---- 78 kb
UIImagePNGRepresentation: image size is---->: 78 kb
UIImageJPEGRepresentation with scale 1.0: image size is---->: 78 kb 
*************Completed test****************
Actual Results:
1)Click on "Test Online Image" button result should be as following 
*************Test Online Image****************
Before testing image size is :<---- 78 kb
UIImagePNGRepresentation: image size is---->: 480 kb
UIImageJPEGRepresentation with scale 1.0: image size is---->: 180 kb
*************Completed test****************
2)1)Click on "Test Local image" button result should be as following
*************Test Local Image****************
Before testing image size is :<---- 78 kb
UIImagePNGRepresentation: image size is---->: 480 kb
UIImageJPEGRepresentation with scale 1.0: image size is---->: 180 kb 
*************Completed test******************

Мой вопрос:

почему он увеличивает его размер? и каков оптимизированный способ преобразования изображения в NSData?

Примечания: загрузите изображение "hero_ipad_retina.jpg" отсюда и сохраните в своих ресурсах

Ответ 1

"hero_ipad_retina.jpg" - сжатое jpg-изображение

Эта строка:

[[NSData dataWithContentsOfFile:path] length]/1024

дает сжатый размер файла...

Эта строка:

[UIImagePNGRepresentation(img) length]/1024

распаковывает изображение и преобразует его в PNG, который является файлом без потерь. Его размер неизбежно намного больше.

Эта строка:

[UIImageJPEGRepresentation(img, 1.0) length]/1024  

сжимает изображение и пересчитывает его в JPG-представление. Вы задали качество до максимума (1.0), поэтому - по сравнению с оригиналом, который, без сомнения, был сжат до более низкого качества - вы получаете больший размер файла. Если вы установите качество на 0,5, вы получите небольшой размер файла (около 42K)

Это отличное напоминание о том, почему вы должны относиться к jpeg-изображениям с осторожностью. Каждый раз, когда вы получаете доступ к jpeg imageRep, вы разжимаете. Если вы затем повторно сжимаете - даже при полном качестве - вы понижаете качество изображения (поскольку каждый сбой с потерями хуже предыдущего). Артефакты увеличиваются и становятся особенно заметными с графическими изображениями (плоские цвета, прямые/контрастные края). PNG всегда безопаснее - он без потерь в 24-битном режиме, а в 8-битном состоянии справляется с областями плоского цвета.

Обновить

Чтобы получить размер изображения в памяти:

NSUInteger sizeInBytes  = 
  CGImageGetHeight(image.CGImage) * CGImageGetBytesPerRow(image.CGImage);

Из этого вы можете выработать коэффициенты сжатия для PNG, JPG и исходного файла (разделите на 1024 килобайта, чтобы получить правильные соотношения с приведенными выше цифрами).