This portfolio seeks to document my contributions to our team's project, FomoFoto.

Project Title: FomoFoto

Overview

My team and I were tasked with enhancing a basic command line Address Book for our software engineering project. We decided to morph the project into an image editor.

FomoFoto is a robust yet simple image-editing tool. Users interact with the application through worded commands from their keyboard, and receive visual feedback from it through the displayed image on the application.

Unlike other heavy image editors, FomoFoto has a very gentle learning curve as it abstracts out clutter by providing the more essential features (complex editing can still be done with special commands). The features and implementations are well documented in guides for users and developers respectively.

In addition, FomoFoto is well-maintained with high reliability and code quality as it is covered by rigorous tests and checks.

Summary of contributions

This section provides a summary of my coding, documentation and other contributions to FomoFoto, our team project.

Major Enhancement — Added the feature to open an image.

  • What it does: The open command allows users to open an image that was previously imported into the album for editing.

  • Why it is important: This feature is essential as it enables users to choose which image they want to edit. Upon using the open command, the chosen image is displayed prominently in the main window of the application, allowing users to know which image they are about to apply their edits on.

  • Highlights: The open command duplicates the opened image so that users are able to recover the original image should they decide to abandon their edits or in the unlikely event of an application crash. Therefore, this enhancement requires in-depth analysis on how the temporary image is stored. When an image is opened, two copies named ori_img.png and temp_img.png are created in the temporary folder. Subsequent edits will update and overwrite temp_img.png while ori_img.png is used for undo and redo operations.

Major Enhancement — Added the feature to save an image.

  • What it does: The save command allows users to apply their edits to the image and save it as a new image.

  • Why it is important: This feature completes the image editor by enabling users to apply their edits permanently onto the image. It also gives users the ability to save their current work and resume editing at another time.

  • Highlights: The save command gives users the choice to either save the edited image with a new name or overwrite the original image. To save as a new image, users simply type save newName.png and an image named newName.png will be created in the album. To overwrite the original image, a simple save would suffice. After saving, users may continue to edit the image.

Minor Enhancement — Added the feature to list file names.

The listfiles command displays all the names of the images in the album. It provides a quick reference to the images so that users may type the name correctly when using open.

Code Contributed

Here are the code contributions that I have made. [List of Commits] [Project Code Dashboard]

Other Contributions

  • Project management:

    • Managed release v1.2, v1.3, v1.3.1 and v1.4 (4 releases) on GitHub.

    • Managed labels, milestones and issues for issue tracking on GitHub.

  • Documentation:

    • Wrote features implemented for the User Guide: #58, #142

    • Wrote features implemented and User Stories for the Developer Guide: #129, #244

  • Community:

Contributions to the User Guide

This section highlights my contributions to the User Guide. It showcases my ability to write documentation targeting end-users.

Features


This section describes all the commands available in FomoFoto. It provides a short description of what each command does, their formats as well as examples of how to use them. The commands are listed in alphabetical order.

Command Format

The following styles are used to describe the format of the commands.

  • Words in UPPER_CASE are to be replaced with what the text specifies.
    e.g. open FILENAME: FILENAME is to be replaced with the name of the file that the user wants to work on such as open myImage.png.

  • Words in square brackets are optional values.
    e.g. brightness [BRIGHTNESS_RATIO]: BRIGHTNESS_RATIO can be omitted. Both brightness and brightness 0.9 are accepted.

Save Feature

Applies your edits and saves the image.
Format: save [FILENAME]

Example:

  • save

  • save newname.jpg

For a file name to be valid, it must end with either of the following: .jpg, .png, .gif, .bmp, .jpeg, .tif or tiff.

ugInvalidsave
Figure 1. Invalid Save Name
ugValidsave
Figure 2. Valid Save Name

Invalid Save Name shows an example of how FomoFoto does not allow saving with invalid names. Ensure that your file name is valid before saving. There should be a message to indicate that the save is successful as shown in Valid Save Name . To overwrite the original image, simply use save without the file name.

Other Works Contributed


  • Open Feature

  • List Files Feature

Contributions to the Developer Guide

The section highlights my contributions to the Developer Guide. It showcases my ability to write technical documentation and the technical depth of my contributions to the project.

Open Feature


This command allows the user to open a previously imported image for editing.

Current Implementation

The open function is facilitated by Album and CurrentEdit. It uses the following operations:

  • Album#checkFileExist(String) - Checks if file name specified by the String exists in assets directory.

  • Album#retrieveImage(String) - Returns an Image specified by the String in assets directory.

  • CurrentEdit#openImage(Image) - Creates two copies of the opened image in temp directory. The duplicated images are instantiated as tempImage and originalImage.

  • CurrentEdit#updateExif() - Updates the Exif data of the image.

  • CurrentEdit#displayTempImage() - Displays the temporary image stored in the temp directory.

OpenCommandSequenceDiagram
Figure 3. Sequence Diagram for Open Command

The following is an example usage scenario of how open behaves at each step as shown in the figure above.

Step 1. The user executes open sample.png.

