【问题标题】:CoreGraphics drawing on a large UIImageCoreGraphics 在大 UIImage 上绘图
【发布时间】:2011-08-08 23:21:34
【问题描述】:

我有一个 UIImage,我在它上面画出跟随用户手指的线条。这就像一个绘图板。这在 UIImage 很小(比如 500 x 600)时非常有效,但如果它像 1600 x 1200 一样,它会变得非常粗糙和滞后。有没有办法可以优化这个?这是我在 touchesModed 中的绘图代码:

UIGraphicsBeginImageContext(self.frame.size);
[drawImageView.image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 15.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
//CGContextSetAlpha(UIGraphicsGetCurrentContext(), 0.5f);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
drawImageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

谢谢。

【问题讨论】:

    标签: objective-c ios cocoa-touch core-graphics


    【解决方案1】:

    与其一次性绘制整个 1600X1200 帧,不如根据需要绘制它。我的意思是,由于您正在绘制整个帧(驻留在内存中),因此您的性能参差不齐。

    试试CATiledLayer。基本上,您只需要绘制您的设备能够绘制的屏幕尺寸,除此之外,当用户滚动时,您需要动态绘制它。

    这是在 iPad 或 iPhone 上的 Google 地图中使用的。希望这会有所帮助...

    【讨论】:

      【解决方案2】:

      不是每次触摸移动时都创建一个新上下文并将当前图像绘制到其中,而是使用CGBitmapContextCreate 创建一个上下文并重用该上下文。之前的所有绘图都已经在上下文中,并且您不必在每次触摸移动时都创建新的上下文。

      - (CGContextRef)drawingContext {
          if(!context) { // context is an instance variable of type CGContextRef
              CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
              if(!colorSpace) return nil;
              context = CGBitmapContextCreate(NULL, contextSize.width, contextSize.height,
                                              8, contextSize.width * 32, colorSpace,
                                              kCGImageAlphaPremultipliedFirst);
              CGColorSpaceRelease(colorSpace);
              if(!context) return nil;
              CGContextConcatCTM(context, CGAffineTransformMake(1,0,0,-1,0,contextSize.height));
              CGContextDrawImage(context, (CGRect){CGPointZero,contextSize}, drawImageView.image.CGImage);
              CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
              CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 15.0);
              CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
          }
          return context;
      }
      - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
          CGContextRef ctxt = [self drawingContext];
          CGContextBeginPath(ctxt);
          CGContextMoveToPoint(ctxt, lastPoint.x, lastPoint.y);
          CGContextAddLineToPoint(ctxt, currentPoint.x, currentPoint.y);
          CGContextStrokePath(ctxt);
          CGImageRef img = CGBitmapContextCreateImage(ctxt);
          drawImageView.image = [UIImage imageWithCGImage:img];
          CGImageRelease(img);
      }
      

      此代码需要实例变量CGContextRef contextCGSize contextSize。上下文需要在 dealloc 中释放,并且每当您更改其大小时。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-01-26
        • 2014-12-24
        • 1970-01-01
        • 2015-10-26
        • 2011-05-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多