Coding4fun: Rob's image shrinker

Source: Internet
Author: User
Tags set background

Show TOC

Content on this page
ApplicationProgram
Set the Image Target
Obtain source Image
Execute Processing
Zoom bitmap
Manage dimensions
Set background color
Preview an image
Show progress
Solve the deadlock problem
Completed Program
Automatic PlayStation portable detection
Drag and Drop Image Transmission
Automatic horizontal/Vertical Rotation

Smartphone, Pocket PC, and Sony PlayStation Portable are very useful image carrying devices. However, today's cameras are much more demanding than mobile devices. High pixels make the image print or preview on a large display very good, but it is not easy to achieve this effect when the display is small. These high-resolution image files take a long time to load and occupy a large amount of file space. (This article contains links to English websites)

Many graphics programs, such as Microsoft Digital Image Pro 10, have the batch editing feature, allowing you to resize images in batches. If you have a portable media center, you can use Media Player 10 to resize an image during transmission. However, what you really need is a program that allows you to resize images and transmit them immediately. So I wrote a program and we can look at how it works.

Whether you just want to use this program or want to studyCodeIs easy to get started. If you just want to use this program, I provide a user manual.

Use applications

I created this project using Visual C #2005 express edition. Open the corresponding project file to use. If you do not have Visual Studio, you can get a free copy from the http://msdn.microsoft.com/vstudio/express/visualcsharp.

The initial download copy is very small, but the installation time code will reach 300 MB.

After Visual Studio is installed on your machine, you can open the corresponding directory and select a solution file. In the following section, we will detail each part of the program. Examples andSource codeThey are not exactly the same, but we hope to focus on the important aspects of each development part.

Back to Top

Set the Image Target

I useFolderbrowserdialogTo set the target. This allows you to find the target directory for transferring image files. I set this option to enable users to create a new directory for storing images:

 
Outputdirdialog = new system. Windows. Forms. folderbrowserdialog (); outputdirdialog. Description = "select target"; outputdirdialog. shownewfolderbutton = true; outputdirdialog. showdialog ();

I useShowdialogSo that when you use the following dialog box to select a target, the rest of the program can be paused:

Figure 1: browsing target

When you open the "my computer" tree, you can see all drive letters, including all drive letters of the storage device. Note: This program must also handle the situation where the user clicks the "cancel" button instead of selecting a folder. In this case, the generated path length will be 0, so we will display the corresponding message:

 
If (outputdirdialog. selectedpath. Length = 0) {statuslabel. Text = "no target selected"; return ;}

We use a label at the bottom of the table to send messages to users.

Back to Top

Obtain source Image

After learning the location of the file, we need to select some files for transmission.OpenfiledialogThis operation happens because you can configure it to allow users to select multiple files. This dialog box also displays thumbnails of each image, so you can easily view the file to be transmitted.

 
Sourcefilesdialog = new openfiledialog (); sourcefilesdialog. multiselect = true; sourcefilesdialog. Title = "select the file to be shrunk ";

This Code creates this dialog box and configures it to allow multiple files to be selected. Now we can configure it to display only the image files to be transmitted:

 
Sourcefilesdialog. filter = "image file (*. BMP ;*. JPG ;*. GIF) | *. BMP ;*. JPG ;*. GIF | all files (*. *) | *. *";

The filter string looks quite complex, but is actually very simple. Each element in a string is separated by a vertical line. Each filter is represented as a pair of items, a description string followed by a column of filter expressions. It looks clearer if the expression is as follows:

 
"Image file (*. BMP ;*. JPG ;*. GIF) | *. BMP ;*. JPG ;*. GIF | "+" all files (*. *) | *. *"

The filter above allows you to select bitmap, JPEG, or GIF image files. The second exercise user can select all files. For each line, the text to be displayed in front of the user is separated from the file extension column applied to the selected line.

If you select the filter above, only the file names matching bitmap, JPEG, or GIF images are displayed. If the following filter is selected, all files are displayed.

Figure 2: Filter Used

Note: Only because the file has a special extension does not indicate that the file contains a special file type. Our program must ensure that invalid file content will not cause problems. We can introduce this part later.

You can select any number of files from the directory, or even use Ctrl + A to select all files. When you click the OPEN button, the dialog box ends and you can process the file and transfer it to the target device.

Back to Top

Execute Processing

OpenfiledialogReturns the Object Name of a column as a string array. Now, the program must open each file, load the bitmap in the file, adjust the bitmap size to the desired size, and then save the bitmap to the target directory. MethodProcessfilesAll the preceding operations can be performed.

