Получить реальный кадр после аффинного преобразования

Цель состоит в том, чтобы получить настоящие кадры на странице 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);
        }
    }
}

Размер слоя (612.000000, 792.000000), но размер s.frame (3.110400, 1.107000). Как я могу получить реальную рамку из прямоугольника, заполненного желтым цветом?


person Oleg Kuzenko    schedule 25.12.2016    source источник
comment
Вся концепция frame бессмысленна, если только преобразование не является идентичностью. Документы совершенно ясно об этом.   -  person matt    schedule 25.12.2016
comment
Значит, нет способа сделать это? Правильно?   -  person Oleg Kuzenko    schedule 25.12.2016
comment
Я не знаю, что это значит. Я не знаю, что вы думаете, что пытаетесь сделать; ты даже не объяснил, что такое s! Но ваш вопрос касается frame, а frame — это чисто сконструированная концепция, которая не имеет смысла при преобразовании.   -  person matt    schedule 25.12.2016


Ответы (2)


Как говорит Мэтт, свойство кадра вида/слоя недопустимо, если преобразование не является преобразованием идентичности.

Если вы хотите преобразовать какой-либо прямоугольник с помощью преобразования, то структура CGRect бесполезна, поскольку CGRect указывает начало координат и размер и предполагает, что остальные 3 точки прямоугольника сдвинуты вправо/вниз от начала координат.

Чтобы создать преобразованный прямоугольник, вам нужно построить 4 точки для верхней левой, верхней правой, нижней левой и нижней правой точек непреобразованного прямоугольника кадра, а затем применить преобразование к этим точкам, до применение преобразования к представлению.

См. функцию CGPoint CGPointApplyAffineTransform(CGPoint point, CGAffineTransform t), чтобы применить CGAffineTransform к точке.

Как только вы это сделаете, вы можете использовать преобразованные точки для построения пути Безье, содержащего многоугольник, который является вашим преобразованным прямоугольником. (Он может быть или не быть прямоугольником после преобразования, и единственный верный способ представить его — это 4 точки, описывающие четырехугольник.)

person Duncan C    schedule 25.12.2016

Пожалуйста, используйте свойство bounds. Также вы должны использовать bounds при создании собственного макета. Это бесплатно.

frame это прямоугольник, который определяет размер и положение вида в системе координат суперслоя. bounds его прямоугольник определяет размер и положение слоя в самой системе координат.

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

person Nick Rybalko    schedule 25.12.2016