Step 2. Album#checkFileExist(String) is called to check if the file specified by the String is in assets directory. If it exists, Album#retrieveImage(String) is called to create an Image object from the specified file. Otherwise, CommandException is thrown.

Step 3. The Image is passed to CurrentEdit#openImage(Image) to create two copies of it, named temp_img.png and ori_img.png, in temp directory. These copies are then instantiated as tempImage and originalImage.

Step 4. CurrentEdit#updateExif() is called to update the information of the opened image.

Step 5. CurrentEdit#displayTempImage() is called to display the opened image on the GUI.

Design Considerations

  • Alternative 1 (current choice): The user can only open and edit one image at a time.

    • Advantages:

      • Easy to implement.

      • Saves space as temp directory only stores one original image and one temporary image.

      • Clear to users that edits are done to the only opened image.

    • Disadvantage: Only one image can be edited at a time.

  • Alternative 2: The user can open and edit multiple images.

    • Advantage: Images can be edited simultaneously.

    • Disadvantages:

      • Hard to distinguish whether the user is opening an image from assets or temp directory.

      • Requires many duplicates with different temporary names.

      • May be confusing for the user.

Alternative 1 was chosen as it is less complicated, requires lesser space and more user-friendly.

List Files Feature


This command displays the names of all the files in the assets directory.

Current Implementation

The listfiles function is facilitated by Album. It uses the following operation:

  • Album#getFileNames() - Returns a list of all the files in assets directory.

ListFilesCommandSequenceDiagram
Figure 4. Sequence Diagram for ListFiles

The following is an example usage scenario of how listfiles behaves at each step as shown in the figure above.

Step 1. The user executes listfiles.

Step 2. Album#getFileNames() accesses assets directory and returns all the file names in a String array.

Step 3. The String array is displayed on the GUI.

Design Considerations

This command was created to allow the user to know what files are stored in assets directory so that the FILENAME can be easily referenced for open.

Save Feature


This command applies the edits to the current image and saves it into assets directory.

Current Implementation

The save function is facilitated by Album and CurrentEdit. It uses the following operations:

  • CurrentEdit#tempImageDoNotExist() - Returns true if tempImage in CurrentEdit is null. tempImage is null only if open command was never called.

  • CurrentEdit#getTempImage() - Returns the latest edited image stored in tempImage in CurrentEdit.

  • CurrentEdit#getOriginalName() - Returns the original name of opened image.

  • CurrentEdit#overwriteOriginal(String) - Replaces ori_img.png with temp_img.png in temp directory. Updates originalImage to tempImage and originalImageName to String in CurrentEdit.

  • CurrentEdit#deleteHistory() - Clears the history in CurrentEdit.

  • CurrentEdit#updateExif() - Updates the Exif data of the new image.

  • Album#checkFileExist(String) - Checks if the file name specified by the String exists in the assets directory.

  • Album#saveToAssets(Image, String) - Saves the Image as String into assets directory.

  • Album#populateAlbum() - Updates list of images in Album class.

  • Album#refreshAlbum() - Updates and displays the latest images in assets directory on the GUI.

SaveCommandSequenceDiagram
Figure 5. Sequence Diagram for Save Command

The following is an example usage scenario of how save behaves at each step as shown in the figure above.

Step 1. The user executes save.

Step 2. CurrentEdit#tempImageDoNotExist() is called to check if an image was previously opened. If open was not called previously, CommandException is thrown.

Step 3. CurrentEdit#getTempImage() is called to retrieve the tempImage from CurrentEdit.

Step 4. If the user did not input a String after save previously, CurrentEdit#getOriginalName() will retrieve the originalImageName from CurrentEdit. Otherwise, Album#checkFileExist(String) will be called to check if a file name is similar to String. If it is a duplicate, CommandException will be thrown.

Step 5. Album#saveToAssets(Image, String) takes in the previously retrieved Image and String to create a new image file in assets directory.

Step 6. CurrentEdit#overwriteOriginal(String) is called to update the files in temp directory and their respective instances in CurrentEdit.

Step 7. CurrentEdit#deleteHistory() is called to delete the edit history in CurrentEdit so that the user can no longer perform undo on the saved image.

Step 8.CurrentEdit#updateExif() is called to update the Exif data of the new image.

Step 9. Album#populateAlbum() is called to update the list of images in the Album class and to ensure it reflects all the files in the assets directory.

Step 10.Album#refreshAlbum() is called to update the Information Panel on the GUI.

Design Considerations

  • Alternative 1: The user must give a name to the new image.

    • Advantage: Name of the new image is clear to the user.

    • Disadvantage: May be tedious for the user to type in a name each time save is performed.

  • Alternative 2 (current choice): The user can choose to save as a new name or overwrite the original image

    • Advantage: Convenient for the user to save quickly without having to type a new name every time.

    • Disadvantage: The user may unintentionally overwrite the original image.

Alternative 2 was chosen as the user is likely to use save frequently. Since the assets directory functions like an album, images can be re-imported if they are accidentally overwritten. The user is able to save easily and choose to resume editing immediately or at a later time.

Other Works Contributed


  • Appendix B: User Stories