iphone - example - phimagemanager



Сохранение содержимого UIView в iOS 4 с реальным размером изображений внутри(т.е. масштабирование содержимого для сохранения) (4)

У меня есть UIView со многими UIImageViews в качестве подзаголовков. Приложение работает на iOS4, и я использую изображения с разрешением экрана сетчатки (т.е. загрузка изображений с масштабом = 2)

Я хочу сохранить содержимое UIView ... НО ... имеют реальный размер изображений внутри. Т.е. вид имеет размер 200x200 и изображения со шкалой = 2 внутри, я хотел бы сохранить результирующий образ 400x400 и все изображения с их реальным размером.

Теперь первое, на что нужно обратить внимание, - создать новый контекст изображения и снова загрузить все изображения внутри с помощью scale = 1, и это должно было бы сделать, но мне было интересно, есть ли более элегантный способ сделать это? Кажется, что талия памяти и процессорное время перезаряжают все снова, так как это уже сделано ...

ps, если у кого-то есть ответ - в том числе код будет приятным

https://src-bin.com


Answer #1

Импортируйте QuartzCore (щелкните главный проект, постройте фазы, импортируйте), и где вам это нужно:

#import <QuartzCore/QuartzCore.h>

Мои изображения - это свойства, если вы их не используете, игнорируйте .self и передавайте imageViews в функцию в качестве параметров, а затем вызывайте renderInContext на два изображения в новом UIGraphicsCurrentContext

- (UIImage *)saveImage
{
    UIGraphicsBeginImageContextWithOptions(self.mainImage.bounds.size, NO, 0.0);

    [self.backgroundImage.layer renderInContext:UIGraphicsGetCurrentContext()];
    [self.mainImage.layer renderInContext:UIGraphicsGetCurrentContext()];

    UIImage *savedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return savedImage;
}

Answer #2

Ключ состоит в том, что третьим параметром для UIGraphicsBeginImageContextWithOptions является масштаб , который определяет, как изображение будет в конечном счете выписано.

Если вы всегда хотите реальные размеры пикселей, используйте масштаб [[UIScreen mainScreen]], чтобы получить текущий масштаб экрана:

UIGraphicsBeginImageContextWithOptions(viewSizeInPoints, YES, [[UIScreen mainScreen] scale]);

Если вы используете scale = 1.0 на iPhone4, вы получите изображение с его размером в точках, и результат будет уменьшен с истинного количества пикселей. Если вы вручную выведете изображение на размер 640x960 (например, передаете пиксели в качестве первого параметра), это будет фактически уменьшенное изображение, которое масштабируется, что выглядит так же ужасно, как вы думаете, что это будет выглядеть.


Answer #3

Реализация для рендеринга любого UIView для изображения (работает также для отображения сетчатки).

Файл helper.h:

@interface UIView (Ext) 
- (UIImage*) renderToImage;
@end

и принадлежность к реализации в файле helper.m:

#import <QuartzCore/QuartzCore.h>

@implementation UIView (Ext)
- (UIImage*) renderToImage
{
  // IMPORTANT: using weak link on UIKit
  if(UIGraphicsBeginImageContextWithOptions != NULL)
  {
    UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, 0.0);
  } else {
    UIGraphicsBeginImageContext(self.frame.size);
  }

  [self.layer renderInContext:UIGraphicsGetCurrentContext()];
  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();  
  return image;
}

0.0 - масштабный коэффициент. Масштабный коэффициент для применения к растровому изображению. Если вы укажете значение 0.0, масштабный коэффициент будет установлен на масштабный коэффициент главного экрана устройства.

QuartzCore.framework также должен быть помещен в проект, потому что мы вызываем функцию на объект слоя.

Чтобы включить слабую ссылку в инфраструктуре UIKit, нажмите на элемент проекта в левом навигаторе, щелкните цель проекта -> фазы сборки -> ссылка на двоичный код и выберите «необязательный» (слабый) тип в среде UIKit.

Вот библиотека с аналогичными расширениями для UIColor, UIImage, NSArray, NSDictionary, ...


Answer #4

Я выполнил такую ​​вещь, чтобы сохранить булавки из MKMapView в виде PNG-файла (на экране сетчатки): MKPinAnnotationView: есть ли более трех цветов?

Вот выдержка из важной части, которая выполняет сохранение UIView ( theView ) с использованием определения сетчатки:


-(void) saveMyView:(UIView*)theView {
    //The image where the view content is going to be saved.
    UIImage* image = nil;
    UIGraphicsBeginImageContextWithOptions(theView.frame.size, NO, 2.0);
    [theView.layer renderInContext: UIGraphicsGetCurrentContext()];
    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    NSData* imgData = UIImagePNGRepresentation(image);
    NSString* targetPath = [NSString stringWithFormat:@"%@/%@", [self writablePath], @"thisismyview.png" ];
    [imgData writeToFile:targetPath atomically:YES]; 
}

-(NSString*) writablePath { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; return documentsDirectory; }





retina-display