Exemple #1
0
        public void Dispose()
        {
            if (_isDisposed)
            {
                return;
            }

            Stop();

            _backgroundHandler?.Dispose();
            _captureListener?.Dispose();
            _imageAvailableListener?.Dispose();
            _imageReader?.Dispose();
            _bufferFrame?.Dispose();
            _isDisposed = true;
        }
Exemple #2
0
        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();
        }