|
| 1 | +using System; |
| 2 | +using System.Collections.Generic; |
| 3 | +using System.Diagnostics; |
| 4 | +using System.Drawing; |
| 5 | +using System.Drawing.Imaging; |
| 6 | +using System.IO; |
| 7 | +using RazorEngine; |
| 8 | +using RazorEngine.Templating; |
| 9 | +using System.Linq; |
| 10 | +using RazorEngine.Configuration; |
| 11 | +using CrossStitchProject.Models; |
| 12 | +using System.Threading.Tasks; |
| 13 | + |
| 14 | +namespace CrossStitchProject |
| 15 | +{ |
| 16 | + public class PatternWriter |
| 17 | + { |
| 18 | + private readonly List<Bitmap> _imageChunks = new List<Bitmap>(); |
| 19 | + private readonly Dictionary<Color, Floss> _color2Floss; |
| 20 | + private readonly bool _isColored; |
| 21 | + private const decimal DefaultChunkWidth = 50.0M; |
| 22 | + private const decimal DefaultChunkHeight = 60.0M; |
| 23 | + private static string _outputPath; |
| 24 | + public List<string> PatternChunks; |
| 25 | + public string PatternLegend; |
| 26 | + |
| 27 | + public PatternWriter(Bitmap b, Dictionary<Color, Floss> c2F, bool colored, string outDir) |
| 28 | + { |
| 29 | + PatternChunks = new List<string>(); |
| 30 | + ChunkifyImage(b); |
| 31 | + |
| 32 | + _isColored = colored; |
| 33 | + _color2Floss = c2F; |
| 34 | + |
| 35 | + var pictureFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures); |
| 36 | + if (string.IsNullOrEmpty(outDir)) { outDir = "MyCrossStitchPattern"; } |
| 37 | + _outputPath = Path.Combine(pictureFolder, outDir); |
| 38 | + |
| 39 | + if (!Directory.Exists(_outputPath)) { Directory.CreateDirectory(_outputPath); } |
| 40 | + } |
| 41 | + public void BuildAndSavePattern() |
| 42 | + { |
| 43 | + var task = Task.Factory.StartNew(() => GetDistinctFlossesInImage()); |
| 44 | + BuildCrossStitchPattern(); |
| 45 | + GenerateHtmlLegend(task.Result); |
| 46 | + for (var i = 0; i < PatternChunks.Count; i++) |
| 47 | + { |
| 48 | + Save(PatternChunks[i],$"chunk{i+1}.html"); |
| 49 | + } |
| 50 | + Save(PatternLegend,"legend.html"); |
| 51 | + } |
| 52 | + |
| 53 | + private void ChunkifyImage(Bitmap b) |
| 54 | + { |
| 55 | + var numHorizontalChunks = (int)Math.Ceiling(b.Width / DefaultChunkWidth); |
| 56 | + var numVerticalChunks = (int)Math.Ceiling(b.Height / DefaultChunkHeight); |
| 57 | + for (var y = 0; y < numVerticalChunks; y++) |
| 58 | + for (var x = 0; x < numHorizontalChunks; x++) |
| 59 | + { |
| 60 | + var widthLeft = b.Width - (x + 1) * DefaultChunkWidth; |
| 61 | + var heightLeft = b.Height - (y + 1) * DefaultChunkHeight; |
| 62 | + var curChunkWidth = (int)(widthLeft < 0 ? widthLeft + DefaultChunkWidth: DefaultChunkWidth); |
| 63 | + var curChunkHeight = (int)(heightLeft < 0 ? heightLeft + DefaultChunkHeight: DefaultChunkHeight); |
| 64 | + var chunk = b.Clone( |
| 65 | + new Rectangle(x * (int) DefaultChunkWidth, y * (int) DefaultChunkHeight, curChunkWidth, |
| 66 | + curChunkHeight), PixelFormat.Format32bppArgb); |
| 67 | + _imageChunks.Add(chunk); |
| 68 | + } |
| 69 | + } |
| 70 | + private void Save(string outString, string filename) |
| 71 | + { |
| 72 | + File.WriteAllText(Path.Combine(_outputPath, filename), outString); |
| 73 | + Process.Start(_outputPath); |
| 74 | + } |
| 75 | + |
| 76 | + private void GenerateHtmlLegend(HashSet<Floss> flosses) |
| 77 | + { |
| 78 | + var model = flosses.ToList(); |
| 79 | + var template = File.ReadAllText("Templates/legend_razor.html"); |
| 80 | + var result = Engine.Razor.RunCompile(template,"legendKey", null, model); |
| 81 | + PatternLegend = result; |
| 82 | + } |
| 83 | + private void BuildCrossStitchPattern() |
| 84 | + { |
| 85 | + foreach (var chunk in _imageChunks) |
| 86 | + { |
| 87 | + var template = File.ReadAllText("Templates/pattern_razor.html"); |
| 88 | + var model = new PatternChunk { Chunk = chunk, ColorToFlossDict = _color2Floss, IsColorPattern = _isColored }; |
| 89 | + //Engine.Razor = RazorEngineService.Create(new TemplateServiceConfiguration { Debug = true }); |
| 90 | + var result = Engine.Razor.RunCompile(template,"patternKey", null, model); |
| 91 | + PatternChunks.Add(result); |
| 92 | + } |
| 93 | + } |
| 94 | + private HashSet<Floss> GetDistinctFlossesInImage() |
| 95 | + { |
| 96 | + var flossesUsed = new HashSet<Floss>(); |
| 97 | + foreach (var chunk in _imageChunks) |
| 98 | + for (var y = 0; y < chunk.Height; y++) |
| 99 | + for (var x = 0; x < chunk.Width; x++) |
| 100 | + { |
| 101 | + flossesUsed.Add(_color2Floss[chunk.GetPixel(x, y)]); |
| 102 | + } |
| 103 | + return flossesUsed; |
| 104 | + } |
| 105 | + } |
| 106 | +} |
0 commit comments