#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.