CGContextDrawImage ЧРЕЗВЫЧАЙНО медленный после того, как в него втянут большой UIImage

Похоже, что CGContextDrawImage (CGContextRef, CGRect, CGImageRef) выполняет НАМНОГО ХУЖЕ при рисовании CGImage, созданного CoreGraphics (т.е. с помощью CUREitmapContextCreateImage), чем при рисовании CGGIGIMmImage Смотрите этот метод тестирования:

-(void)showStrangePerformanceOfCGContextDrawImage
{
    ///Setup : Load an image and start a context:
    UIImage *theImage = [UIImage imageNamed:@"reallyBigImage.png"];
    UIGraphicsBeginImageContext(theImage.size);
    CGContextRef ctxt = UIGraphicsGetCurrentContext();    
    CGRect imgRec = CGRectMake(0, 0, theImage.size.width, theImage.size.height);


    ///Why is this SO MUCH faster...
    NSDate * startingTimeForUIImageDrawing = [NSDate date];
    CGContextDrawImage(ctxt, imgRec, theImage.CGImage);  //Draw existing image into context Using the UIImage backing    
    NSLog(@"Time was %f", [[NSDate date] timeIntervalSinceDate:startingTimeForUIImageDrawing]);

    /// Create a new image from the context to use this time in CGContextDrawImage:
    CGImageRef theImageConverted = CGBitmapContextCreateImage(ctxt);

    ///This is WAY slower but why??  Using a pure CGImageRef (ass opposed to one behind a UIImage) seems like it should be faster but AT LEAST it should be the same speed!?
    NSDate * startingTimeForNakedGImageDrawing = [NSDate date];
    CGContextDrawImage(ctxt, imgRec, theImageConverted);
    NSLog(@"Time was %f", [[NSDate date] timeIntervalSinceDate:startingTimeForNakedGImageDrawing]);


}

Итак, я полагаю, вопрос в том, # 1 что может вызвать это, и # 2 есть ли способ обойти это, т.е. другие способы создания CGImageRef, которые могут быть быстрее? Я понимаю, что мог бы сначала преобразовать все в UIImages, но это такое уродливое решение. У меня уже есть CGContextRef.

ОБНОВЛЕНИЕ: Это не обязательно верно при рисовании небольших изображений? Это может быть признаком того, что эта проблема усиливается, когда используются большие изображения (то есть изображения камеры полного размера). 640x480 кажется довольно похожим с точки зрения времени выполнения с любым методом

UPDATE 2: Ok, так что я обнаружил что-то новое.. На самом деле это НЕ поддержка CGImage, которая меняет производительность. Я могу перевернуть порядок 2 шагов и сделать метод UIImage вести себя медленно, в то время как «голый» CGImage будет супер быстро. Кажется, что то, что вы выступите вторым, будет страдать от ужасного выступления. Это происходит, ЕСЛИ Я не освобождаю память, вызывая CGImageRelease для образа, который я создал с помощью CUREitmapContextCreateImage. Затем метод с поддержкой UIImage будет быстрым. Обратное это неправда. Что дает? «Переполненная» память не должна так влиять на производительность?

ОБНОВЛЕНИЕ 3: Говорить слишком рано. Предыдущее обновление верно для изображений размером 2048x2048, но увеличение до 1936x2592 (размер камеры) голый метод CGImage все еще намного медленнее, независимо от порядка операций или ситуации с памятью. Возможно, существуют некоторые внутренние ограничения CG, которые делают 16MB изображение эффективным, в то время как 21MB изображение не может быть эффективно обработано. Его буквально в 20 раз медленнее, чем размер камеры 2048x2048. Каким-то образом UIImage предоставляет свои данные CGImage гораздо быстрее, чем чистый объект CGImage. o. O

UPDATE 4: Я подумал, что это может иметь отношение к какой-то вещи кэширования памяти, но результаты те же, загружается ли UIImage с не кэшированием [UIImage ImageWityContiveOfFile], как если бы использовался [UIImage imageName].

ОБНОВЛЕНИЕ 5 (День 2): После создания вопросов mroe, чем вчера были даны ответы, у меня есть что-то тела сегодня. Что я могу сказать точно, так это следующее:

  • CGImages за UIImage не используют альфа. (kCGImageAlphaAlphaSkipLast). Я думал, что, может быть, их быстрее нарисовать, потому что мой контекст использовал альфа. Я изменил контекст, чтобы использовать kCGImageAlphaAlphaSkipLast. Это делает чертеж НАМНОГО быстрее, ЕСЛИ:
  • Рисование в CGContextRef с UIImage FIRST,делает ВСЕ последующие рисунки изображения медленными

Я доказал это 1) сначала создавая контекст, не являющийся альфа (1936x2592). 2) Заполнен случайным цветом 2x2 квадратов. 3) Полный кадр, рисующий CGImage в этот контекст, был FAST (0,17 секунды) 4) Повторный эксперимент, но заполненный контекст с нарисованным CGImage, поддерживающим UIImage. Последующий полный рисунок кадра составлял 6 + секунд. SLOWWWW.

Каким-то образом рисование в контексте с (большим) UIImage резко замедляет все последующее рисование в этом контексте.

-121--712720- Ввод SecurityContext в прослушиватель prePersist или preUpdate в Symfony2 для получения пользователя в хранилище По или По причинам циклической ошибки ссылки Я устанавливаю класс прослушивателя, в котором я задам столбец ownerid в любой доктрине PrePersist. Мой файл services.yml выглядит так... услуги: my.listener: класс: App\SharedBundle\Listener\...

Я устанавливаю класс прослушивателя, где я буду устанавливать столбец ownerid в любой доктрине prePersist. Мой файл services.yml выглядит так...

services:
my.listener:
    class: App\SharedBundle\Listener\EntityListener
    arguments: ["@security.context"]
    tags:
        - { name: doctrine.event_listener, event: prePersist }

и мой класс выглядит так...

use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\Security\Core\SecurityContextInterface;

class EntityListener
{

protected $securityContext;

public function __construct(SecurityContextInterface $securityContext)
{
    $this->securityContext = $securityContext;
}


/**
 *
 * @param LifecycleEventArgs $args 
 */
public function prePersist(LifecycleEventArgs $args)
{

    $entity = $args->getEntity();
    $entityManager = $args->getEntityManager();

    $entity->setCreatedby();

}
}

Результатом этого является следующая ошибка.

ServiceSharingReferureException: обнаружена циклическая ссылка для пути службы «doctrine.orm.default_entity_manager,»: «doctrine.orm.default_entity_manager - > doctrine.dbal.default_connection - > my.listener - > security.context - > security.authentication.manager - >». «Text» «fos_user.user_manager.»

Я предполагаю, что контекст безопасности уже введен где-то в цепочке, но я не знаю, как получить к нему доступ. Есть идеи?

44
задан Jon Winstanley 9 September 2013 в 11:15
поделиться