( Index )
Month

 

Brief Information about the October '16 CSIG Meeting

FotoApp.EXE - An application to reduce the size of photos.  Part 2.

by Bruce Arnold

 

Photo Screen Shot

About Box

Welcome to the CSIG, a Special Interest Group of the ACGNJ. This is an exciting time for the C Language programming since Microsoft now has 4 different language compilers: C++, C++ Express, C-Sharp, and C-Sharp Express. These are all capable of creating Windows (tm) programs. (Some are FREE!)  During the meeting there will be time for Random Access Questions as well as other discussions. Since this is a complex subject, the presentation will continue during the October meeting.

Here's a brief synopsis of the coming meeting:

Last month we discussed the basics of the program, especially the graphics functions needed to convert the photographs or jpg files. This month routines or procedures and menus will be added to do batch processing. In a typical scenario you have just arrived home from a vacation, etc. and you have a hundred or more photos to convert. After specifying the source folder and the destination folder, just hit the "Process Now" option in the menu. The functions that were used to create a single new photo are now used inside a loop to process hundreds of photos. This involves about 6 major procedures and a few minor ones. An added bonus will be a slide show if you just want to watch.

Last month at the end of the meeting I tried unsuccessfully to quickly add a "Tool Strip" at the bottom of the display in order to show extra information.  Code for this will be presented. Finally, we will discuss a Microsoft Bug in the method FolderBrowserDialog(). When the user creates a new folder with with a given name, the method returns the wrong name.  This bug has been around since Windows XP and is still present in Windows 10.  I will present my own imperfect workaround for the bug and I challenge everyone to do better.

[From last month] The object of this program is described above in the sample display. This month's program uses Microsoft DOT NET C# code (CLI) to create a Windows Forms Application.  The Forms Class created contains about 10 methods that we will discuss in detail.  Some methods have simple mathematical calculations.  Others involve the graphics call necessary to produce the photo shown above.  And, of course, the method to reduce the size of the photo is there too.  Source code is available as well as an execuitable.

The program uses some of the most sophisticated Dot Net Library functions including the following:

using System
using System.Drawing
using System.Windows.Forms

MessageBox.Show()
OpenFileDialog()
System.Windows.Forms.DialogResult.OK
Image.Dispose()
Image.FromFile()
Image.GetPropertyItem(EXIF_JPG_ROTATION)
Image.RotateFlip(RotateFlipType.Rotate90FlipNone)
Image.Save()
pictureBox1.Image
Bitmap(target_width, target_height)
Graphics.FromImage();
DrawImage()
String.Format()
Close()
System.IO.File.Exists()
Enviornment.GetFolderPath()
FolderBrowserDialog()


There are a number of ways to refer to Microsoft's latest compilers and code. Here's what Wikipedia says: The Common Language Infrastructure (CLI) is an open specification developed by Microsoft that describes the executable code and runtime environment that form the core of the Microsoft .NET Framework. The specification defines an environment that allows multiple high-level languages to be used on different computer platforms without being rewritten for specific architectures.

Microsoft .Net Framework 4.5
C++ / C#
Visual Studio Community 2015
CLI
Common Language Infrastructure
Managed

Sample Code

        /* **********             OPEN  PICTURE  FILE                    ********** */
        // --------------------------------------------------------------------
        const int EXIF_JPG_ROTATION = 274;
        const int CLOCKWISE_ROTATION = 6;

        private void OpenToolStripMenuItem_Click(object sender, EventArgs e)
            {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "Photo files(*.JPG)|*.JPG|All files(*.*)|*.*";
            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                SourceFile = dlg.FileName;
                SourceFileBase = System.IO.Path.ChangeExtension(SourceFile, null);
                }
            else
                return;
            if (pictureBox1.Image != null) pictureBox1.Image.Dispose();
            splash.Visible = false;
            label1.Visible = false;
            Ready_to_Save = false;
            try
                {
                pictureBox1.Image = Image.FromFile(SourceFile);
                }
            catch                       // bad file
                {
                MessageBox.Show("Error Reading Image File", "Error");
                ShowStatus(0, 0);
                return;
                }
            int rotation = 0;
            try
                {
                rotation = pictureBox1.Image.GetPropertyItem(EXIF_JPG_ROTATION).Value[0];
                }
            catch   // no support available.
                {
                rotation = 0;
                }
            if (rotation == CLOCKWISE_ROTATION)
                {
                pictureBox1.Image.RotateFlip(RotateFlipType.Rotate90FlipNone);
                }
            ShowStatus(pictureBox1.Image.Width, pictureBox1.Image.Height);
            }


        /* **********             CALCULATE SIZE AND MAINTAIN ASPECT        ********** */
        // --------------------------------------------------------------------
        private void Calculate(ref int target_width, ref int target_height, float width, float height)
            {
            float ratio = width / height;
            float TVratio = (float)target_width / (float)target_height; // aspect ratio of TV
            if (ratio > TVratio)
                target_height = (int)((float)target_width / ratio);
            else
                target_width = (int)((float)target_height * ratio);
            }

        /* **********             DISPLAY  STATUS  IN  TITLE  BAR             ********* */
        // --------------------------------------------------------------------
        private void ShowStatus(int width, int height)
            {
            Text = String.Format("FotoApp 1.00 by B.Arnold       {0} x {1}, {2:#,###0} pixels.    {3}",
                                width, height, width * height, SourceFile);
            }

        /* **********             HANDLE EXIT MENU                    ********** */
        // --------------------------------------------------------------------
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
            {
            this.Close();
            }

        /* **********             SAVE  FILE                                  ********* */
        // --------------------------------------------------------------------
        private void SavePhotoToolStripMenuItem_Click(object sender, EventArgs e)
            {
            string aout = SourceFileBase + "-R.jpg";        // create new name for output
            if (System.IO.File.Exists(aout))
                {
                MessageBox.Show("Not saved because file already exists.", "Error");
                return;
                }
            if (pictureBox1.Image != null && Ready_to_Save == true)
                pictureBox1.Image.Save(aout, System.Drawing.Imaging.ImageFormat.Jpeg);
            else
                MessageBox.Show("Nothing to Save.", "Error");
            }
        }
    }

SOURCE CODE

Source Code Files

For help, email me at b a r n o l d @ i e e e . o r g
Back to C++ Main Page