/// <summary> /// Sets the unscaled image and draws it with the current zoom level and focus point settings. /// </summary> /// <param name="b">Bitmap to set display image to.</param> public void SetImage(Bitmap b) { Bitmap currentImage = (Bitmap)this.DisplayImageBox.Image; // obtain semaphore control before changing the image ctrlSem.WaitOne(); unscaledImage = b; ctrlSem.Release(); // attempt to draw the image try { DrawImage(); } catch (Exception inner) { log.Error("ZoomImageBox.SetImage : Unable to set and draw image.", inner); ZoomImageBoxException ex = new ZoomImageBoxException("ZoomImageBox.SetImage : Unable to set and draw image.", inner); throw ex; } if (currentImage != null) { currentImage.Dispose(); } }
/// <summary> /// Zooms out on unscaled image at point p. /// </summary> /// <param name="p">Point on unscaled image to focus on.</param> public void ZoomOut(Point p) { // verify image can zoom out if (zoomlvl - 1 < ZOOM_MIN) { log.Error("ZoomImageBox.ZoomOut : Cannot zoom out any further."); ZoomImageBoxException ex = new ZoomImageBoxException("ZoomImageBox.ZoomOut : Cannot zoom out any further."); throw ex; } // update the zoom lvl and focus point ctrlSem.WaitOne(); zoomlvl--; focusPoint = new Point(p.X + displayImageOffset.X, p.Y + displayImageOffset.Y); ctrlSem.Release(); // attempt to draw the image to DisplayImage try { DrawImage(); } catch (Exception inner) { log.Error("ZoomImageBox.ZoomOut : Exception thrown drawing image.", inner); ZoomImageBoxException ex = new ZoomImageBoxException("ZoomImageBox.ZoomOut : Exception thrown drawing image.", inner); throw ex; } }
/// <summary> /// Draws the image stored in unscaled image and scales it into the scaled image. /// </summary> private void DrawImage() { // we dont want settings changed while drawing image ctrlSem.WaitOne(); // make sure unscaled image is not null if (unscaledImage == null) { log.Error("ZoomImageBox.DrawImage : Unscaled image is null, cannot draw zoomed image."); ZoomImageBoxException ex = new ZoomImageBoxException("ZoomImageBox.DrawImage : Unscaled image is null, cannot draw zoomed image."); ctrlSem.Release(); throw ex; } // store portion to draw in mem bitmap Bitmap buffer; // size the image wants to be int desiredImageWidth; int desiredImageHeight; // check to see what desired image size is try { desiredImageWidth = Convert.ToInt32(unscaledImage.Width * Math.Pow(2, zoomlvl)); desiredImageHeight = Convert.ToInt32(unscaledImage.Height * Math.Pow(2, zoomlvl)); } catch (Exception inner) { log.Error("ZoomImageBox.DrawImage : Error obtaining desired image width/height.", inner); ZoomImageBoxException ex = new ZoomImageBoxException("ZoomImageBox.DrawImage : Error obtaining desired image width/height.", inner); ctrlSem.Release(); throw ex; } // grab requested output size int requestedOutputWidth = DisplayImageBox.Width; int requestedOutputHeight = DisplayImageBox.Height; // create the scaled bitmap, just size at this point if (desiredImageWidth > requestedOutputWidth || desiredImageHeight > requestedOutputHeight) { int outputWidth; int outputHeight; // get image width to set if (desiredImageWidth > requestedOutputWidth) { outputWidth = requestedOutputWidth; } else { outputWidth = desiredImageWidth; } // get image height to set if (desiredImageHeight > requestedOutputHeight) { outputHeight = requestedOutputHeight; } else { outputHeight = desiredImageHeight; } // use the requested size by user form try { scaledImage = new Bitmap(outputWidth, outputHeight); } catch (Exception inner) { log.Error("ZoomImageBox.DrawImage : Unable to create scaledImage Bitmap.", inner); ZoomImageBoxException ex = new ZoomImageBoxException("ZoomImageBox.DrawImage : Unable to create scaledImage Bitmap.", inner); ctrlSem.Release(); throw ex; } Point requestedFocusPoint = focusPoint; // create a cropping rectanble around the focus point in terms of original unscaled image Rectangle cropRectangle = new Rectangle( Convert.ToInt32(focusPoint.X - outputWidth / 2 / Math.Pow(2, zoomlvl)), Convert.ToInt32(focusPoint.Y - outputHeight / 2 / Math.Pow(2, zoomlvl)), Convert.ToInt32(outputWidth / Math.Pow(2, zoomlvl)), Convert.ToInt32(outputHeight / Math.Pow(2, zoomlvl)) ); // verify cropping rectangle is within unscaledBitmap's width and height // check left side if (cropRectangle.X < 0) { cropRectangle.X = 0; if (cropRectangle.Right > unscaledImage.Width) { cropRectangle.Width = unscaledImage.Width; } } // check top side if (cropRectangle.Y < 0) { cropRectangle.Y = 0; if (cropRectangle.Bottom > unscaledImage.Height) { cropRectangle.Height = unscaledImage.Height; } } // check right side if (cropRectangle.Right > unscaledImage.Width) { cropRectangle.X -= cropRectangle.Right - unscaledImage.Width; if (cropRectangle.X < 0) { cropRectangle.X = 0; cropRectangle.Width = unscaledImage.Width; } } // check bottom side if (cropRectangle.Bottom > unscaledImage.Height) { cropRectangle.Y -= cropRectangle.Bottom - unscaledImage.Height; if (cropRectangle.Y < 0) { cropRectangle.Y = 0; cropRectangle.Height = unscaledImage.Height; } } // set the top left coordinate to copy image from displayImageOffset = new Point(cropRectangle.X, cropRectangle.Y); // try to get the cropped image try { buffer = unscaledImage.Clone(cropRectangle, unscaledImage.PixelFormat); //buffer.Save("Image.bmp"); } catch (Exception inner) { log.Error("ZoomImageBox.DrawImage : Unable to draw scaled image.", inner); ZoomImageBoxException ex = new ZoomImageBoxException("ZoomImageBox.DrawImage : Unable to draw scaled image.", inner); ctrlSem.Release(); throw ex; } } else { // use size dictated by zoom lvl, this is smaller than requested size displayImageOffset = new Point(0, 0); try { scaledImage = new Bitmap(desiredImageWidth, desiredImageHeight); } catch (Exception inner) { log.Error("ZoomImageBox.DrawImage : Unable to draw scaled image.", inner); ZoomImageBoxException ex = new ZoomImageBoxException("ZoomImageBox.DrawImage : Unable to draw scaled image.", inner); ctrlSem.Release(); throw ex; } buffer = unscaledImage; } // apply gain to the image float displayGain = 1.0f; float[][] matrix = { new float[] { displayGain, 0, 0, 0, 0 }, new float[] { 0, displayGain, 0, 0, 0 }, new float[] { 0, 0, displayGain, 0, 0 }, new float[] { 0, 0, 0, displayGain, 0 }, new float[] { 0, 0, 0, 0, 1 } }; ColorMatrix colorMatrix = new ColorMatrix(matrix); ImageAttributes imageAttr = new ImageAttributes(); imageAttr.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); // make the scaled bitmap Graphics g; try { g = Graphics.FromImage(scaledImage); } catch (Exception inner) { log.Error("ZoomImageBox.DrawImage : Unable to get graphics handle for scaled image.", inner); ZoomImageBoxException ex = new ZoomImageBoxException("ZoomImageBox.DrawImage : Unable to get graphics handle for scaled image.", inner); ctrlSem.Release(); throw ex; } // grab the nearest pixel for color g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; try { g.DrawImage(buffer, new Rectangle(0, 0, scaledImage.Width, scaledImage.Height), 0, 0, buffer.Width, buffer.Height, GraphicsUnit.Pixel, imageAttr); } catch (Exception inner) { log.Error("ZoomImageBox.DrawImage : Exception redrawing scaled image.", inner); ZoomImageBoxException ex = new ZoomImageBoxException("ZoomImageBox.DrawImage : Exception redrawing scaled image.", inner); ctrlSem.Release(); throw ex; } // Draw the region of intereset on box if (regionToProcess_scaled != Rectangle.Empty) { try { Brush b = new SolidBrush(Color.Red); Pen p = new Pen(b); /// Math.Pow(2, zoomlvl) //int startX = int xStart = Convert.ToInt32(regionToProcess_scaled.Left * Math.Pow(2, zoomlvl)); int yStart = Convert.ToInt32(regionToProcess_scaled.Top * Math.Pow(2, zoomlvl)); int xEnd = Convert.ToInt32(regionToProcess_scaled.Right * Math.Pow(2, zoomlvl)); int yEnd = Convert.ToInt32(regionToProcess_scaled.Bottom * Math.Pow(2, zoomlvl)); Rectangle r = new Rectangle(xStart, yStart, xEnd - xStart, yEnd - yStart); g.DrawRectangle(p, r); } catch (Exception) { throw; } } // dispose graphics ~ avoids memory leak g.Dispose(); // update the image shown on ZoomImageBox control DisplayImageBox.Image = scaledImage; ctrlSem.Release(); }