Contents:

Introduction

In this assignment, you will build Photostall, a GUI to an image convolution service. Image convolution is commonly used in image processing, computer vision and deep learning. For example, it can be used to blur or sharpen an image, to find edges, and more.

Photostall is a client-server application. That is, it has two components:

Technologies used by the Photostall GUI

The Photostall GUI is written using HTML and JavaScript.

To learn about HTML, see the W3 Schools HTML tutorial.

To learn about JavaScript, see the MDN JavaScript tutorial.

Here are some tools you will need for this assignment:

Step 1: Cloning your repository

Since Photostall is not part of the Campus Maps application, you will use a separate Git repository. You can clone it from the command line:

git clone git@gitlab.cs.washington.edu:cse331-18au-students/hw9/cse331-18au-hw9-CSENetID.git

To import the project into IntelliJ, follow the same instructions you used to add your original project to IntelliJ. Since this project uses Maven instead of Gradle, the external model you are importing the project from is Maven, not Gradle.

Step 2: Running the Server

The server is already implemented for you. You must run the server:

Once the server is running, visit http://localhost:8080/swagger-ui.html to interact with the API. Click on "public-api", then the green button "POST", then "Try it out", then edit the model example value.

Troubleshooting

It might take a long time to copy resources. Be patient, and do not kill the process.

If you get an error of the form

Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.1.0.RELEASE:run (default-cli) on project hw9:
An exception occurred while running. null

then running mvn clean may be a solution.

If you get an error of one of the following forms:

APPLICATION FAILED TO START

The Tomcat connector configured to listen on port 8080 failed to start.
The port may already be in use or the connector may be misconfigured.

org.apache.catalina.LifecycleException: Protocol handler start failed

then perhaps you already have a process running on port 8080. This can happen if you ran the process earlier and didn't kill it. You can reboot your computer, or you can run netstat -vanp tcp | grep 8080 to get the pid to kill.

Step 3: Creating a User Interface using React

You will write a user interface to let users interact with the convolution service in a more friendly way.

You will write the UI in file src/main/resources/src/App.js.

To run the React server, run npm start from src/main/resources. Once your server is running, visit http://localhost:3000 to view your UI. (You should try to run this even before you have written any code, and you will see a default web app provided by the staff.)

Your interface should allow a user to input the URL and the convolution. (Your UI won't do anything with those arguments yet.) Here is a very basic way to implement the UI:

The staff recommends that you use the Material UI library, which provides "React components that implement Google's Material Design." This dependency has already been added for you (in file src/main/resources/package.json), so you can import its classes in file App.js, for instance using import Button from '@material-ui/core/Button';. You are permitted to add other dependencies, but the staff does not support other dependencies and cannot help with any problems you might encounter.

Step 4: Connecting the UI with the API

Your UI exists and has graphical components, but it is not yet functional because you have not yet invoked the convolution service. To do that, the UI should issue an asynchronous request using fetch, then update the image display area after receiving a response from the server.

The reason to issue a request asynchronously rather than synchronously is to prevent the backend service from blocking the main UI thread. Because the main UI thread is still running, it can be responsive to user actions while waiting for a backend response.

To issue requests to a server asynchronously, you should use node-fetch. (Another implementation of fetch is JavaScript Fetch, but the staff recommends node-fetch.) node-fetch is a JavaScript library that handles asynchronous requests.

The basic code run by your submit button will look like

fetch('http://localhost:8080/convolve', { arguments }))
  .then(response => do some work)
  // possibly more chained .then(arg => action) lines

In the above code, the fetch line is performed immediately, and the .then function is invoked on the response, when it eventually arrives. The argument to then is a function whose formal parameter is named response. That function will be invoked on whatever fetch returns. It needs to do two things:

Here is some more help about calling fetch:

To update the image display area when you receive a server response, you should use React's setState function. You might also use lifecycle functions like componentDidMount; see the documentation of the state and lifecycle of a React component.

Do not use ReactDOM.render in your application. Only index.js (which you do not need to edit) should call ReactDOM.render. The Document Object Model (DOM) is a representation of HTML and XML documents. The DOM represents the document as nodes and objects. A JavaScript program can change the DOM, which changes what the user sees in the browser. Using React allows React to manage the webpage and saves time as React no longer needs to keep communicating with the DOM. Calling ReactDOM.render will require React to communicate with the DOM which affects performance and defeats the purpose of React.

UI enhancements

You are responsible for making a GUI that performs the required tasks, and is easy to use and intuitive. You are permitted, but not required, to be creative and improve upon this basic design. (Don't do this until after you have completed the entire assignment.)

Here are a few suggestions of optional API expansions:

Additional functionality should augment, not replace, the requirements of the assignment. Please record all additional functionality you attempted to add in src/main/resources/answers.txt.

In case you add functionality or provide a UI that goes beyond the requirements of the assignment, you are eligible for extra credit. This extra credit will either allow you to get back points you have lost on this assignment, or will be used when final grades are being decided.

Hints

Approximately 100 lines of JavaScript are enough to complete the basic requirements of this assignment. It is acceptable to write the entire implementation in one file. However, if you add a lot of functionality and a lot more code, consider splitting it into multiple files.

It is easiest to have a different handleChange... function for each component of your GUI.

The JavaScript function console.log can be useful for logging (that is, for printf debugging). The output will appear in the client's (browser's) console. To see it:

The JavaScript syntax param => body creates a function (like a lambda expression does in Java). That is, the following two code snippets are essentially equivalent:

  double =  param => 2 * param

  function double(param) { return 2 * param; }

Feedback on the assignment

Complete the Canvas Quiz associated with this assignment. You will receive full credit for this section if you complete the quiz. Your answers will be anonymous to the instructors. This quiz is due 24 hours after the assignment due date. You cannot use late days for this quiz.

What to Turn In

We don't have any specific files that you must submit as part of the assignment. The only exception to the previous statement is the requirement of answers.txt if you add additional functionality. The staff strongly urges you to test your UI on a lab machine. Your UI must load when we visit http://localhost:3000.

Refer to the assignment submission handout for complete turnin instructions.