/* * ImageView.cs * * CMSC 498B, Spring 2002, Project #1 * -- A C# program that displays all GIF/JPEG images found in a directory along with their names. * * Bongshin Lee, February 2002 */ using System; using System.IO; using System.Collections; using System.Drawing; using System.Windows.Forms; using System.Security; using System.Security.Permissions; public class ImageView : Form { VScrollBar vScroll; // vertical scrollbar ImageComponent iComponent; // a control to draw images // default box & pad size static int boxSize = 150; static int padSize = 15; static public void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("Usage: ImageView imageDir [boxSize] [padSize]"); } else { // parse input parameters if (args.Length > 1) { boxSize = int.Parse(args[1]); if (args.Length > 2) padSize = int.Parse(args[2]); } DirectoryInfo dir = new DirectoryInfo(args[0]); // check whether the specified directory exists if (dir.Exists) { Application.Run(new ImageView(dir)); } else { Console.WriteLine(args[0] + " is an invalid directory."); } } } public ImageView(DirectoryInfo dir) { Text = "CMSC 498B Project #1 - ImageView"; // set the title of the form iComponent = new ImageComponent(this, dir, boxSize, padSize); iComponent.Size = new Size(500, 500); // add a listener to Resize event Resize += new EventHandler(ResizeEventHandler); vScroll = new VScrollBar(); vScroll.Dock = DockStyle.Right; // add a listener to ValueChanged event of the vertical scrollbar vScroll.ValueChanged += new EventHandler(VChangedEventHandler); // form width = iComponent width + scrollbar width ClientSize = new Size(500 + vScroll.Width, 500); // add image component & scrollbar to the form Controls.Add(iComponent); Controls.Add(vScroll); } // show/hide vertical scrollbar public void ShowVScroll(Boolean show) { vScroll.Visible = show; // recompute the size of ImageComponent if (show) iComponent.Width = ClientSize.Width - vScroll.Width; else iComponent.Width = ClientSize.Width; iComponent.Height = ClientSize.Height; } // event handler for Resize event public void ResizeEventHandler(object sender, EventArgs e) { // the size of form has changed vScroll.Value = 0; // initialize the position of scrollbar // compute the size of ImageComponent if (vScroll.Visible) iComponent.Width = ClientSize.Width - vScroll.Width; else iComponent.Width = ClientSize.Width; iComponent.Height = ClientSize.Height; // relayout & redraw images on ImageComponent iComponent.ReLayout(); iComponent.Invalidate(); } // event handler for ValueChanged event public void VChangedEventHandler(object sender, EventArgs e) { // the value of scrollbar has changed iComponent.SetScrollValue(vScroll.Value); // redraw images iComponent.Invalidate(); } // set the (control) values for vertical scrollbar public void SetScrollValues(int extent, int maximum) { vScroll.Minimum = 0; vScroll.Maximum = maximum; vScroll.LargeChange = extent; } } class ImageComponent : Control { ImageView parent; // container of this ImageComponent Array images; // stores all images Array names; // stores all image file names static Font font = new Font("Helvetica", 10); // font to display file name static SolidBrush lgBrush = new SolidBrush(Color.LightGray); // brush for light gray border static SolidBrush bBrush = new SolidBrush(Color.Black); // brush for black file name int perRow; // # of images per row int actualHeight; // height to display all images int scrollValue = 0; // current position of the vertical scrollbar int boxSize, padSize; // box & pad size Boolean vScrollShow = true; // visibility of the vertical scrollbar public ImageComponent(ImageView iv, DirectoryInfo baseDir, int box, int pad) { parent = iv; // remember the container of this ImageComponent boxSize = box + 6; // boxSize includes the gray border padSize = pad; // search all images in the specified directory SearchImages(baseDir); // turn on double buffering and some bits that tell .NET that // this control is being painted manually - this improves performance. SetStyle(System.Windows.Forms.ControlStyles.UserPaint, true); SetStyle(System.Windows.Forms.ControlStyles.DoubleBuffer, true); SetStyle(System.Windows.Forms.ControlStyles.AllPaintingInWmPaint, true); } public void SetScrollValue(int sValue) { scrollValue = sValue; } // calculate height to display all images // based on the # of images and current width public void CalcHeight() { perRow = Width / (boxSize + 2 * padSize); // # of images per row if (perRow == 0) perRow = 1; // min # of images per row is 1 int rows = images.Length / perRow; // # of rows to display all images if (images.Length == rows * perRow) actualHeight = rows * (boxSize + 2 * padSize + font.Height); else actualHeight = (rows + 1) * (boxSize + 2 * padSize + font.Height); } public void ReLayout() { CalcHeight(); if (actualHeight > Height) { if (!vScrollShow) { // if scrollbar is needed but now shown before // we have to show scrollbar parent.ShowVScroll(true); vScrollShow = true; CalcHeight(); } } else { if (vScrollShow) { // if scrollbar is not needed but shown before // we have to hide scrollbar parent.ShowVScroll(false); vScrollShow = false; CalcHeight(); } } // set values for vertical scrollbar parent.SetScrollValues(Height, actualHeight); } // search all image files in a directory private void SearchImages(DirectoryInfo baseDir) { FileInfo[] files = baseDir.GetFiles(); Queue imageQ = new Queue(); Queue nameQ = new Queue(); foreach (FileInfo fi in files) { // check the file is image file based on the extension String lowerName = fi.Name.ToLower(); if (lowerName.EndsWith(".jpg") || lowerName.EndsWith(".gif") || lowerName.EndsWith(".jpeg")) { Image img = Image.FromFile(fi.FullName); // load image if (img != null) { imageQ.Enqueue(img); nameQ.Enqueue(fi.Name); } } } // store images and file names to Array images = imageQ.ToArray(); names = nameQ.ToArray(); } protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; BackColor = Color.White; // white background if (images.Length == 0) return; // we don't have anything to draw // the minimum row number to be shown in current viewport int startRow = scrollValue / (boxSize + 2 * padSize + font.Height); // the maximum row number to be shown in current viewport int endRow = (scrollValue + Height) / (boxSize + 2 * padSize + font.Height); int n = startRow * perRow; // the index of image to be shown first for (int i = startRow; i < endRow + 1; i++) { for (int j = 0; j < perRow; j++) { // draw 3pixel lightgray border using rectangle int left = j * (boxSize + 2 * padSize) + padSize; int right = left + boxSize; int top = i * (boxSize + 2 * padSize + font.Height) + padSize - scrollValue; int bottom = top + boxSize; g.FillRectangle(lgBrush, left, top, boxSize, 3); // upper line g.FillRectangle(lgBrush, left, top, 3, boxSize); // left line g.FillRectangle(lgBrush, right - 3, top, 3, boxSize); // right line g.FillRectangle(lgBrush, left, bottom - 3, boxSize, 3); // bottom line Image img = (Image)images.GetValue(n); // calculate scaled image size int width = boxSize - 6; int height = boxSize - 6; int imgWidth = img.Width; int imgHeight = img.Height; double ratio = (double)imgWidth / imgHeight; if (ratio > 1) { height = width * imgHeight / imgWidth; // wide and short } else if (ratio < 1) { width = height * imgWidth / imgHeight; // thin and long } // draw n scaled image at the center of the box g.DrawImage(img, left + (boxSize - width) / 2, top + (boxSize - height) / 2, width, height); // draw the file name centered, immediately below the gray bordered box String fileName = (String)names.GetValue(n++); SizeF nameSize = g.MeasureString(fileName, font); // size of the file name string g.DrawString(fileName, font, bBrush, left + (boxSize - nameSize.Width) / 2, bottom); if (n == images.Length) return; // end of images } } } }