/// <summary> /// Processes a single PNG file representing a copper layer. /// The nets, i.e. the areas in electrical contact are found, a bitmap with each net highlighted is generated as well /// as a HTML file to show them properly. /// </summary> /// <param name="filename">Filename of the file containing the PNG image of the copper layer.</param> public static void ProcessSingleLayer(string filename) { if (!File.Exists(filename)) { Console.WriteLine($"File {filename} not found"); return; } MonochromeBitmapAccessor topLayer = new MonochromeBitmapAccessor(filename); var scannerToplayer = LoadAndScan(filename); var path = Path.GetFileNameWithoutExtension(filename); Directory.CreateDirectory(path); foreach (int netId in scannerToplayer.GetNetIds()) { AbstractBitmapGenerator outBitmap = new RealBitmapGenerator(topLayer.Bitmap); foreach (var segment in scannerToplayer.GetSegmentsOfNet(netId)) { outBitmap.DrawSegment(segment, 100); } outBitmap.SaveTo(Path.Combine(path, $"Net_{netId}.png")); } File.WriteAllLines(path + ".html", GenerateHtml(path, GenerateNetLinks(scannerToplayer, path)), Encoding.UTF8); }
/// <summary> /// Loads the PNG bitmap contained by the file filename and returns it inside a <see cref="BitmapScanner"/> class. /// </summary> /// <param name="filename">Filename of the PNG file.</param> /// <returns>A <see cref="BitmapScanner"/> object containing the loaded bitmap.</returns> private static BitmapScanner LoadAndScan(string filename) { MonochromeBitmapAccessor layer = new MonochromeBitmapAccessor(filename); Console.WriteLine($"Loading {filename}"); var result = new BitmapScanner(layer); result.PrepareAll(); return(result); }
/// <summary> /// Loads and processes the PNG bitmaps containing the bitmaps representing the top, drill and bottom layers. /// It generates bitmaps containing the copper layers with each available net highlighted and an HTML file to easily /// show all the found nets. /// </summary> /// <param name="topLayerFilename">Filename of the PNG file containing the top copper layer.</param> /// <param name="drillLayerFilename">Filename of the PNG file containing the drill layer.</param> /// <param name="bottomLayerFilename">Filename of the PNG file containing the bottom copper layer.</param> /// <param name="path">name of the project output. This is the name of the folder where bitmaps will be stored and the html will be path.HTML.</param> /// <param name="doHoles">True if holes should be drawn on copper layers.</param> /// <param name="doMirror">True if the bottom layer should be mirrored in the output file produced.</param> public static void ProcessDoubleLayerWithDrill(string topLayerFilename, string drillLayerFilename, string bottomLayerFilename, string path, bool doHoles, bool doMirror) { if (!File.Exists(topLayerFilename)) { Console.WriteLine($"The top layer file {topLayerFilename} was not found"); return; } if (!File.Exists(drillLayerFilename)) { Console.WriteLine($"The drill layer file {topLayerFilename} was not found"); return; } if (!File.Exists(bottomLayerFilename)) { Console.WriteLine($"The bottom layer file {topLayerFilename} was not found"); return; } var top = LoadAndScan(topLayerFilename); var drill = LoadAndScan(drillLayerFilename); var bottom = LoadAndScan(bottomLayerFilename); MonochromeBitmapAccessor topLayer = new MonochromeBitmapAccessor(topLayerFilename); MonochromeBitmapAccessor bottomLayer = new MonochromeBitmapAccessor(bottomLayerFilename); MonochromeBitmapAccessor drillLayer = new MonochromeBitmapAccessor(drillLayerFilename); DrillScanner drillScanner = new DrillScanner(drill); DrillConnector connector = new DrillConnector(top, bottom, drillScanner); connector.ComputeGlobalNet(); Directory.CreateDirectory(path); if (doHoles) { MonochromeBitmapAccessor drillPlane = new MonochromeBitmapAccessor(drillLayerFilename); Bitmap bitmap = drillPlane.Bitmap; for (int x = 0; x < drillPlane.Width; x++) { for (int y = 0; y < drillPlane.Height; y++) { if (drillPlane.PixelAt(x, y)) { topLayer.Bitmap.SetPixel(x, y, System.Drawing.Color.Black); bottomLayer.Bitmap.SetPixel(x, y, System.Drawing.Color.Black); } } } } // Generates the bitmaps with the highlighted segments. // Bottom layer is mirrored foreach (int key in connector.GetNets()) { RealBitmapGenerator topBitmap = new RealBitmapGenerator(topLayer.Bitmap); RealBitmapGenerator bottomBitmap = new RealBitmapGenerator(bottomLayer.Bitmap); foreach (var layerNet in connector.GetLayerNetsOfNet(key)) { if (layerNet.LayerId == LayerNet.TOPLAYER) { foreach (var segment in top.GetSegmentsOfNet(layerNet.NetId)) { topBitmap.DrawSegment(segment, 100); } } else { foreach (var segment in bottom.GetSegmentsOfNet(layerNet.NetId)) { bottomBitmap.DrawSegment(segment, 100); } } } int margin = 20; Bitmap full = new Bitmap( topBitmap.Width + bottomBitmap.Width + margin, topBitmap.Height); Graphics gr = Graphics.FromImage(full); gr.DrawImage( topBitmap.GetBitmap(), 0, 0, topBitmap.Width, topBitmap.Height); var bottomImage = (Bitmap)bottomBitmap.GetBitmap().Clone(); if (doMirror) { bottomImage.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipX); } gr.DrawImage( bottomImage, topBitmap.Width + margin, 0); full.Save(Path.Combine(path, $"Net_{key}.png")); } var options = new List <string>(); int line = 1; foreach (int netId in connector.GetNets()) { options.Add($"<option value=\"{path}/Net_{line}.png\">Net_{line}</option>"); line++; } File.WriteAllLines(path + ".html", GenerateHtml(path, options), Encoding.UTF8); }