Как я создаю/представляю UIImage из 3D преобразованного UIImageView?

После применения 3-го преобразования к UIImageView.layer я должен сохранить получающееся "представление" как новый UIImage... Походивший простая задача сначала :-) но никакая удача до сих пор и поиск не подняли подсказок :-( таким образом, я надеюсь, что кто-то будет достаточно любезен для указания на меня в правильном направлении.

Очень простой проект iPhone доступен здесь.

Спасибо.

- (void)transformImage {
    float degrees = 12.0;
    float zDistance = 250;
    CATransform3D transform3D = CATransform3DIdentity;
    transform3D.m34 = 1.0 / zDistance; // the m34 cell of the matrix controls perspective, and zDistance affects the "sharpness" of the transform
    transform3D = CATransform3DRotate(transform3D, DEGREES_TO_RADIANS(degrees), 1, 0, 0); // perspective transform on y-axis
    imageView.layer.transform = transform3D;
}

/* FAIL : capturing layer contents doesn't get the transformed image -- just the original

CGImageRef newImageRef = (CGImageRef)imageView.layer.contents;

UIImage *image = [UIImage imageWithCGImage:newImageRef];

*/


/* FAIL : docs for renderInContext states that it does not render 3D transforms

UIGraphicsBeginImageContext(imageView.image.size);

[imageView.layer renderInContext:UIGraphicsGetCurrentContext()];

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

*/
//
// header
//
#import 
#define DEGREES_TO_RADIANS(x) x * M_PI / 180
UIImageView *imageView;
@property (nonatomic, retain) IBOutlet UIImageView *imageView;

//
// code
//
@synthesize imageView;

- (void)transformImage {
    float degrees = 12.0;
    float zDistance = 250;
    CATransform3D transform3D = CATransform3DIdentity;
    transform3D.m34 = 1.0 / zDistance; // the m34 cell of the matrix controls perspective, and zDistance affects the "sharpness" of the transform
    transform3D = CATransform3DRotate(transform3D, DEGREES_TO_RADIANS(degrees), 1, 0, 0); // perspective transform on y-axis
    imageView.layer.transform = transform3D;
}

- (UIImage *)captureView:(UIImageView *)view {
    UIGraphicsBeginImageContext(view.frame.size);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

- (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    NSString *title = @"Save to Photo Album";
    NSString *message = (error ? [error description] : @"Success!");
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    [alert release];
}

- (IBAction)saveButtonClicked:(id)sender {
    UIImage *newImage = [self captureView:imageView];
    UIImageWriteToSavedPhotosAlbum(newImage, self, @selector(imageSavedToPhotosAlbum: didFinishSavingWithError: contextInfo:), nil);  
}

14
задан hfossli 5 June 2013 в 07:24
поделиться

3 ответа

Вы видели это? UIImage из UIView

1
ответ дан 1 December 2019 в 14:32
поделиться

В вашем методе captureView: попробуйте заменить эту строку:

[view.layer renderInContext:UIGraphicsGetCurrentContext()];

на эту:

[view.layer.superlayer renderInContext:UIGraphicsGetCurrentContext()];

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

Я не вижу ничего в доке API, что говорит о том, что renderInContext: игнорирует 3D-преобразования. Однако, преобразования применяются к слою, а не к его содержимому, поэтому вам нужно отрисовать суперслой, чтобы увидеть примененное преобразование.

Обратите внимание, что вызов drawRect: на супервью определенно не сработает, так как drawRect: не отрисовывает subviews.

.
0
ответ дан 1 December 2019 в 14:32
поделиться

Теоретически, можно было бы использовать (сейчас разрешенный) недокументированный вызов UIGetScreenImage() после быстрого вывода его на экран на черном фоне, но на практике это будет медленным и уродливым, так что не используйте его ;P.

.
2
ответ дан 1 December 2019 в 14:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: