drawViewHierarchyInRect的问题:拍摄快照后afterScreenUpdates [英] Issue With drawViewHierarchyInRect: afterScreenUpdates while taking snapshot

查看:709
本文介绍了drawViewHierarchyInRect的问题:拍摄快照后afterScreenUpdates的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在拍摄UIViewCAEmitterLayer快照时遇到问题.下面是我用来拍摄快照的代码:

这里editingView是我的UIView:

UIGraphicsBeginImageContextWithOptions(editingView.bounds.size, NO, 0.0);
[editingView drawViewHierarchyInRect:editingView.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

请通过以下链接获取Gif图片

对于AfterScreenUpdates:否(Gif)的链接,在这种情况下,我缺少快照数据

对于afterScreenUpdates:是(Gif),在这种情况下uiview闪烁,然后更新并也面临性能问题.

解决方案

过去我也遇到过类似的问题.以下方法可能对您有用:

UIGraphicsBeginImageContextWithOptions(editingView.bounds.size, NO, 0.0);
[editingView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

请注意,您可能会在屏幕捕获中失去一些准确性,因为它可能会排除模糊和某些核心动画功能.

renderInContextdrawViewHierarchyInRect似乎都存在问题/折衷.以下代码可能值得一试(摘自此处以供参考):

- (CGContextRef) createBitmapContextOfSize:(CGSize) size {
   CGContextRef    context = NULL;
   CGColorSpaceRef colorSpace;
   int             bitmapByteCount;
   int             bitmapBytesPerRow;

   bitmapBytesPerRow   = (size.width * 4);
   bitmapByteCount     = (bitmapBytesPerRow * size.height);
   colorSpace = CGColorSpaceCreateDeviceRGB();
   if (bitmapData != NULL) {
       free(bitmapData);
   }
   bitmapData = malloc( bitmapByteCount );
   if (bitmapData == NULL) {
       fprintf (stderr, "Memory not allocated!");
       return NULL;
   }

   context = CGBitmapContextCreate (bitmapData,
                                    size.width,
                                    size.height,
                                    8,      // bits per component
                                    bitmapBytesPerRow,
                                    colorSpace,
                                    kCGImageAlphaNoneSkipFirst);

   CGContextSetAllowsAntialiasing(context,NO);
   if (context== NULL) {
       free (bitmapData);
       fprintf (stderr, "Context not created!");
       return NULL;
   }
   CGColorSpaceRelease( colorSpace );

   CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, size.height);
   CGContextConcatCTM(context, flipVertical);

   return context;
}

然后您可以执行以下操作:

CGContextRef context = [self createBitmapContextOfSize:editingView.bounds.size];
[editingView.layer renderInContext:context];

CGImageRef cgImage = CGBitmapContextCreateImage(context);
UIImage* background = [UIImage imageWithCGImage: cgImage];
CGImageRelease(cgImage);

I am facing problem with taking snapshot of UIView along with CAEmitterLayer. Below is the code which I am using for taking snapshot:

here editingView is my UIView:

UIGraphicsBeginImageContextWithOptions(editingView.bounds.size, NO, 0.0);
[editingView drawViewHierarchyInRect:editingView.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Please go through the below links for Gif Images

Link For For afterScreenUpdates:NO (Gif) in this case I am missing Snapshot data

Link For For afterScreenUpdates:YES (Gif) in this case uiview is blinking and then updated and also facing performance issue.

解决方案

I've had similar a similar issue in the past. The following might work for you as a workaround:

UIGraphicsBeginImageContextWithOptions(editingView.bounds.size, NO, 0.0);
[editingView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Note that you may lose some accuracy in the screen capture, as it may exclude blurs, and some Core Animation features.

Edit:

There seems to be issues/tradeoffs with both renderInContext and drawViewHierarchyInRect. The following code may be worth a try (taken from here for reference):

- (CGContextRef) createBitmapContextOfSize:(CGSize) size {
   CGContextRef    context = NULL;
   CGColorSpaceRef colorSpace;
   int             bitmapByteCount;
   int             bitmapBytesPerRow;

   bitmapBytesPerRow   = (size.width * 4);
   bitmapByteCount     = (bitmapBytesPerRow * size.height);
   colorSpace = CGColorSpaceCreateDeviceRGB();
   if (bitmapData != NULL) {
       free(bitmapData);
   }
   bitmapData = malloc( bitmapByteCount );
   if (bitmapData == NULL) {
       fprintf (stderr, "Memory not allocated!");
       return NULL;
   }

   context = CGBitmapContextCreate (bitmapData,
                                    size.width,
                                    size.height,
                                    8,      // bits per component
                                    bitmapBytesPerRow,
                                    colorSpace,
                                    kCGImageAlphaNoneSkipFirst);

   CGContextSetAllowsAntialiasing(context,NO);
   if (context== NULL) {
       free (bitmapData);
       fprintf (stderr, "Context not created!");
       return NULL;
   }
   CGColorSpaceRelease( colorSpace );

   CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, size.height);
   CGContextConcatCTM(context, flipVertical);

   return context;
}

Then you can do:

CGContextRef context = [self createBitmapContextOfSize:editingView.bounds.size];
[editingView.layer renderInContext:context];

CGImageRef cgImage = CGBitmapContextCreateImage(context);
UIImage* background = [UIImage imageWithCGImage: cgImage];
CGImageRelease(cgImage);

这篇关于drawViewHierarchyInRect的问题:拍摄快照后afterScreenUpdates的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