【问题标题】:Get real frame after affine transformation仿射变换后得到实帧
【发布时间】:2017-05-10 09:26:12
【问题描述】:

目标是在 pdf 页面中获取真实框架以识别搜索的字符串,我正在使用 PDFKitten lib 突出显示搜索的文本并试图弄清楚如何获取突出显示文本的框架。接下来是核心方法:

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
    CGContextSetFillColorWithColor(ctx, [[UIColor whiteColor] CGColor]);
    CGContextFillRect(ctx, layer.bounds);

    // Flip the coordinate system
    CGContextTranslateCTM(ctx, 0.0, layer.bounds.size.height);
    CGContextScaleCTM(ctx, 1.0, -1.0);

    // Transform coordinate system to match PDF
    NSInteger rotationAngle = CGPDFPageGetRotationAngle(pdfPage);
    CGAffineTransform transform = CGPDFPageGetDrawingTransform(pdfPage, kCGPDFCropBox, layer.bounds, -rotationAngle, YES);
    CGContextConcatCTM(ctx, transform);

    CGContextDrawPDFPage(ctx, pdfPage);

    if (self.keyword)
    {
        CGContextSetFillColorWithColor(ctx, [[UIColor yellowColor] CGColor]);
        CGContextSetBlendMode(ctx, kCGBlendModeMultiply);
        for (Selection *s in self.selections)
        {
            NSLog(@"layer.bounds = %f, %f, %f, %f", layer.bounds.origin.x, layer.bounds.origin.y, layer.bounds.size.width, layer.bounds.size.height);
            CGContextSaveGState(ctx);
            CGContextConcatCTM(ctx, s.transform);
            NSLog(@"s.frame = %f, %f, %f, %f", s.frame.origin.x, s.frame.origin.y, s.frame.size.width, s.frame.size.height);
            CGContextFillRect(ctx, s.frame);
            CGContextRestoreGState(ctx);
        }
    }
}

layer的大小是(612.000000, 792.000000),但是s.frame的大小是(3.110400, 1.107000)。如何从填充为黄色的矩形中获取真实框架?

【问题讨论】:

  • frame 的整个概念是没有意义的,除非转换是身份。文档对此非常清楚。
  • 那么就没有办法了吗?对吗?
  • 我不知道“这样做”是什么意思。我不知道你认为你想做什么;你甚至没有解释s 是什么!但是您的问题是关于frame,而frame是一个纯粹构造的概念,在转换下没有意义。

标签: ios pdf quartz-graphics cgcontext quartz-2d


【解决方案1】:

正如马特所说,除非变换是恒等变换,否则视图/图层的框架属性无效。

如果您想使用变换来变换某个矩形,那么 CGRect 结构就没有用了,因为 CGRect 指定了原点和大小,并假定矩形的其他 3 个点从原点向右/向下移动.

为了创建一个变换的矩形,您需要为未变换的框架矩形的左上角、右上角、左下角和右下角构建 4 个点,然后将变换应用于这些点,之前 将变换应用于视图。

查看函数CGPoint CGPointApplyAffineTransform(CGPoint point, CGAffineTransform t)CGAffineTransform 应用于一个点。

完成后,您可以使用转换后的点来构建包含多边形的贝塞尔路径,该多边形是您转换后的矩形。 (变换后它可能是也可能不是矩形,唯一可靠的表示方法是用 4 个点来描述一个四边形。)

【讨论】:

    【解决方案2】:

    请使用bounds 属性。您还必须在创建自定义布局时使用bounds。它是免费的。

    frame 它是一个矩形,它定义了视图在其父层坐标系中的大小和位置。 bounds 它的矩形定义了图层在其自身坐标系中的大小和位置。

    https://developer.apple.com/reference/quartzcore/calayer/1410915-bounds

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-11
      • 2010-12-17
      • 2013-07-04
      • 2014-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多