Сохранение контента UIVIEW в iOS 4 с реальным размером изображений внутри (т. Е. Шкала до последствия для сохранения)

StackOverflow https://stackoverflow.com/questions/4213529

Вопрос

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

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

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

PS Если у кого-нибудь есть ответ - в том числе код будет хорошим

Это было полезно?

Решение

Реализация для оказания Любой 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, масштабный коэффициент устанавливается в масштабный коэффициент основного экрана устройства.

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

Чтобы включить слабую ссылку на Uikit Framework, щелкните элемент проекта в левом навигаторе, щелкните целевой этап проекта -> Фазы построения -> Link Binary и выберите «Дополнительно» (SIDES) в uikit Framework.

Вот библиотека С похожими расширениями для UICOLOR, UIIMAGE, NSARRAY, NSDIMESARY, ...

Другие советы

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

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

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

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

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

Не могли бы вы просто создать новый контекст графики по желанию, используйте CGAffineTransform, чтобы масштабировать его, образуйте корневой слой корневого UIView, восстановите контекст к исходному размеру и визуализировать изображение? Не пробовал это для контента сетчатки, но это, кажется, хорошо работает для больших изображений, которые были расширены в UiimageViews ...

что-то типа:

CGSize originalSize = myOriginalImage.size; //or whatever

//create context
UIGraphicsBeginImageContext(originalSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context); //1 original context

// translate/flip the graphics context (for transforming from CG* coords to UI* coords
CGContextTranslateCTM(context, 0, originalSize.height);
CGContextScaleCTM(context, 1.0, -1.0);

//original image
CGContextDrawImage(context, CGRectMake(0,0,originalSize.width,originalSize.height), myOriginalImage.CGImage);

CGContextRestoreGState(context);//1 restore to original for UIView render;

//scaling
CGFloat wratio = originalSize.width/self.view.frame.size.width;
CGFloat hratio = originalSize.height/self.view.frame.size.height;

//scale context to match view size
CGContextSaveGState(context); //1 pre-scaled size
CGContextScaleCTM(context, wratio, hratio);

//render 
[self.view.layer renderInContext:context];

CGContextRestoreGState(context);//1  restore to pre-scaled size;

UIImage *exportImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

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

#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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top