public PhotoRegion[] GetRegionImages() { List <PhotoRegion> gatheredRegions = new List <PhotoRegion>(); int N = ImagesCount; for (int i = 0; i < N; i++) { var regions = imageRegions[i]; var transform = imageTransforms[i]; var backTransform = transform.Inverse; foreach (CalibratedRegionVM regVM in regions) { Point up = backTransform.Transform(regVM.Up); Point down = backTransform.Transform(regVM.Bottom); Point side = backTransform.Transform(regVM.Side); Point M = Calc.FindNormalIntersection(down, up, side); Vector sideV = side - M; //todo: coerce side point side double height = (up - down).Length; double width = (sideV * 2.0).Length; Vector downUp = up - down; Vector downUpNorm = new Vector(downUp.Y, -downUp.X); if (sideV * downUpNorm > 0.0) { sideV.Negate(); } TransformGroup tg = new TransformGroup(); Point upperLeft = up - sideV; tg.Children.Add(new TranslateTransform(-upperLeft.X, -upperLeft.Y)); if (sideV.X == 0) { throw new NotImplementedException(); } else { double angle = Vector.AngleBetween(sideV, new Vector(1.0, 0.0)); tg.Children.Add(new RotateTransform(angle)); } Canvas canvas = new Canvas(); Image img = new Image(); img.Source = new BitmapImage(new Uri(imageStorage.GetFilePath(imageIDs[i]))); canvas.Children.Add(img); img.RenderTransform = tg; canvas.Measure(new Size(width, height)); canvas.Arrange(new Rect(new Size(width, height))); RenderTargetBitmap bmp = new RenderTargetBitmap((int)width, (int)height, 96, 96, PixelFormats.Pbgra32); bmp.Render(canvas); var encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(bmp)); var bitmap = new BitmapImage(); using (MemoryStream stm = new MemoryStream()) { encoder.Save(stm); stm.Seek(0, SeekOrigin.Begin); bitmap.BeginInit(); bitmap.StreamSource = stm; bitmap.CacheOption = BitmapCacheOption.OnLoad; bitmap.EndInit(); bitmap.Freeze(); } gatheredRegions.Add(new PhotoRegion(bitmap, new Size(width, height), regVM.Order, regVM.Length)); //for now upper and lower are just placeholders holding order and length } } List <PhotoRegion> result = new List <PhotoRegion>(); //transforming order into real depth var reorderedRegions = gatheredRegions.OrderBy(r => r.ImageUpperDepth).ToArray(); //ordering by order double prevBound = UpperDepth; for (int j = 0; j < reorderedRegions.Length; j++) { PhotoRegion curReg = reorderedRegions[j]; result.Add(new PhotoRegion(curReg.BitmapImage, curReg.ImageSize, prevBound, prevBound + curReg.ImageLowerDepth)); prevBound = prevBound + curReg.ImageLowerDepth; } return(result.ToArray()); }