CGContextStrokePath не работи при мащабиране и рисуване на изображения

Чертая линии според метода touchesMoved: и обикновено работи добре. Но когато приближавам изображението и рисувам, начертаните преди това линии се разместват и продължават да стават все по-мъгливи, като в крайна сметка изчезват. Опитах да използвам UIPinchGestureRecognizer и просто да увелича frame от myImageView (само за събития с много докосване), но проблемът възниква и в двете посоки. Ето кода за рисуване:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
 NSArray *allTouches = [touches allObjects];
 int count = [allTouches count];
 if(count==1){//single touch case for drawing line
    UITouch *touch = [touches anyObject];   
    CGPoint currentPoint = [touch locationInView:myImageView];
    UIGraphicsBeginImageContext(myImageView.frame.size);
    [drawImage.image drawInRect:CGRectMake(0, 0, myImageView.frame.size.width, myImageView.frame.size.height)];
    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 2.0);
    CGContextBeginPath(UIGraphicsGetCurrentContext());
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
    CGContextStrokePath(UIGraphicsGetCurrentContext());
    drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    lastPoint = currentPoint;
 }
else{//multi touch case
   // handle pinch/zoom
  }
}

Ето изображението, нарисувано без мащабиране:

въведете описание на изображението тук

И това е изображението, изобразяващо проблема след приближаване с червената стрелка, показваща сегмента, който вече е бил начертан преди приближаването (както е показано в предишното изображение). Изображението е замъглено и разместено:

въведете описание на изображението тук

Може също така да се забележи, че част от линията, начертана към края, не е засегната и феноменът възниква за линии, изтеглени назад във времето. Вярвам, че причината за това е, че атрибутите за размера на изображението се губят, когато увеличавам/намалявам, което вероятно причинява замъгляването и изместването, но не съм сигурен за това!

РЕДАКТИРАНЕ- Качих кратък видеоклип да покаже какво се случва. Това е някак забавно...

РЕДАКТИРАНЕ 2- Ето примерно приложение с един изглед, фокусирано върху проблема.


person tipycalFlow    schedule 14.02.2012    source източник
comment
Мисля, че това може да има нещо общо с contentMode на изгледа, в който рисувате. Опитайте UIViewContentModeRedraw?   -  person kevboh    schedule 14.02.2012
comment
Опитах да го настроя за myImageView и drawImage (и двете са UIImageViews), но не се получи :( ...   -  person tipycalFlow    schedule 14.02.2012
comment
@kevboh Качих видео (и добавих в отговора), което може да ви даде по-добра представа за проблема...   -  person tipycalFlow    schedule 14.02.2012
comment
Сега виждам. Това е много странно - съжалявам, че не мога да помогна повече :/   -  person kevboh    schedule 14.02.2012
comment
@kevboh няма проблем човече...благодаря за опита...   -  person tipycalFlow    schedule 15.02.2012


Отговори (3)


Изтеглих вашия проект и открих, че проблемът е в автоматичното преоразмеряване. Следните стъпки ще го решат:

Стъпка 1. Коментирайте ред 70:

drawImage.frame = CGRectMake(0, 0, labOrderImgView.frame.size.width, labOrderImgView.frame.size.height);

във вашия touchesMoved метод.

Стъпка 2. Добавете един ред код, след като drawImage е alloced (ред 90) в viewDidLoad метод:

drawImage.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

След това грешката е коригирана.

person Yu-Wei Chang    schedule 16.05.2012

Винаги просто рисувате в контекст на изображение с размера на изгледа на вашето изображение - това разбира се става замъглено, тъй като не се адаптирате към по-висока разделителна способност при увеличение. Би било по-разумно вместо това да създадете UIBezierPath веднъж и просто да добавите линия към него (с addLineToPoint:) в метода touchesMoved, след което го начертайте в персонализиран drawRect метод чрез [bezierPath stroke]. Можете също така просто да добавите CAShapeLayer като подизглед на изгледа на изображението и да зададете свойството му path на свойството CGPath на bezierPath, което сте създали по-рано.

За пример.

person MrMage    schedule 14.02.2012

Приложих поведение като това по следния начин:

  1. Трябва да запомните всички координати на вашия път (МОДЕЛ).
  2. Начертайте пътя си във временния подизглед на imageView.
  3. Когато потребителят започне да щипне/увеличи вашето изображение - не правете нищо, т.е. пътят ще бъде мащабиран от iOS
  4. В момента, когато потребителят приключи мащабирането с щипка - преначертайте пътя си по правилния начин, като използвате вашия модел.

Ако запазите пътя като изображение, ще получите лошо изглеждащо мащабиране като резултат. Освен това - не чертайте пътя направо към изображението - начертайте до някакъв прозрачен изглед и ги разделете заедно в края на редактирането.

person SVGreg    schedule 14.02.2012
comment
Между другото, разгледах вашия пример за код - и бих ви препоръчал да внедрите пътя за улавяне/запазване отделно от чертежа. Това може да ви помогне да избегнете много неприятности. Модел-изглед-контролер. - person SVGreg; 14.02.2012
comment
Всъщност лошите резултати не се получават при мащабиране. Тази странност се случва, когато рисувам след мащабиране. Гледайте краткото видео във въпроса, за да добиете по-добра представа. - person tipycalFlow; 14.02.2012
comment
Да, видях видео - това е някакъв замъглен ефект - не рисувайте пътя направо към изображението - рисувайте към някакъв прозрачен изглед и ги разделете заедно в края на редактирането. - person SVGreg; 14.02.2012
comment
Имате въпрос: проверявате ли дали рамките на drawImage и myImageView са еднакви: [drawImage.image drawInRect:CGRectMake(0, 0, myImageView.frame.size.width, myImageView.frame.size.height)]; - person SVGreg; 14.02.2012
comment
Да...всъщност, в touchesBegan гарантирам, че-drawImage.frame = myImageView.frame - person tipycalFlow; 14.02.2012
comment
Добре...опитах, като начертах drawImage и го добавих като подизглед, но пак същия проблем... - person tipycalFlow; 14.02.2012
comment
И така, последен съвет (вече казах) - отделете модела от чертежа. Не рисувайте на муха. Но използвайте MODEL (запазени пътища, параметър за мащабиране...), за да опресните изгледа си. Чертайте в UIView, но не и в UIImage. Разделете ги след края на редактирането. - person SVGreg; 14.02.2012
comment
Може да помогне, ако публикувате някакъв кодов фрагмент, с който мога да сравня своя код и да се опитам да разбера какво не е наред тук! - person tipycalFlow; 14.02.2012
comment
Опитах по твоя начин, но проблемът продължава. Запазването на точките обаче ми помогна по-късно да дам ефекта за отмяна/възвръщане, така че благодаря :) - person tipycalFlow; 20.02.2012