internal void AddUpdatePuzzleSide(PuzzleSideType puzzleSideType, PuzzleSide puzzleSide) { PuzzleSides[(int)puzzleSideType] = puzzleSide; var targetExtract = puzzleSide.ConnectorType == PuzzleSide.PuzzleConnectorType.Inbound ? Image : puzzleSide.PuzzlePiece.Image; var targetInsert = puzzleSide.ConnectorType == PuzzleSide.PuzzleConnectorType.Inbound ? puzzleSide.PuzzlePiece.Image : Image; BitmapData connectorMaskData = null; var maskX = 0; var maskY = 0; switch (puzzleSideType) { case PuzzleSideType.Right: if (puzzleSide.ConnectorType == PuzzleSide.PuzzleConnectorType.Inbound) { connectorMaskData = _puzzleConnectorMask.LeftData; maskX = ImageRect.Width - _puzzleConnectorMask.Rect.Width * 2; maskY = ImageRect.Height / 2 - _puzzleConnectorMask.Rect.Height / 2; } else { connectorMaskData = _puzzleConnectorMask.RightData; maskX = _puzzleConnectorMask.Rect.Width; maskY = ImageRect.Height / 2 - _puzzleConnectorMask.Rect.Height / 2; } break; case PuzzleSideType.Bottom: if (puzzleSide.ConnectorType == PuzzleSide.PuzzleConnectorType.Inbound) { connectorMaskData = _puzzleConnectorMask.TopData; maskX = ImageRect.Width / 2 - _puzzleConnectorMask.Rect.Width / 2; maskY = ImageRect.Height - _puzzleConnectorMask.Rect.Height * 2; } else { connectorMaskData = _puzzleConnectorMask.BottomData; maskX = ImageRect.Width / 2 - _puzzleConnectorMask.Rect.Width / 2; maskY = _puzzleConnectorMask.Rect.Height; } break; } if (connectorMaskData != null) { var insertMask = targetExtract.ExtractMask(ImageRect, connectorMaskData, _puzzleConnectorMask.Rect, maskX, maskY); insertMask.DrawTo( targetInsert, new Point( puzzleSideType == PuzzleSideType.Right ? ImageRect.Width - maskX - (puzzleSide.ConnectorType == PuzzleSide.PuzzleConnectorType.Inbound ? _puzzleConnectorMask.Rect.Width * 2 : 0) : maskX, puzzleSideType == PuzzleSideType.Bottom ? ImageRect.Height - maskY - (puzzleSide.ConnectorType == PuzzleSide.PuzzleConnectorType.Inbound ? _puzzleConnectorMask.Rect.Height * 2 : 0) : maskY)); } }
public static Puzzle MakePuzzle(this Bitmap inputImageRaw, int xSplitCount, int ySplitCount) { var result = new Puzzle { PuzzlePieces = new PuzzlePiece[xSplitCount][] }; for (var i = 0; i < result.PuzzlePieces.Length; i++) { result.PuzzlePieces[i] = new PuzzlePiece[ySplitCount]; } var puzzlePieceWidth = (int)Math.Floor(inputImageRaw.Width / (decimal)xSplitCount); var puzzlePieceHeight = (int)Math.Floor(inputImageRaw.Height / (decimal)ySplitCount); result.XSplitCount = xSplitCount; result.YSplitCount = ySplitCount; var puzzlePieceRect = new Rectangle(0, 0, puzzlePieceWidth, puzzlePieceHeight); var largerSideSize = puzzlePieceWidth > puzzlePieceHeight ? puzzlePieceWidth : puzzlePieceHeight; using (var puzzleConnectorMask = new PuzzleConnectorMask( largerSideSize / DefaultConnectorScale, largerSideSize / DefaultConnectorScale)) { var inputImageRect = new Rectangle(0, 0, xSplitCount * puzzlePieceRect.Width, ySplitCount * puzzlePieceRect.Height); var inputImage = inputImageRaw.Clone(inputImageRect, PixelFormat.Format32bppArgb); result.Image = inputImage; for (var i = 0; i < xSplitCount; i++) { for (var j = 0; j < ySplitCount; j++) { var slicePuzzlePieceRect = new Rectangle(i * puzzlePieceRect.Width, j * puzzlePieceRect.Height, puzzlePieceRect.Width, puzzlePieceRect.Height); var slicePuzzlePieceBitmap = inputImage.Clone(slicePuzzlePieceRect, inputImage.PixelFormat); var puzzlePieceBitmap = new Bitmap( puzzlePieceRect.Width + puzzleConnectorMask.Rect.Width * 2, puzzlePieceRect.Height + puzzleConnectorMask.Rect.Height * 2, PixelFormat.Format32bppArgb); slicePuzzlePieceBitmap.DrawTo( puzzlePieceBitmap, new Point( puzzleConnectorMask.Rect.Width, puzzleConnectorMask.Rect.Height), slicePuzzlePieceRect.Width, slicePuzzlePieceRect.Height); var puzzlePiece = new PuzzlePiece(puzzlePieceBitmap, puzzleConnectorMask); result.PuzzlePieces[i][j] = puzzlePiece; } } Parallel.For(0, xSplitCount, i => { for (var j = 0; j < ySplitCount; j++) { var puzzlePiece = result.PuzzlePieces[i][j]; if (i != 0) { var puzzleConnectorType = Random.Next(2) > 0 ? PuzzleSide.PuzzleConnectorType.Inbound : PuzzleSide.PuzzleConnectorType.Outbound; var leftPuzzlePiece = result.PuzzlePieces[i - 1][j]; puzzlePiece.AddUpdatePuzzleSide( PuzzlePiece.PuzzleSideType.Left, new PuzzleSide( leftPuzzlePiece, (i - 1, j), puzzleConnectorType)); leftPuzzlePiece.AddUpdatePuzzleSide( PuzzlePiece.PuzzleSideType.Right, new PuzzleSide( puzzlePiece, (i, j), puzzleConnectorType == PuzzleSide.PuzzleConnectorType.Inbound ? PuzzleSide.PuzzleConnectorType.Outbound : PuzzleSide.PuzzleConnectorType.Inbound)); } if (j != 0) { var puzzleConnectorType = Random.Next(2) > 0 ? PuzzleSide.PuzzleConnectorType.Inbound : PuzzleSide.PuzzleConnectorType.Outbound; var topPuzzlePiece = result.PuzzlePieces[i][j - 1]; puzzlePiece.AddUpdatePuzzleSide( PuzzlePiece.PuzzleSideType.Top, new PuzzleSide( topPuzzlePiece, (i, j - 1), puzzleConnectorType)); topPuzzlePiece.AddUpdatePuzzleSide( PuzzlePiece.PuzzleSideType.Bottom, new PuzzleSide( puzzlePiece, (i, j), puzzleConnectorType == PuzzleSide.PuzzleConnectorType.Inbound ? PuzzleSide.PuzzleConnectorType.Outbound : PuzzleSide.PuzzleConnectorType.Inbound)); } }