Processfiles (sourcefilesdialog. filenames, outputdirdialog. selectedpath );

This method will pass an array of file names and the target path for output. Then, it must process all the files in the same way, and scale and save each file in sequence.

Private void processfiles (string [] filenames, string outputpath) {bitmap DEST = new Bitmap (size. width, size. height); foreach (string filename in filenames) {bitmap image; try {image = new Bitmap (filename);} catch {MessageBox. show ("An error occurred while loading the bitmap:" + filename); continue;} scalebitmap (DEST, image); string destfilename = outputpath + @ "\" + system. io. path. getfilenamewithoutextension (filename) + ". jpg "; try {DeST. save (destfilename, system. drawing. imaging. imageformat. JPEG);} catch {MessageBox. show ("An error occurred while saving the bitmap:" + destfilename); Return ;}}}

This method processes each file, creates a bitmap for each file, and callsScalebitmapMethod to scale the bitmap, and save the result back to the disk.

Note: I have applied an exception handler to the bitmap of the created file. If loading fails, a message is displayed and the method starts to process the next image. A try catch structure is also applied to the Save operation. However, if this operation fails, the next operation may fail because the output device may be full. Therefore, if the Save call fails, the method will return instead of continuing.

Back to Top

Zoom bitmap

It is very easy to scale the bitmap. You can use some plotting methods to draw a rectangle from one image to another. By controlling the size of the source and target, we can adjust the image size to make it suitable for our devices. The only difficulty is that we have to process the aspect ratio of the source and target images so that we do not cut out any part of the image. This is exactly the same as the problem when you watch an old TV program on a wide-screen TV (or watch a new TV program on a narrow-screen TV. The resize method must match the screen size and insert a blank area around the screen as needed.

Private rectangle srcrect = new rectangle (); Private rectangle destrect = new rectangle (); Private void scalebitmap (Bitmap DEST, bitmap SRC) {destrect. width = DeST. width; destrect. height = DeST. height; using (Graphics G = graphics. fromimage (DEST) {brush B = new solidbrush (backgroundcolor); G. fillrectangle (B, destrect); srcrect. width = SRC. width; srcrect. height = SRC. height; float sourceaspect = (float) SRC. width/(float) SRC. height; float destaspect = (float) DeST. width/(float) DeST. height; If (sourceaspect> destaspect) {// when the width is greater than the height, keep the width unchanged and increase the height according to the proportion (note: the programmer comment in the example program file uses English, this document translates it into Chinese for reference.) destrect. width = DeST. width; destrect. height = (INT) (float) DeST. width/sourceaspect); destrect. X = 0; destrect. y = (DEST. height-destrect. height)/2;} when the else {// height is greater than the width, the height remains unchanged and the width is increased proportionally. height = DeST. height; destrect. width = (INT) (float) DeST. height * sourceaspect); destrect. X = (DEST. width-destrect. width)/2; destrect. y = 0;} G. drawimage (SRC, destrect, srcrect, system. drawing. graphicsunit. pixel );}}

Adjusting the image size is actually very simple. You can provide the source and target rectanglesDrawimageMethod. The above method determines which method to scale the source rectangle and then adjusts the target rectangle to a proper size and position. MethodDrawimageIs part of the actual work. Note: The rectangle we use to adjust the source and target sizes is declared outside the method. In this way, we will not stop creating or deleting new rectangles for each scaled image. What we really need to do is to change the size of these rectangles each time, so we don't have to always create new rectangles.

Back to Top

Manage dimensions

You need to select a range of possible widths and heights based on the target device. The best screen component to perform this operation isComboBoxThis component has a project list from which you can select a project.

Figure 3: select the output format

The best way to manage the output format is to create a special class to save the size information. Then, we can provide this type of instance arrayComboBoxYou can select an instance.

Public class outputsize {public int width; Public int height; string name; Public override string tostring () {return name + "" + width. tostring () + "X" + height. tostring () ;}public outputsize (string inname, int inwidth, int inheight) {name = inname; width = inwidth; Height = inheight ;}}

OutputsizeThe type includes the name attribute used to identify the type and the height and width values. It providesTostringThe method is used to provideComboBox. Set the width and height attributes to public so that the methods in other classes can use these attributes. Finally, it uses a constructor so that we can set all values. Now, we can create an instance array for this class, which can be used to configureComboBox:

Private outputsize [] resolutionsettings = new outputsize [] {New outputsize ("Pocket PC", 640,480), new outputsize ("qvga", 320,240), new outputsize ("PSP ", 480,272), new outputsize ("Smartphone", 176,180 )};

If you want to add other dimensions to the program, these dimensions can be placed in the array and automatically selected and used. Add settingsComboBoxIs very convenient:

 
Resolutioncombobox. datasource = resolutionsettings;

This is a very powerful function of Windows Forms.ComboBoxYou can introduce these settings and use the values in the array to fill in its selection. To obtain an existing selection, we only need to obtain the selection and convert it to the actual type we have recognized:

 
Outputsize size = resolutioncombobox. selecteditem as outputsize;

Now, we can useSizeInstanceWidthAndHeightAttribute to control scaling.

Back to Top

Set background color

When the aspect ratio of the image is not very timely, you can choose to fill the background color around the image. The color will be stored as a form member:

 
Private color backgroundcolor = color. White;

The background color is initially set to white, but you can select other colors based on your preferences. I useColordialogDialog Box to allow users to perform this operation:

 
Backcolordialog = new colordialog (); backcolordialog. solidcoloronly = true; backcolordialog. Color = backgroundcolor; backcolordialog. showdialog ();

This dialog box allows you to select a color:

Figure 4: select a color

After you select a color, you can use it as the background of the image (ScalebitmapMethod ).

Back to Top

Preview an image

You may want to view the previewed image when transferring the image. UsePictureboxYou can easily view the components. We willPictureboxTo make the preview image look as close as possible to the transmitted image.PictureboxThe image on is set from the scaled image.

Previewpicturebox. Image = DEST;

We mustPictureboxThe only other operation that is performed is to ensure thatSizemodeSet propertyZoomSo that the preview image can accurately fill up the preview window.

Back to Top

Show progress

Another useful feature is the progress bar. When you transfer a large number of files, you will be eager to get some prompts about the program Transfer Progress. You can calculate the progress by dividing the number of transferred files by the total number of selected files. This produces a score. We can multiply by 100 to generate a percentage value of the progress bar size.

 
Loadprogressbar. value = (INT) (100 * (float) filecount/(float) nooffiles ));
Back to Top

Solve the deadlock problem

This program can work normally, but there is indeed a problem. Sometimes it takes quite a long time to complete image transmission. During this process, the Error Tracking provided by Visual Studio may determine that the program has stopped. Then, it will cause exceptions that cause program failure. It is not difficult to close the exception. We need to locate the "exception" item (on the "debug" menu item) and then clear it.ContextswitchdeadlockThe "throw" box next to the exception displays the following dialog box:

Figure 5: contextswitchdeadlock disabled exception

After these operations are completed, the program runs normally even if the transmission volume is large.

Back to Top

Completed Program

The completed program can work normally. I have successfully transferred 127 images to my PlayStation Portable in one way, and I have found that, apart from the images, 127 images only occupy 3.7 MB of space. However, you can also use a large number of enhancements.

Back to Top

Automatic PlayStation portable detection

The PlayStation Portable has a special file arrangement on its storage device. In fact, you must put the images in the \ PSP \ photo directory, otherwise they will not be displayed (take the path in Figure 1 as an example ). The program can check each drive of the system, automatically find the PSP device, and configure it accordingly.

Back to Top

Drag and Drop Image Transmission

In addition to selecting images from the file dialog box, the program can also be dragged to a file in the form. You can then scale and transmit these images.

Back to Top

Automatic horizontal/Vertical Rotation

Smartphone has a portrait display: its height is greater than the width, which is opposite to most images (these images are landscape. This means that the compiled program will not make full use of the screen. This is useful if images can be rotated during transmission so that they can fill the display screen as much as possible. Alternatively, you can provide users with options to allow them to rotate the smartphone image before transmission so that they can display the best results.

Rob miles is a lecturer at the computer department at the University of Hull, UK. The Department website is/http://www.net.dcs.hull.ac.uk /. He has been engaged in programming from the very beginning and has always liked this job. He is currently teaching C # and a large number of software engineering courses in this department. In his free time, he will write some essays in his blog (http://www.crazyworldofrobmiles.com) or play games on his Xbox 360. He also likes smartphone and cheese.

Go to the original English page


Back to Top

Suitable for printer printing versions, send this page via email to add to favorites



Personal Information Center | Msdn Chinese express mail | Contact us 2006 Microsoft Corporation. All rights reserved. Reserve all rights | Trademark | Privacy Statement



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.