You will build one or more UI-based mini-applications that displays and manipulate ObservableFrame2D objects. These little mini-applications are simple enough that they don’t really require the use of a model-view-controller pattern and can be encapsulated easily into a single self-contained UI widget. In order to display ObservableFrame2D objects on to the screen, we need to make use of some built-in Java library classes for images. In order to shield you from the details of these classes, I have created a subclass of the Java Canvas type called FrameView that is capable of displaying an ObservableFrame2D which you should use in your solutions. You don’t really need to understand how it works internally to use it, but in order to support this object, we need a few supporting functions.
- The Frame2D interface now includes a createObservable() method
- This method basically converts a Frame2D object into an ObservableFrame2D object. It is implemented in AnyFrame2D which means that all of our Frame2D implementations automatically inherit this capability.
- The ObservableFrame2D interface has been streamlined.
- Specifically, I have removed the methods to unregister observers by region and to find observers by region. Also, an overloaded version of the registration method has been added that simply takes the observer and assumes that you are interested in the entire frame (i.e., it simply calls the original registration method with a region of interest that covers the whole frame).
- A helper class called A7Helper has been added.
- 这个class提供了一些需要用到的method
- This class contains three static methods that are needed to support our new FrameView class. These methods are:
- public static Frame2D readFromURL(String url)
- This function takes a URL string (i.e., a web address) for a picture and, if successful, constructs a Frame2D object that represents the picture. It may throw an IOException if something goes wrong.
- 这个method把一个网址图片的网址变成了一个Frame2D object
- public static int pixelToRGB(Pixel p)
- Java’s classes for dealing with images represent pixels as integers with different bits within the integer representing the red, green, and blue components. This function converts our Pixel objects into the appropriate corresponding packed integer.
- public static Pixel rgbToPixel(int rgb)
- This function does the conversion between a packed RGB integer color and our Pixel representation.
- 这两个methods就帮助把一个pixel转化成对应的红绿蓝三个数字
- A new class called FrameView has been added.
- This class is a subclass of the Java Canvas user-interface component. It accepts an ObservableFrame2D object as a parameter to its constructor. A FrameView object simply paints the encapsulated ObservableFrame2D object on the screen. You can use the setFrame() method to change what ObservableFrame2D object it is painting. It implements ROIObserver and attaches itself to the ObservableFrame2D object that it encapsulates so that if the ObservableFrame2D object changes, it can repaint the picture automatically. You use it like any other user interface object (i.e., place this object into a UI container, attach listeners in order to respond to user interface events, etc.). As a subclass of Canvas, it supports all of the same event listeners that Canvas does. You will mostly just need to be able to add mouse listeners and key listeners
- A UI widget called SimpleFrameViewWidget has been provided.
- This widget is provided a Frame2D object and a String “title” as arguments to its constructor. The widget creates a user-interface comprising of a FrameView object to display the Frame2D object and a JLabel object to display the title. It also handles mouse click events on the FrameView object by printing the x and y coordinates to the console whenever a click occurs. You can use this object as a basic pattern for using FrameView in your own widgets.
The class A7SetupTest is a simple test application that creates a Frame2D object from a URL using the A7Helper.readFromURL() function, creates a new top-level user interface window with a SimpleFrameViewWidget to display the Frame2D object along with a title.
If your setup is working correctly, you shold be able to run A7SetupTest and see me appear on the screen along with the title “K to the M to the P”. Mouse clicks on the image should print coordinates of the click to the console.
It should look like this:
这部分是已经写好了当你的鼠标点到一个点的时候,在下面console那个里面会有坐标
Follow the pattern above to create one or more of the following mini-applications. In the descriptions below, the name of the application should be the name of the main class (i.e., the one with main() to run). These are listed in the order of increasing complexity (and thus point value). For each, there may be many different ways to approach and architect your solution. We will be grading both for basic functionality as well as the design and readability of your code.
PixelInspector (5 points)
This application should load an image and when clicked display information about the pixel where the click occurs.
这部分的要求就是当你的鼠标点到一个点上面的时候,旁边会显示这个点得X坐标Y坐标,红绿蓝分别对应的数还有亮度
例子
ImageAdjuster (10 points)
This application should provide two or more sliders that adjust the image in some way. I suggest the following but you can do others if you would like:
- Blur Replaces each pixel as the average of the pixels around it. You can think of the slider as controlling the size of a square area centered on each pixel to be averaged. So a blur size of 0 would mean no blurring. A blur size of 1 would mean averaging all adjacent pixels. A blur size of 2 would be averaging all pixels with x and y coordinates that were +/- 2 of each pixel, etc.
- Blur 的范围是0到5,如果是0,就没有变化,如果是1,就把每一个pixel都替换成它周围pixels的平均值,也就是周围一圈八个pixels的平均值。如果是2的话,就是把每一个pixel都换成它周围两圈16个pixels。
- Brightness Adjusts the pixels toward black or white according to a slider. In my solution, the slider runs from -100 representing black, 0 representing the original pixel value, and 100 representing white.
- Brightness是一个-100到100的滑动条,-100就是向黑色变,+100就是向白色变
- Saturation Adjusts the pixels toward gray scale or oversaturation. In my solution, -100 means no color and 100 means fully saturated. The formula for this is as follows: Let f be the saturation factor defined by the slider (-100 to 100). Let b be the brightness (i.e. intensity) of the original pixel. Then given a saturation factor f between -100 and 0, for each component of pixel (i.e., red, green, blue), the new value is: new = old * (1.0 + (f / 100.0) ) – (b * f / 100.0) Given a saturation factor f between 0 and 100, first determine which component of the pixel is largest. Call this value l. Then calculate the following value for gain: gain = (l + ((1.0 – l) * (f / 100.0))) / l; Now calculate the new value of each components as: new = old * gain
- 这个也是有一个-100到+100的滑动条,让f表示那个滑动条上的数字,如果这个数字在-100到0之间,b代表之前算得亮度,那么新的pixel的每一个component就是之前的乘(1.0 + (f / 100.0) ) – (b * f / 100.0) 。如果在0到100之间,那么先找到红绿蓝三个component哪个最大,然后把那个最大的值叫做l, gain = (l + ((1.0 – l) * (f / 100.0))) / l,new = old * gain ,先算gain,新的值就是以前的值乘gain
My version of this mini-application looks like this:例子
FramePuzzle (10 points)
This application should create a 5×5 grid of FrameView objects that each display a portion of the original frame. The lower right corner should be replaced with a Frame2D filled with a solid color. Clicking on a row or column in line with the “blank” tile should move the portions over to fill the blank space, resulting in the blank space moving to where the click occured. Using the keyboard up, down, left, and right keys should swap the blank space with the adjacent portion in the appropriate direction. Getting the boundaries between the FrameView objects to line up seamlessly is very difficult (especially if the image dimensions are not a perfect multiple of 5) so don’t worry if you see discontinuities.
My version of this looks like this (it is shown after I’ve moved some of the pieces of the puzzle around already):
这一部分就是把一张图片分乘25个小格子,然后把右下角的那一块变成一个颜色块,当鼠标点击到跟这个颜色块在同一行或者同一列的小方块时,这一行或者这一列的格子都往那个颜色格子的地方移,然后这个颜色格子就被移到鼠标点的那个格子的位置了。当用键盘上上下左右键的时候,会把这个颜色格子与周围的格子互换
例子