public bool[,] RenderImage(Bitmap img, IViewBoxModel view, IPannable offset, bool invert, double zoom) { //call pre hooks object cImg = img as object; 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) { using (Bitmap _img = img.Clone() as Bitmap) { try { 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) { } } } //call post hooks callAllPostHooks(view, img, ref m, offset, invert, zoom); //try { if (img != null) img.Dispose(); } //catch { } 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(); } } }