4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
Menu
Introduction Fundamentals Description – Part A Description – Part B Appendix Download Programming Tips Submission & Deadline
FAQ
About Plagiarism
COMP 1022P Introduction to Computing with Java Assignment 1 Animated Meme Maker!
Introduction
In this assignment, you will learn some basic concepts in image processing. After implementing those concepts using Java, you will be able to generate some animated memes using your own images.
There are 2 parts of this assignment: Part A (3 tasks) and Part B (2 tasks). Implement ALL routines in part A and in part B.
There’s also an Appendix section where we released some sample code to you. You may read it before starting your implementation.
Get Started
To get started on the assignment, download the skeleton code and read the fundamentals & description on this page and the given Java source file ImageProcessor.java. Please note that all implementation of your program should be done in Java and placed in ImageProcessor.java.
To test your program, you may want to download some sample images here. Submit your program file (i.e. ImageProcessor.java) to Canvas, by 23:59:00 on April 6, 2019 (Saturday).
End of Introduction
Page maintained by
Tony JI
Email: twsji@connect.ust.hk Last Modified: 03/22/2019 00:00:39
Homepage
Course Homepage
Fundamentals
Fundamentals of Image Processing
A digital image is a two-dimensional grid of intensity values, represented by I(x,y), where x and y are coordinates, and the value of I at coordinates (x,y) is called intensity of the image. The following is a list of common terminologies of digital images.
Pixels
Dimensions
The dimensions of images are specified by the width and height of the image. Image width is the number of columns in the image, and image height is the
Short for Picture Element. A pixel is a single point (dot) in an image.
https://course.cse.ust.hk/comp1022p/assignments/pa1/
1/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
number of rows in the image. This following shows an image of dimensions 32×21 (i.e. image width = 32 pixels, image height = 21 pixels).
Image Coordinate System
A specific pixel is specified by its coordinates (x,y) where x is increasing from left to right and y is increasing from top to bottom. The origin (0,0) is in the top-left corner. A pictorial description of image coordinate system is as follows:
where width and height are the image width and image height respectively.
The legal range of x-coordinate is between 0 to width – 1 The legal range of y-coordinate is between 0 to height – 1
Color and Grayscale Images represented in RGB
Color images have intensity from the darkest and lightest of 3 different colors, Red, Green, and Blue (RGB). The mixtures of these color intensities produces a color image. Since RGB images contain 3×8-bit intensities, they are also referred to as 24- bit color images.
An 8-bit intensity range has 256 possible values, 0 to 255. Common colors represented in RGB
(0,0)
(1,0)
(2,0)
(3,0)
…
(width-1,0)
(0,1)
(1,1)
(2,1)
(3,1)
…
(width-1,1)
…
(0,height-1)
(1,height-1)
(2,height-1)
(3,height-1)
…
(width-1,height-1)
Black
RGB = (0, 0, 0)
White
RGB = (255, 255, 255)
Red
RGB = (255, 0, 0)
Green
RGB = (0, 255, 0)
Blue
RGB = (0, 0, 255)
Yellow
RGB = (255, 255, 0)
Gray
RGB = (128, 128, 128)
Dark Gray
RGB = (50, 50, 50)
https://course.cse.ust.hk/comp1022p/assignments/pa1/
2/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
24-bit grayscale images are RGB images contain 3×8-bit intensities, where the RGB values to be all equal (e.g. gray and dark gray as shown above).
Animated Image – GIF Image
When you save images into your devices, you may notice that those images have some suffixes at the end of their filenames. For example, “my_cat.jpg”, “my_girlfriend.bmp”, “desmond_inclass.png”, etc. Those are very typical image types, and you don’t need to know their differences in this assignment.
In comparison, you will be playing with another image type, which is the gif type. Let’s meet rabbit Foobar, who will be supporting you during your first programming assignment.
(click the image to stop animation)
The gif image is an “animated image”, which consists of a collection of images.
The above image shows you how the animated rabbit gif image is obtained.
First, we create the collection of images by calculating how Foobar should look like at a certain time.
Then, we line up those obtained images and put them into their correct slot in our desired gif image.
Finally, the gif image will be created using the images. When we view the gif image, it will be played like a slideshow, thus we will feel like the image is “animated”.
Playing with the Assignment Program
After downloading the skeleton code, create a project and copy all the files into the source folder. Then, build and run the project. You will see a similar interface as shown below.
The first thing you need to do is open an image. Click “File” -> “Open”, and choose an image you’d like to play with.
https://course.cse.ust.hk/comp1022p/assignments/pa1/
3/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
Then, you may select “Processing”. There are several options inside. Everytime when you want to test a part of your implementation, select the corresponding option, wait for a few seconds, and an animated gif image will be generated.
If your implmentation is correct, you will see the animation changing between your original image and the resulting image. The gif image will be automatically saved to your Project Folder. You may also change the corresponding variables inside “imageFrame.java” for testing purposes. (Optional)
Some sample code have been released to you in the appendix section. Please read the code and try to understand what it does. The implementation of the other routines should be similar to the given one.
https://course.cse.ust.hk/comp1022p/assignments/pa1/
4/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
End of Fundamentals
Description: Part A – Image Transformation
(Please note that the example images each has a black image frame which is not a part of the image)
1. Translation
Given an image in 24-bit format, implement a method to translate the image. The
method header of the image processing routine is shown below:
Input:
bi is a reference variable to the input buffered image.
xDir is an integer representing the number of pixels that the image should move in the +x direction.
yDir is an integer representing the number of pixels that the image should move in the +y direction.
Output:
the returned value is a reference to the resulting image.
Idea:
click here to get the basic idea on how to do image translation.
Examples: (Original image is of size 640 x 640 pixels) Translate Foobar by 320 pixels in x direction.
Original Translated
Translate Foobar by -320 pixels in y direction.
public static BufferedImage translate(BufferedImage bi, int xDir, int yDir)
https://course.cse.ust.hk/comp1022p/assignments/pa1/
5/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
Original Translated
Translate Foobar by 160 pixels in both x & y direction
Original Translated
Translation values in “ImageFrame.java”: 0, 8, 16, 24, 32, …, 160 pixels in both x and y direction, then reverse. Resulting gif image using the assignment program with “rabbit.jpg”: (The image shown below is lossy compressed)
Animated
(click to stop animation)
2. Scaling (with respect to image origin)
Given an image in 24-bit format, implement a method to scale the image around image’s
origin (0, 0). The method header of the image processing routine is shown below:
Input:
bi is a reference variable to the input buffered image.
xDirScale is a float representing how many times the image’s width will be enlarged / shrinked (1 means not changed).
yDirScale is a float representing how many times the image’s height will be enlarged / shrinked (1 means not changed).
Output:
the returned value is a reference to the resulting image.
Idea:
click here to get the basic idea on how to do image scaling.
Examples: (Original image is of size 640 x 640 pixels)
Scale dark mode Foobar by 2 in x direction (which is same as doubling the width), 1 in y direction
public static BufferedImage scale(BufferedImage bi, float xDirScale, float yDirScale)
https://course.cse.ust.hk/comp1022p/assignments/pa1/
6/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
Original Scaled
Scale dark mode Foobar by 0.5 in y direction (which is same as halving the height), 1 in x direction
Scaled Scaled
Scale dark mode Foobar by 2 in both x & y direction
Original Scaled
Scaling values in “ImageFrame.java”: 1.0, 1.05, 1.10, 1.15, …, 2.0 in both x and y direction, then reverse.
Resulting gif image using the assignment program with “rabbit-inverse.jpg”: (The image shown below is lossy compressed)
Animated
(click to stop animation)
3. Rotation (with respect to image center)
Given an image in 24-bit format, implement a method to rotate the image around image’s center (width / 2, height / 2). For example: half of 7 is 3.5, not 3.0. Please pay attention to conversion and division between int & float. The method header of the image processing routine is shown below:
Input:
bi is a reference variable to the input buffered image.
angle is a float representing how much the image should be rotated counter- clockwisely. It is in radians.
Output:
public static BufferedImage rotate(BufferedImage bi, float angle)
https://course.cse.ust.hk/comp1022p/assignments/pa1/
7/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
the returned value is a reference to the resulting image.
Idea:
click here to get the basic idea on how to do image rotation.
Examples:
Rotate Foobar by 90 degrees
Original
Rotate Foobar by -60 degrees
Original
Rotate Foobar by 720 degrees
Original
Rotated
Rotated
Rotated
Rotation values in “ImageFrame.java”: 0, 18, 36, 54, …, 360 degress, then reverse. Resulting gif image using the assignment program with “rabbit.jpg” and “owl.jpg”: (The image shown below are lossy compressed)
Animated Animated
(click to stop animation) (click to stop animation)
After you have successfully implemented translation & rotation, you may play with the “Shaking” option. It is just a combination of translation and rotation. Resulting gif image using the assignment program with “trembling.jpg”: (The image shown below is lossy compressed)
https://course.cse.ust.hk/comp1022p/assignments/pa1/
8/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
Trembling…? Really Trembling (click to stop animation)
Part A – Way of Thinking
This section will give you a basic idea on how to obtain the resulting images in part A.
To get started, let’s do the rotation task and suppose the angle is 60 degrees (counter- clockwisely). Here’s the original yellow rabbit.
Suppose we want to find the color of pixel (i, j) in the resulting image
We can first imagine that the yellow rabbit is rotated by 60 degrees.
Now in order to get the color, the problem becomes
“What coordinate (x, y) should I use in order to get the color from the original image?”
https://course.cse.ust.hk/comp1022p/assignments/pa1/
9/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
Here comes the most important part:
Rotating the original image counter-clockwisely by 60 degrees Is the same as
Rotating the pixel indices clockwisely by 60 degrees
Therefore, we use formulas to compute the new pixel coordinate (x, y) after a “inverse” rotation.
(x, y) = rotateAroundCenterClockwisely(i, j, 60)
By using this coordinate (x, y), we can directly obtain the color we want from the original image.
By doing the same thing to all the pixels, we can obtain a rotated image.
The same idea can be applied to translation and scaling, which is easier than rotation. You may try to figure it out yourself.
End of Description – Part A
Description: Part B – Image Effects
(Please note that the example images each has a black image frame which is not a part of the image)
1. Blending two images
Given two images in 24-bit format having the same width and height, implement image blending according to the description below. The following gives the method header of the image processing routine:
public static BufferedImage blend(BufferedImage bi1, BufferedImage bi2, float image1Weight)
Input:
https://course.cse.ust.hk/comp1022p/assignments/pa1/
10/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
bi1 is a reference variable to the first input buffered image.
bi2 is a reference variable to the second input buffered image.
image1Weight is a float between 0 and 1 representing the blending ratio of the first image.
Examples:
0 means image1 accounts for 0% of the resulting image, and image2 accounts for (1-0) = 100% of the resulting image, thus the resulting image is just image2.
1 means image1 accounts for 100% of the reuslting image, and image2 accounts for (1-1) = 0% of the resulting image, thus the resulting image is just image1.
Details can be found below in the pesudo-code section.
Output:
the returned value is a reference to the resulting image
Algorithm in pseudo-code:
// Input: image1, image2, weight1
For each pixel at coordinates (i, j) in the resulting image {
blended red value = image1.redColorAt(i,j) * weight1 +
image2.redColorAt(i,j) * (1-weight1)
blended green value = image1.greenColorAt(i,j) * weight1 +
image2.greenColorAt(i,j) * (1-weight1)
blended blue value = image1.blueColorAt(i,j) * weight1 +
image2.blueColorAt(i,j) * (1-weight1)
resultingImage.pixelAt(i,j).color = (blendedRed, blendedGreen,
blendedBlue)
}
Examples: (Bothe images are of size 640 x 640 pixels)
Blend two images with image1Weight = 0.9
Image 1 Image 2
Blend two images with image1Weight = 0.5
Image 1 Image 2
Blend two images with image1Weight = 0.0
Result
Result
https://course.cse.ust.hk/comp1022p/assignments/pa1/
11/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
Image 1 Image 2 Result
Blending values in “ImageFrame.java”: 1.0, 0.95, 0.90, 0.85, …, 0.0, then reverse.
Resulting gif image using the assignment program with image1 “rabbit.jpg” and image2 “handsome.jpg”: (The image shown below is lossy compressed)
Animated
(click to stop animation)
2. Blurring
Given an image in 24-bit format, implement image blurring according to the description
below. The following gives the method header of the image processing routine:
Input:
bi is a reference variable to the input buffered image.
blurRadius is an integer bigger than 0 representing the “radius” of the blurring square.
Output:
the returned value is a reference to the resulting image.
Algorithm
In the previous parts, we loop through each pixel and only make use of its original color. In this part, we are going to use a pixel’s neighbors’ colors to determine its own color.
In order to blur an image, the easiest way is to average a pixel’s color among its neighbours.
public static BufferedImage blur(BufferedImage bi, int blurRadius)
https://course.cse.ust.hk/comp1022p/assignments/pa1/
12/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
In this picture, the pixel to be blurred is the center “1”, and the blurring box has a radius of 1. When processing each pixel, we also obtain its’ left-up, straight-up, right-up, straight-left, straight-right, left-down, straight-down, right-down pixels. We add the 9 pixels’ colors together, and divide it by 9 to obtain the averaged color of this pixel. By doing this operation to all pixels, the resulting image will be blurred.
Similarly, this blurring box has a radius of 2. When processing each pixel, we also obtain its 24 “neighbors” and calculate an average. By using a blurring box of a larger radius, the resulting image will be fuzzier.
In the assignment, for the pixels who don’t have enough neighbors, their colors should be the same as their original colors.
Algorithm in pseudo-code:
// Input: image, blurRadius
For each pixel at coordinates (i, j) in the resulting image {
if (some parts of the pixel’s blurring square is out of bounds) {
// pixel does not have enough neighbors
resultingImage.pixelAt(i,j).color = image.pixelAt(i,j).color
} else {
// pixel has enough neighbors
int sumOfRed, sumOfGreen, sumOfBlue
for each pixel in the blurring square {
sumOfRed += neighborPixel.redColor
sumOfGreen += neighborPixel.greenColor
sumOfBlue += neighborPixel.blueColor
}
// no need to cast to float, just directly divide two integers
averageRed = sumOfRed / numOfNeighbors
averageGreen = sumOfGreen / numOfNeighbors
averageBlue = sumOfBlue / numOfNeighbors
resultingImage.pixelAt(i,j).color = (averageRed, averageGreen,
averageBlue)
}
}
Examples:
Example 1: Tree – blurRadius 1
https://course.cse.ust.hk/comp1022p/assignments/pa1/
13/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
Original
Example 2: Tree – blurRadius 3
Blurred
Original
Example 3: Tree – blurRadius 7
Blurred
Original
Example 4: Panda – blurRadius 7
Blurred
Original
Blurred
You can see that the pixels along the edges are not blurred because they don’t have enough neighbors
https://course.cse.ust.hk/comp1022p/assignments/pa1/
14/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
Blurring values in “ImageFrame.java”: 0, 1, 2, 3, …, 7, then reverse. If your code encounter bugs when radius = 0, you may just return a copy of the input image in this case. Resulting gif image using the assignment program with “panda.jpg” (The image shown below is lossy compressed)
Animated
(click to stop animation)
End of Description – Part B
Appendix Inverting an image
This part provides you with a sample solution to another effect “invert”. You may follow the idea of the given codes and write your codes for the assignment tasks. The effect of this part can only be viewed after you finished the Blending two images effect.
Given an image in 24-bit format, implement image invert according to the description below. The following gives the method header of the image processing routine:
Input:
bi is a reference variable to the input buffered image. Output:
the returned value is a reference to the resulting image. Algorithm in pseudo-code:
// Input: image
For each pixel at coordinates (i, j) in the resulting image {
inverted red value = 255 – image.redColorAt(i,j)
inverted green value = 255 – image.greenColorAt(i,j)
inverted blue value = 255 – image.blueColorAt(i,j)
resultingImage.pixelAt(i,j).color = (invertedRed, invertedGreen, invertedBlue)
}
Examples:
Example 1: Foobar
public static BufferedImage invert(BufferedImage bi)
https://course.cse.ust.hk/comp1022p/assignments/pa1/
15/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
Original Example 2: Dog
Original Example 3: Yellow Rabbit
Inverted
Inverted
Original
Inverted
Resulting gif image using the assignment program with “rabbit.jpg”: (The image shown below is lossy compressed)
Animated
(click to stop animation)
Sample Solution:
(This piece of code can also be found in “ImageProcessor.java”)
https://course.cse.ust.hk/comp1022p/assignments/pa1/
16/21
4/1/2019 COMP 1022P Assignment 1: Animated Meme Maker!
// Assignment B – Sample Code
public static BufferedImage invert(BufferedImage bi) {
// create a new buffered image to be output as the result BufferedImage result = new BufferedImage(bi.getWidth(), bi.getHeight(),
BufferedImage.TYPE_INT_RGB);
// loop through every RESULTING IMAGE’s pixel (point) for (int x = 0; x < bi.getWidth(); x++) {
for (int y = 0; y < bi.getHeight(); y++) {
// for each pixel, obtain its previous RGB values
// its new RGB values are:
// newR = 255 - oldR, same with R and B
Color color = new Color(bi.getRGB(x, y));
int ir = 255 - color.getRed();
int ig = 255 - color.getGreen();
int ib = 255 - color.getBlue();
Color inversedColor = new Color(ir, ig, ib);
// set the color of the resulting image's corresponding pixel result.setRGB(x, y, inversedColor.getRGB());
} }
return result; }
End of Appendix
Programming Tips
1. What is method in Java?
A Java method is a collection of statements that are grouped together to perform an operation. The following shows the syntax of a method:
where
Example:
public static
}
https://course.cse.ust.hk/comp1022p/assignments/pa1/
17/21