Как избавиться от этих «точек» между моими линиями, когда я рисую?

#iphone #xcode #cgcontext #uitouch

#iPhone #xcode #cgcontext #uitouch

Вопрос:

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

Я получил код из примера рисования.

 // draw a line
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

mouseSwiped = YES;
UITouch *touch = [touches anyObject];   
CGPoint currentPoint = [touch locationInView:self.view];
currentPoint.y -= 0; // 20 only for 'kCGLineCapRound'
UIGraphicsBeginImageContext(self.view.frame.size);
//Albert Renshaw - Apps4Life
[drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width, drawImage.frame.size.height)]; //originally self.frame.size.width, self.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); //kCGLineCapSquare, kCGLineCapButt, kCGLineCapRound
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brushSize); // for size
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), r, g, b, alpha); //values for R, G, B, and Alpha
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

lastPoint = currentPoint;

mouseMoved  ;

if (mouseMoved == 10) {
    mouseMoved = 0;
}

    }

    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {


//Draw a dot
if(!mouseSwiped) {

    UIGraphicsBeginImageContext(self.view.frame.size);
    [drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width, drawImage.frame.size.height)]; //originally self.frame.size.width, self.frame.size.height)];
    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); //kCGLineCapSquare, kCGLineCapButt, kCGLineCapRound
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brushSize);
    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), r, g, b, alpha);
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
    CGContextStrokePath(UIGraphicsGetCurrentContext());
    CGContextFlush(UIGraphicsGetCurrentContext());
    drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}
    }
  

Это окончательная версия с уникальной буквой, цветом, размером кисти для каждой линии:

 - (void) updateDrawingBoard 
{
UIGraphicsBeginImageContext(self.drawImage.bounds.size);

for ( NSDictionary *dict in paths ) {

   UIBezierPath *p = (UIBezierPath*)[dict objectForKey:@"path"];
   p.lineWidth = [[dict objectForKey:@"size"]floatValue];
   [[UIColor colorWithRed:[[dict objectForKey:@"red"]floatValue] 
                     green:[[dict objectForKey:@"green"]floatValue] 
                      blue:[[dict objectForKey:@"blue"]floatValue] 
                     alpha:[[dict objectForKey:@"alpha"]floatValue]] setStroke];
  [p stroke];
}
[[UIColor colorWithRed:r green:g blue:b alpha:alpha] setStroke];
[path stroke];

self.drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint touchPoint = [[touches anyObject] locationInView:self.drawImage];

path = [[UIBezierPath bezierPath] retain];
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinBevel;
path.lineWidth = brushSize;
[path moveToPoint:touchPoint];

[self updateDrawingBoard];
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint touchPoint = [[touches anyObject] locationInView:self.drawImage];

[path addLineToPoint:touchPoint];

NSDictionary   *dict = [NSDictionary dictionaryWithObjectsAndKeys:
                        path,@"path",
                        [NSNumber numberWithFloat:r], @"red", 
                        [NSNumber numberWithFloat:g], @"green", 
                        [NSNumber numberWithFloat:b], @"blue", 
                        [NSNumber numberWithFloat:alpha], @"alpha", 
                        [NSNumber numberWithFloat:brushSize], @"size", nil];
[paths addObject:dict];
[path release];
path = nil;

[self updateDrawingBoard];
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint touchPoint = [[touches anyObject] locationInView:self.drawImage];

[path addLineToPoint:touchPoint];

[self updateDrawingBoard];
}
  

Комментарии:

1. Откуда alpha берется? Похоже, вы можете исправить это, установив alpha на 1.

2. Да, я знаю, с alpha = 1 это работает. Но я хочу иметь прозрачный цвет, чтобы выделить текст под ним.

3. Вы пытались манипулировать соединением линий? developer.apple.com/library/mac/#documentation/GraphicsImaging /…

4. Вы получили ответ? Я сталкиваюсь с той же проблемой.

Ответ №1:

Проблема в том, что вы постепенно наращиваете линию, рисуя в изображении. Там, где старая линия и новая линия перекрываются, вы видите «точки» от перерисовки.

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

Схема кода:

  • За некоторое время до начала рисования создайте CGMutablePathRef .
  • Когда вы получите новую точку, которую хотите добавить к своей линии, используйте CGPathAddLineToPoint .
  • Когда придет время рисовать контур, используйте CGContextAddPath , чтобы добавить линию в контекст, затем заполните или обведите по желанию. Вы также могли бы использовать CGContextDrawPath .

В качестве альтернативы вы можете использовать UIBezierPath вместо CGMutablePathRef , и в этом случае выполняются следующие действия:

  • Создайте UIBezierPath .
  • Используйте -addLineToPoint: для добавления линий к контуру.
  • Используйте -stroke , -fill и подобные, чтобы отобразить путь в контексте.

Вероятно, это будет проще, если вы не привыкли работать с CoreGraphics напрямую.

Я бы удалил промежуточное изображение и переместил этот код в класс view ( LineDrawView или CanvasView или что-то еще), а не оставлял код в контроллере view. Вместо обновления изображения вид может просто выводиться непосредственно на экран. В представлении будут методы для очистки контура, отмены штрихов и создания изображения контура. Затем контроллер просмотра будет использовать их для очистки холста, отмены линий и сохранения рисунка. Позже вы могли бы дополнить это функциональными возможностями для настройки стиля линий.

Комментарии:

1. Хорошо, теперь я могу рисовать. Но как я могу сохранить пути к моему виду или изображению? Потому что я загружаю в UIImageView и устанавливаю его в качестве подвида из этого представления, чтобы я мог рисовать над ним. В конце я хочу сохранить загруженное изображение с новыми путями в файле. Отредактировал код в моем вопросе.

2. Используйте UIGraphicsBeginImageContextWithOptions так, как вы делали в старом коде. Сделайте размер изображения размером границ вашего вида, [self bounds].size . Затем просто рисуйте, как обычно; вы могли бы вызвать [self drawRect:[self bounds]] , при условии, что начало координат ваших границ по-прежнему равно (0, 0).

3. Как это должно работать? Теперь мое приложение постоянно вылетает. Я не знаю, куда поместить UIGraphicsBeginImageContext и функцию drawRect. Отредактировал мой код.

4. На этом этапе вы теряетесь. Вам необходимо ознакомиться с Руководством по рисованию и печати для iOS . Если у вас есть дополнительные вопросы, не стесняйтесь задать новый вопрос по Stack Overflow.

Ответ №2:

Я пытался решить эту проблему в течение нескольких дней, пробуя Джереми У. Ответ Шермана, который, вероятно, является очень хорошей идеей, но не был осуществим для моей реализации.

В моем приложении для рисования я не мог заставить альфа-кривые сливаться друг с другом, постоянно отображая контур, хотя точки исчезли. Если вам просто нужен чистый контур альфа-цвета, возможно, это правильный путь.

Но я нашел решение этой проблемы, которое было намного проще; эти настройки создают идеальный контур альфа-цвета в режиме реального времени с помощью наложения (думайте об этом как о стиле фломастера).:

 CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapButt);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeMultiply);
  

Надеюсь, это поможет всем, кто занимается простым CG-рисованием в iOS.