Beispiel #1
0
        /// <summary>
        /// Renders the image.
        /// </summary>
        /// <param name="img">The image.</param>
        /// <param name="view">The view.</param>
        /// <param name="offset">The offset for translation.</param>
        /// <param name="invert">if set to <c>true</c>  the result will be inverted.</param>
        /// <param name="zoom">The zoom factor.</param>
        /// <param name="callHooks">if set to <c>true</c> per- and post renderer hooks  are called.</param>
        /// <returns>
        /// a bool matrix
        /// </returns>
        /// <exception cref="System.ArgumentException">
        /// The zoom level is with a value of  + zoom + to high. The zoom level should not be more than 3.;zoom
        /// or
        /// The zoom level is with a value of  + zoom + to low. The zoom level should be between 0 and 3.;zoom
        /// </exception>
        public bool[,] RenderImage(Bitmap img, IViewBoxModel view, IPannable offset, bool invert, double zoom, bool callHooks = true)
        {
            //call pre hooks
            object cImg = img as object;

            if (callHooks)
            {
                callAllPreHooks(ref view, ref cImg, offset, invert, zoom);
            }
            img = cImg as Bitmap;

            if (zoom > 3)
            {
                throw new ArgumentException("The zoom level is with a value of " + zoom + "to high. The zoom level should not be more than 3.", "zoom");
            }
            if (zoom < 0)
            {
                throw new ArgumentException("The zoom level is with a value of " + zoom + "to low. The zoom level should be between 0 and 3.", "zoom");
            }

            if (view == null)
            {
                return(new bool[0, 0]);
            }
            //TODO: bring in threshold here
            //TODO: check how to get the threshold
            Rectangle viewRange    = view.ContentBox;
            int       matrixWidth  = viewRange.Width;
            int       matrixHeight = viewRange.Height;

            bool[,] m = new bool[matrixHeight, matrixWidth];

            int offsetX = 0;
            int offsetY = 0;

            if (offset != null && zoom > 0)
            {
                offsetX = offset.GetXOffset();
                offsetY = offset.GetYOffset();

                offsetX = (Int32)Math.Round(offsetX / zoom);
                offsetY = (Int32)Math.Round(offsetY / zoom);
            }
            if (img != null)
            {
                try
                {
                    using (Bitmap _img = img.Clone() as Bitmap)
                    {
                        Int32 contentWidth  = (Int32)Math.Max(Math.Round(_img.Width * zoom), 1);
                        Int32 contentHeight = (Int32)Math.Max(Math.Round(_img.Height * zoom), 1);
                        //set the content size fields in the view.
                        view.ContentHeight = contentHeight;
                        view.ContentWidth  = contentWidth;

                        double vrZoom = zoom > 0 ? (double)1 / zoom : 0;

                        Int32 zoomedVrWidth  = (Int32)Math.Max(Math.Round(matrixWidth * vrZoom), 1);
                        Int32 zoomedVrHeight = (Int32)Math.Max(Math.Round(matrixHeight * vrZoom), 1);

                        int imgWidth = Math.Min(zoomedVrWidth, _img.Width);
                        int imgHeiht = Math.Min(zoomedVrHeight, _img.Height);

                        using (Bitmap viewRangeImage = new Bitmap(matrixWidth, matrixHeight))
                        {
                            try
                            {
                                using (Graphics grMatrix = Graphics.FromImage(viewRangeImage))
                                {
                                    // good results with a Threshold of 210 but smooths the edges
                                    grMatrix.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low;
                                    grMatrix.PixelOffsetMode   = System.Drawing.Drawing2D.PixelOffsetMode.HighSpeed;

                                    grMatrix.SmoothingMode      = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
                                    grMatrix.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;

                                    Rectangle sourceRectangle = new Rectangle(offsetX * -1, offsetY * -1, zoomedVrWidth, zoomedVrHeight);
                                    Rectangle destRectangle1  = new Rectangle(0, 0, matrixWidth, matrixHeight);

                                    grMatrix.FillRectangle(Brushes.White, destRectangle1);
                                    grMatrix.DrawImage(_img, destRectangle1, sourceRectangle, GraphicsUnit.Pixel);
                                }
                            }
                            catch { }

                            if (viewRangeImage != null)
                            {
                                using (LockBitmap lockBitmap = new LockBitmap(viewRangeImage))
                                {
                                    lockBitmap.LockBits();

                                    int rw = lockBitmap.Width;
                                    int rh = lockBitmap.Height;

                                    System.Threading.Tasks.Parallel.For(0, matrixWidth, x =>
                                    {
                                        System.Threading.Tasks.Parallel.For(0, matrixHeight, y =>
                                        {
                                            int cX = x;
                                            if (cX >= 0)
                                            {
                                                int cY = y;
                                                if (cY >= 0)
                                                {
                                                    if (x < rw && y < rh)
                                                    {
                                                        Color c   = lockBitmap.GetPixel(x, y);
                                                        var l     = GraphicUtils.GetLightness(c);
                                                        m[cY, cX] = (l >= Threshold) ?
                                                                    (invert ? true : false)
                                                            :
                                                                    (invert ? false : true);
                                                    }
                                                }
                                            }
                                        });
                                    });
                                }
                            }
                        }
                    }
                }
                catch (ArgumentException) { }
                catch (InvalidOperationException) { }
            }
            //call post hooks
            if (callHooks)
            {
                callAllPostHooks(view, img, ref m, offset, invert, zoom);
            }
            return(m);
        }
        /// <summary>
        /// Renders the image.
        /// </summary>
        /// <param name="img">The image.</param>
        /// <param name="view">The view.</param>
        /// <param name="offset">The offset for translation.</param>
        /// <param name="invert">if set to <c>true</c>  the result will be inverted.</param>
        /// <param name="zoom">The zoom factor.</param>
        /// <param name="callHooks">if set to <c>true</c> per- and post renderer hooks  are called.</param>
        /// <returns>
        /// a bool matrix
        /// </returns>
        /// <exception cref="System.ArgumentException">
        /// The zoom level is with a value of  + zoom + to high. The zoom level should not be more than 3.;zoom
        /// or
        /// The zoom level is with a value of  + zoom + to low. The zoom level should be between 0 and 3.;zoom
        /// </exception>
        public bool[,] RenderImage(Bitmap img, IViewBoxModel view, IPannable offset, bool invert, double zoom, bool callHooks = true)
        {
            try
            {
                //call pre hooks
                object cImg = img as object;
                if (callHooks)
                {
                    callAllPreHooks(ref view, ref cImg, offset, invert, zoom);
                }
                img = cImg as Bitmap;

                bool[,] m = new bool[0, 0];

                if (view != null && img != null &&
                    img.PixelFormat != PixelFormat.Undefined && img.PixelFormat != PixelFormat.DontCare)
                {
                    //System.Diagnostics.Debug.WriteLine("\t\t\t--- pixel format: " + img.PixelFormat);

                    try
                    {
                        Bitmap _img = null;
                        int    trys = 0;
                        while (_img == null && trys++ < 4)
                        {
                            try
                            {
                                _img = img.Clone() as Bitmap;
                            }
                            catch
                            {
                                if (img.PixelFormat == PixelFormat.DontCare)
                                {
                                    return(m);
                                }
                                System.Threading.Thread.Sleep(2);
                            }
                        }

                        //TODO: bring in threshold here
                        //TODO: check how to get the threshold
                        Rectangle viewRange    = view.ContentBox;
                        int       matrixWidth  = viewRange.Width;
                        int       matrixHeight = viewRange.Height;

                        m = new bool[matrixHeight, matrixWidth];

                        int offsetX = 0;
                        int offsetY = 0;
                        if (offset != null && zoom > 0)
                        {
                            offsetX = offset.GetXOffset();
                            offsetY = offset.GetYOffset();

                            offsetX = (Int32)Math.Round(offsetX / zoom);
                            offsetY = (Int32)Math.Round(offsetY / zoom);
                        }

                        if (_img != null)
                        //using (Bitmap _img = img.Clone() as Bitmap)
                        {
                            // Fix zoom -1 = fit to available space
                            //if (zoom > 3) throw new ArgumentException("The zoom level is with a value of " + zoom + "to high. The zoom level should not be more than 3.", "zoom");
                            if (zoom < 0)
                            {
                                var Bounds = _img.Size;
                                zoom = Math.Min(
                                    view.ContentBox.Height / (double)Bounds.Height + 0.000000001,
                                    view.ContentBox.Width / (double)Bounds.Width + 0.000000001
                                    );
                                ((IZoomable)view).SetZoom(zoom);

                                //  throw new ArgumentException("The zoom level is with a value of " + zoom + "to low. The zoom level should be between 0 and 3.", "zoom");
                            }

                            Int32 contentWidth  = (Int32)Math.Max(Math.Round(_img.Width * zoom), 1);
                            Int32 contentHeight = (Int32)Math.Max(Math.Round(_img.Height * zoom), 1);
                            //set the content size fields in the view.
                            view.ContentHeight = contentHeight;
                            view.ContentWidth  = contentWidth;

                            double vrZoom = zoom > 0 ? 1 / zoom : 0;

                            Int32 zoomedVrWidth  = (Int32)Math.Max(Math.Round(matrixWidth * vrZoom), 1);
                            Int32 zoomedVrHeight = (Int32)Math.Max(Math.Round(matrixHeight * vrZoom), 1);

                            int imgWidth = Math.Min(zoomedVrWidth, _img.Width);
                            int imgHeiht = Math.Min(zoomedVrHeight, _img.Height);

                            using (Bitmap viewRangeImage = new Bitmap(matrixWidth, matrixHeight))
                            {
                                try
                                {
                                    using (Graphics grMatrix = Graphics.FromImage(viewRangeImage))
                                    {
                                        // good results with a Threshold of 210 but smooths the edges
                                        grMatrix.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low;
                                        grMatrix.PixelOffsetMode   = System.Drawing.Drawing2D.PixelOffsetMode.HighSpeed;

                                        grMatrix.SmoothingMode      = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
                                        grMatrix.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;

                                        Rectangle sourceRectangle = new Rectangle(offsetX * -1, offsetY * -1, zoomedVrWidth, zoomedVrHeight);
                                        Rectangle destRectangle1  = new Rectangle(0, 0, matrixWidth, matrixHeight);

                                        grMatrix.FillRectangle(Brushes.White, destRectangle1);
                                        grMatrix.DrawImage(_img, destRectangle1, sourceRectangle, GraphicsUnit.Pixel);
                                    }
                                }
                                catch { }

                                if (viewRangeImage != null)
                                {
                                    using (LockBitmap lockBitmap = new LockBitmap(viewRangeImage))
                                    {
                                        lockBitmap.LockBits();

                                        int rw = lockBitmap.Width;
                                        int rh = lockBitmap.Height;

                                        //for (int y = 0; y < matrixHeight; y++)
                                        System.Threading.Tasks.Parallel.For(0, matrixHeight, y =>
                                        {
                                            //System.Threading.Tasks.Parallel.For(0, matrixWidth, x =>
                                            for (int x = 0; x < matrixWidth; x++)
                                            {
                                                //int cX = x;
                                                if (x >= 0)
                                                {
                                                    //int cY = y;
                                                    if (y >= 0)
                                                    {
                                                        if (x < rw && y < rh)
                                                        {
                                                            Color c = lockBitmap.GetPixel(x, y);
                                                            var l   = GraphicUtils.GetLightness(c);
                                                            m[y, x] = (l >= Threshold) ?
                                                                      (invert ? true : false)
                                                                :
                                                                      (invert ? false : true);
                                                        }
                                                    }
                                                }
                                            }//);
                                        });
                                    }
                                }
                            }

                            _img.Dispose();
                        }
                        else
                        {
                        }
                    }
                    catch (ArgumentException) { }
                    catch (InvalidOperationException) { }
                }

                //call post hooks
                if (callHooks)
                {
                    callAllPostHooks(view, img, ref m, offset, invert, zoom);
                }

                return(m);
            }
            finally
            {
                if (img != null)
                {
                    img.Dispose();
                }
            }
        }