internal static DrawingCall[] AppendCommand(DrawingCall[] drawing, DrawingCall draw) { if (drawing == null) { return new[] { draw } } ; else { var subCanvas = drawing[drawing.Length - 1].Action.Target as SubCanvas; if (subCanvas != null) { subCanvas = new SubCanvas(subCanvas, draw); var result = new DrawingCall[drawing.Length]; Array.Copy(drawing, result, drawing.Length - 1); draw.Action = subCanvas.Draw; result[drawing.Length - 1] = draw; return(result); } else { var result = new DrawingCall[drawing.Length + 1]; Array.Copy(drawing, result, drawing.Length); result[drawing.Length] = draw; return(result); } } }
public override IObservable <Canvas> Process(IObservable <Canvas> source) { return(Observable.Create <Canvas>(observer => { return source.Select(input => { var rect = RegionOfInterest; var subCanvas = new SubCanvas(image => { try { if (rect.Width > 0 && rect.Height > 0) { return image.GetSubRect(rect); } return image; } catch (Exception ex) { observer.OnError(ex); throw; } }); DrawingCall draw; draw.Action = subCanvas.Draw; draw.Observer = observer; return new Canvas(input, draw); }).SubscribeSafe(observer); })); }
public SubCanvas(SubCanvas source, SubCanvas other, bool excludeSource) { if (source.generator != other.generator) { throw new InvalidOperationException(); } generator = source.generator; drawing = MergeCommands(source.drawing, other.drawing, excludeSource); }
internal Canvas(Canvas source, Canvas other) { if (source.generator != other.generator) { throw new InvalidOperationException("Unable to merge drawing operators targeting different image sources."); } generator = source.generator; drawing = SubCanvas.MergeCommands(source.drawing, other.drawing); }
public SubCanvas(SubCanvas canvas, DrawingCall draw) { generator = canvas.generator; drawing = AppendCommand(canvas.drawing, draw); }
internal Canvas(Canvas canvas, DrawingCall draw) { generator = canvas.generator; drawing = SubCanvas.AppendCommand(canvas.drawing, draw); }
internal static DrawingCall[] MergeCommands(DrawingCall[] source, DrawingCall[] other, bool excludeSource = false) { if (source == other) { return(source); } else if (source == null) { return(other); } else if (other == null) { return(source); } else { var commandList = new List <DrawingCall>(); var hashSet = new Dictionary <Action <IplImage>, int>(SubCanvasEqualityComparer.Default); for (int i = 0; i < source.Length; i++) { hashSet.Add(source[i].Action, i); if (!excludeSource) { commandList.Add(source[i]); } } for (int i = 0; i < other.Length; i++) { int index; if (hashSet.TryGetValue(other[i].Action, out index)) { var sourceDraw = source[index]; if (object.ReferenceEquals(sourceDraw.Action, other[i].Action)) { continue; } var subCanvas = other[i].Action.Target as SubCanvas; if (subCanvas != null) { if (!excludeSource && i == 0 && index == hashSet.Count - 1) { // actions are adjacent in command list so we can merge the two subcanvases subCanvas = new SubCanvas((SubCanvas)sourceDraw.Action.Target, subCanvas, excludeSource: false); sourceDraw.Action = subCanvas.Draw; hashSet.Remove(sourceDraw.Action); hashSet.Add(sourceDraw.Action, index); commandList[index] = sourceDraw; } else { // remove redundant actions from other subcanvas subCanvas = new SubCanvas((SubCanvas)sourceDraw.Action.Target, subCanvas, excludeSource: true); sourceDraw.Action = subCanvas.Draw; commandList.Add(sourceDraw); } } } else { commandList.Add(other[i]); } } return(commandList.ToArray()); } }