iphone - phimagemanager - phphotolibrary




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

Импортируйте 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;
}

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

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

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

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


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

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

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

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


Реализация для рендеринга любого 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, ...


Я выполнил такую ​​вещь, чтобы сохранить булавки из 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