Я работаю с графическим приложением, я использую CGlayers для рисования. При завершении штрихов я получаю изображение из слоя и сохраняю его в массиве, который я использую для отмены операции.Выполнение отмены и повтора с помощью Cglayer Рисунок
Мои штрихи состава функции
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touches ended");
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawLayerInRect(context, self.bounds, self.drawingLayer);
m_curImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[m_undoArray addObject: m_curImage];
}
My Drawing View расширяет динамически по запросу пользователя, поэтому предположим, что пользователь может сделать, скажем, линию размером drawView 200 * 200, а затем расширить его до 200 * 300 и нарисовать один больше линии, затем разверните ее до 200 * 300 и нарисуйте еще одну строку.
Вот образ приложения
Так что теперь у меня есть 3 изображения с разными размерами в UndoArray.
Всякий раз, когда я увеличиваю/уменьшаю размер холста. Я написал этот код
Об увеличении и уменьшении drawingView, я пишу эту функцию
(void)increaseDecreaseDrawingView
{
self.currentDrawingLayer = nil;
if(self.permanentDrawingLayer)
{
rectSize = self.bounds;
NSLog(@"Size%@", NSStringFromCGRect(self.bounds));
CGContextRef context = UIGraphicsGetCurrentContext();
//self.newDrawingLayer = CGLayerCreateWithContext(context, self.bounds.size, NULL);
CGFloat scale = self.contentScaleFactor;
CGRect bounds = CGRectMake(0, 0, self.bounds.size.width * scale, self.bounds.size.height * scale);
CGLayerRef layer = CGLayerCreateWithContext(context, bounds.size, NULL);
CGContextRef layerContext = CGLayerGetContext(layer);
CGContextScaleCTM(layerContext, scale, scale);
self.newDrawingLayer = layer;
CGContextDrawLayerInRect(layerContext, self.bounds, self.permanentDrawingLayer);
self.permanentDrawingLayer = nil;
}
И для этого UNDO я написал этот код
- (void)Undo
{
//Destroy the layer and create it once again with the image you get from undoArray.
self.currentDrawingLayer = Nil;
CGContextRef layerContext1 = CGLayerGetContext(self.permanentDrawingLayer);
CGContextClearRect(layerContext1, self.bounds);
CGContextRef context = UIGraphicsGetCurrentContext();
for(int i =0; i<[m_rectArrayUndo count];i++)
{
CGRect rect = [[m_rectArrayUndo objectAtIndex:i]CGRectValue];
CGLayerRef undoLayer = CGLayerCreateWithContext(context, rect.size, NULL);
CGContextRef layerContext = CGLayerGetContext(undoLayer);
CGContextTranslateCTM(layerContext, 0.0, rect.size.height);
CGContextScaleCTM(layerContext, 1.0, -1.0);
CGRect imageFrame;
NSDictionary *lineInfo = [m_undoArray objectAtIndex:i];
m_curImage = [lineInfo valueForKey:@"IMAGE"];
imageFrame = CGRectMake(0 ,0,m_curImage.size.width,m_curImage.size.height);
CGContextDrawImage(layerContext, imageFrame, m_curImage.CGImage);
CGContextDrawLayerInRect(context, rect, undoLayer);
CGContextDrawLayerInRect(layerContext1, rect, undoLayer);
}
}
В моей функции DrawRect, Я написали этот код
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();//Get a reference to current context(The context to draw)
if(self.currentDrawingLayer == nil)
{
CGLayerRef layer = CGLayerCreateWithContext(context, bounds.size, NULL);
self.currentDrawingLayer = layer;
}
if(self.permanentDrawingLayer == nil)
{
CGLayerRef layer = CGLayerCreateWithContext(context, bounds.size, NULL);
self.permanentDrawingLayer = layer;
}
if(self.newDrawingLayer == nil)
{
CGLayerRef layer = CGLayerCreateWithContext(context, bounds.size, NULL);
self.newDrawingLayer = layer;
}
CGPoint mid1 = midPoint(m_previousPoint1, m_previousPoint2);
CGPoint mid2 = midPoint(m_currentPoint, m_previousPoint1);
CGContextRef layerContext = CGLayerGetContext(self.currentDrawingLayer);
CGContextSetLineCap(layerContext, kCGLineCapRound);
CGContextSetBlendMode(layerContext, kCGBlendModeNormal);
CGContextSetLineJoin(layerContext, kCGLineJoinRound);
CGContextSetLineWidth(layerContext, self.lineWidth);
CGContextSetStrokeColorWithColor(layerContext, self.lineColor.CGColor);
CGContextSetShouldAntialias(layerContext, YES);
CGContextSetAllowsAntialiasing(layerContext, YES);
CGContextSetAlpha(layerContext, self.lineAlpha);
CGContextSetFlatness(layerContext, 1.0f);
CGContextBeginPath(layerContext);
CGContextMoveToPoint(layerContext, mid1.x, mid1.y);//Position the current point
CGContextAddQuadCurveToPoint(layerContext, m_previousPoint1.x, m_previousPoint1.y, mid2.x, mid2.y);
CGContextStrokePath(layerContext);//paints(fills) the line along the current path.
CGContextDrawLayerInRect(context, self.bounds, self.newDrawingLayer);
CGContextDrawLayerInRect(context, self.bounds, self.permanentDrawingLayer);
CGContextDrawLayerInRect(context, self.bounds, self.currentDrawingLayer);
[super drawRect:rect];
}
У меня мало сомнений
Это правильный способ сделать? Или их лучший подход.
Здесь происходит то, что мои изображения из массива undo не учитывают прямоугольники и рисуются в любой случайной позиции на новом слое.
Поэтому я хочу знать, как мы можем правильно их нарисовать, чтобы изображения были правильно нарисованы на CGlayers в определенном положении.
Хранение одного изображения для каждой операции пользователя кажется плохим. Это быстро пережевывает память. Почему бы не сохранить пользовательские команды ввода и/или рисования и не восстановить изображение при отмене. Если требуется скорость, сохраните последние N отмен в качестве изображений, а затем воссоздайте их из команд. – iccir
@iccir, я тебя не понял, сможешь ли вы его разработать – Ranjit