public void Dispose() { if (_isDisposed) { return; } Stop(); _backgroundHandler?.Dispose(); _captureListener?.Dispose(); _imageAvailableListener?.Dispose(); _imageReader?.Dispose(); _bufferFrame?.Dispose(); _isDisposed = true; }
public void Generate() { if (InputFilePath == null) { throw new InvalidOperationException("Input file path is not specified."); } if (OutputDirPath == null) { throw new InvalidOperationException("Output directory path is not specified."); } if (ViewerCreation && BaseName == null) { throw new InvalidOperationException("Base name should be specified for viewer creation."); } var zoomLevels = new List <ZoomLevel>(); ImageReader reader = null; try { reader = ImageReader.Create(InputFilePath); var d = 1f; ZoomLevel zoomLevel; do { zoomLevel.ImageWidth = (int)((float)reader.Width / d); zoomLevel.ImageHeight = (int)((float)reader.Height / d); zoomLevel.GridWidth = (zoomLevel.ImageWidth + TileSize - 1) / TileSize; zoomLevel.GridHeight = (zoomLevel.ImageHeight + TileSize - 1) / TileSize; zoomLevels.Add(zoomLevel); tileTotal += zoomLevel.GridWidth * zoomLevel.GridHeight; d *= 2; } while (zoomLevel.ImageWidth > TileSize || zoomLevel.ImageHeight > TileSize); zoomLevels.Reverse(); if (ViewerCreation) { var bd = AppDomain.CurrentDomain.BaseDirectory; try { if (!Directory.Exists(OutputDirPath)) { Directory.CreateDirectory(OutputDirPath); } } catch (Exception e) { throw new IOException(String.Format("Can't create directory {0}.\r\n {1}", OutputDirPath, e.Message)); } File.Copy(Path.Combine(bd, ScriptFileName), Path.Combine(OutputDirPath, ScriptFileName), true); var viewer = File.ReadAllText(Path.Combine(bd, ViewerFileName)). Replace("{viewerwidth}", ViewerWidth.ToString()). Replace("{viewerheight}", ViewerHeight.ToString()). Replace("{imagewidth}", reader.Width.ToString()). Replace("{imageheight}", reader.Height.ToString()). Replace("{basename}", BaseName). Replace("{structure}", FileStructure.Replace("{ext}", GetTileFileExt())); if (TileSize != 256) { viewer = viewer.Replace("{tilesize}", TileSize.ToString()); } else { var r = new Regex(@"^.*{tilesize}.*\r\n", RegexOptions.Multiline); viewer = r.Replace(viewer, ""); } File.WriteAllText(Path.Combine(OutputDirPath, BaseName + ".htm"), viewer); } } finally { if (reader != null) { reader.Dispose(); } } tileProcessedTotal = 0; //Application can't have more than 2048 file handlers. //We can reach the limit with >~100 MP images for (int minTileIndex = 1; minTileIndex <= tileTotal; minTileIndex += MaxOpenFileCount) { int maxTileIndex = Math.Min(minTileIndex + MaxOpenFileCount - 1, tileTotal); int tileIndex = 0; //Store reference to all pipeline elements for further correct object disposing var pipelineElements = new List <PipelineElement>(); try { reader = ImageReader.Create(InputFilePath); pipelineElements.Add(reader); PipelineElement source; //Create progress tracker if (Progress != null) { var progress = new ProgressReporter(); progress.Progress += (s, e) => { OnProgress(e); }; pipelineElements.Add(progress); reader.Receivers.Add(progress); source = progress; } else { source = reader; } for (int zoom = 0; zoom < zoomLevels.Count; zoom++) { PipelineElement resize; if (zoom == zoomLevels.Count) { resize = source; } else { resize = new Resize(zoomLevels[zoom].ImageWidth, zoomLevels[zoom].ImageHeight, ResizeInterpolationMode.Anisotropic9); pipelineElements.Add(resize); source.Receivers.Add(resize); } for (int tileX = 0; tileX < zoomLevels[zoom].GridWidth; tileX++) { for (int tileY = 0; tileY < zoomLevels[zoom].GridHeight; tileY++) { tileIndex++; if (tileIndex < minTileIndex) { continue; } int x = tileX * TileSize; int y = tileY * TileSize; int width = Math.Min((tileX + 1) * TileSize, zoomLevels[zoom].ImageWidth) - x; int height = Math.Min((tileY + 1) * TileSize, zoomLevels[zoom].ImageHeight) - y; var crop = new Crop(x, y, width, height); pipelineElements.Add(crop); resize.Receivers.Add(crop); var outputFilePath = Path.Combine(GetTileOutputDirPath(), String.Format(GetFileStructureFormat(), zoom, tileX, tileY, GetTileFileExt())); var p = Path.GetDirectoryName(outputFilePath); try { if (!Directory.Exists(p)) { Directory.CreateDirectory(p); } } catch (Exception e) { throw new IOException(String.Format("Can't create directory {0}.\r\n {1}", p, e.Message)); } ImageWriter writer; switch (TileImageFormat) { case TileImageFormat.PNG: writer = new PngWriter(outputFilePath); break; default: writer = new JpegWriter(outputFilePath, TileJpegQuality); break; } pipelineElements.Add(writer); crop.Receivers.Add(writer); if (tileIndex == maxTileIndex) { //Remove resize elements without crop receivers for (var l = source.Receivers.Count - 1; l >= 0; l--) { if (source.Receivers[l].Receivers.Count == 0) { source.Receivers.RemoveAt(l); } } Pipeline.Run(reader); tileProcessedTotal = maxTileIndex; goto LoopOut; } } } } LoopOut: ; } finally { for (var i = 0; i < pipelineElements.Count; i++) { pipelineElements[i].Dispose(); } } } }
public override void Apply(ref Bitmap bitmap, out Highlighter[] highlightersOut) { // Make a copy of the bitmap filtered with the Difference filter Bitmap differenceBitmap = new Bitmap(bitmap); var filter = new Images.Filters.FilterDifference(); Highlighter[] temp; filter.Apply(ref differenceBitmap, out temp); // Analyse gridlines ImageReader reader = new ImageReader(ref bitmap); ImageReader differenceReader = new ImageReader(ref differenceBitmap); List <Highlighter> highlighters = new List <Highlighter>(); int numHorizontalDivisions = bitmap.Width / gridInterval, numVerticalDivisions = bitmap.Height / gridInterval; List <EdgePoint>[] horizontalEdges = new List <EdgePoint> [numVerticalDivisions]; List <EdgePoint>[] verticalEdges = new List <EdgePoint> [numHorizontalDivisions]; // Verticals for (int tileX = 0; tileX < bitmap.Width / gridInterval * gridInterval; tileX += gridInterval) { FindEdgesOnLine(ref reader, ref differenceReader, out verticalEdges[tileX / gridInterval], new Point(tileX, 0), 0, 1); } // Horizontals for (int tileY = 0; tileY < bitmap.Height / gridInterval * gridInterval; tileY += gridInterval) { FindEdgesOnLine(ref reader, ref differenceReader, out horizontalEdges[tileY / gridInterval], new Point(0, tileY), 0, 1); } // Debug: highlight the edges foreach (List <EdgePoint> edgeList in verticalEdges) { foreach (EdgePoint edge in edgeList) // ow the edge { // ow the edge highlighters.Add(new PointHighlighter(edge.X, edge.Y)); highlighters.Add(new PointHighlighter(edge.SegmentCentre.X, edge.SegmentCentre.Y) { Pen = new Pen(Color.Orange) }); // add a line too if (edge.LastPoint != null) { highlighters.Add(new EdgeHighlighter(new Point(edge.LastPoint.X, edge.LastPoint.Y), new Point(edge.X, edge.Y)) { Pen = new Pen(edge.AverageSegmentColour, 2.0f) }); } } } // Connect the edge points ConnectEdgePoints(verticalEdges, highlighters); // Add a grid highlighter representing the grid we checked GridHighlighter grid = new GridHighlighter(new Rectangle(0, 0, bitmap.Width, bitmap.Height), gridInterval); grid.Pen.Width = 1; grid.Pen.Color = Color.Gray; //highlighters.Add(grid); // Complete the highlighter array highlightersOut = highlighters.ToArray(); // Release resources reader.Dispose(); }