- Modify a single pixel in an image: Write
your first image processing code. For example create a class named
MyImageAlgorithms with the method oneRedDot as
shown below. Compile your saved code using the javac tool.
import algoritharium.*;
import java.awt.Color;
public class MyImageAlgorithms {
public void oneRedDot ( ) {
Image img =
ImageViewer.getImage( ) ;
img.setPixelColor(20, 20, Color .RED) ;
}
}
Run the Algoritharium program
using the java tool or double click on the jar file.
- Select File-New to get a small
yellow image.
- Select Code-Load, navigate to and
open your MyImageAlgorithms.class file in the file chooser window.
- Select MyOps-oneRedDot.
- Modify several adjacent pixels in one row of the
image: Add another method to your MyImageAlgorithms class
definition called manyRedDots
public void manyRedDots ( ) {
Image img =
ImageViewer.getImage( ) ;
img.setPixelColor(20, 20, Color .RED) ;
img.setPixelColor(21, 20, Color .RED) ;
img.setPixelColor(22, 20, Color .RED) ;
img.setPixelColor(23, 20, Color .RED) ;
}
Save and compile your program.
- Select Code-Reload.
- Select MyOps-manyRedDots
- Use iteration to modify
several adjacent pixels in one row of the image: Add another
method to your MyImageAlgorithms class definition called loopRedDots
public void loopRedDots ( ) {
Image img =
ImageViewer.getImage( ) ;
for(int i = 20; i
<= 23; i++)
img.setPixelColor(i, 20, Color .RED);
}
Save and compile your program.
- Select File-New to get a clean
yellow image
- Select Code-Reload.
- Select MyOps-loopRedDots
- Make entire image red: Add another
method to your MyImageAlgorithms class definition called turnImageRed
public void turnImageRed ( ) {
Image img =
ImageViewer.getImage( ) ;
for(int i = 0; i
< img.getWidth(); i++)
for(int j = 0; j < img.getHeight(); j++)
img.setPixelColor(i, j, Color .RED);
}
Save and compile your program.
- Select Code-Reload.
- Select MyOps-turnImageRed
- Red/green checkerboard: Add two methods
to your MyImageAlgorithms class definition called redGreenCheckerboard
and changeColor
public void redGreenCheckerboard ( ) {
Image img = ImageViewer.getImage( ) ;
Color[][] c = img.getPixelColors();
Color currentColor = Color.red;
for (int i = 0; i < c.length; i++) {
if (i %20 == 0)
currentColor = changeColor(currentColor);
for (int j = 0; j
< c[i].length; j++) {
if (j %20 == 0) currentColor = changeColor(currentColor);
c[i][j] = currentColor;
}
}
img.setPixelColors(c);
}
public Color changeColor (Color c ) {
if (c == Color.GREEN)
return Color.red;
else
return Color.green;
}
Save and compile your program.
- Select Code-Reload.
- Select MyOps-redGreenCheckerboard
- Implement a red filter: Add another
method to your MyImageAlgorithms class definition called redFilter
public void redFilter ( ) {
Image img =
ImageViewer.getImage( ) ;
Color c1, c2;
for(int i = 0; i
< img.getWidth(); i++)
for(int j = 0; j < img.getHeight(); j++) {
c1 = img.getPixelColor (i, j);
c2 = new Color (c1.getRed(), 0, 0);
img.setPixelColor(i, j, c2);
}
}
Save and compile your program.
- Select Code-Reload.
- Select MyOps-redFilter
- For a more stunning effect save MtCastle.ppm (Right-click
and select Save Target As...)
- Select File-Open, then select and open MtCastle in your
viewer, then apply redFilter
- Image algorithms involving multiple images:
Add another method to your MyImageAlgorithms class definition called multipleImages
A more robust approach to multiple images involves using
the viewer ID. Here we open a new image viewer using the
current viewer's image as the source for our target image viewer. In
this way we can manipulate the target image and see the differences
between the original (source) image and modified (target) image. Note:
Selecting File-Exit
will shutdown that image viewer, but clicking on
the red X in the corner of any image viewer opened in the same session
will shutdown all of the viewers.
public void
multipleImages() {
Image source =
ImageViewer.getImage();
ImageViewer iv = new
ImageViewer();
ImageViewer.setImage(iv.getViewerId(), source);
Image target =
ImageViewer.getImage(iv.getViewerId());
Color[][] c =
source.getPixelColors();
//Some code to modify c
target.setPixelColors(c);
}
Save and compile your program.
- Select File-New or File-Open to place an
image in the viewer
- Select Code-Reload.following each
modification to your compiled source code
- Select MyOps-multipleImages
- Image algorithms involving multiple images and
include an update to the Title Bar:
Add another method to your MyImageAlgorithms class definition called removeOneOfRGB. Here
we create multiple images using
the viewer ID. Additionally, the title bar is updated in the
instanctiated image viewers keeping the Viewer ID while adding
additional information regarding the average of the red,
green, and blue pixel intensities across the entire image in the title
bar.
public void removeOneOfRGB() {
Image source = ImageViewer.getImage();
ImageViewer ivR = new ImageViewer();
ImageViewer ivG = new ImageViewer();
ImageViewer ivB = new ImageViewer();
ImageViewer.setImage(ivR.getViewerId(),
source);
ImageViewer.setImage(ivG.getViewerId(),
source);
ImageViewer.setImage(ivB.getViewerId(),
source);
removeImageRed(ImageViewer.getImage(ivR.getViewerId()));
removeImageGreen(ImageViewer.getImage(ivG.getViewerId()));
removeImageBlue(ImageViewer.getImage(ivB.getViewerId()));
int[] data =
pixelIntensities(ImageViewer.getImage(ivR.getViewerId()).getPixelColors());
ivR.setTitle(ivR.getTitle()+ " - Red
removed - R:"+data[0]+" G:"+data[1]+" B:"+data[2]);
data =
pixelIntensities(ImageViewer.getImage(ivG.getViewerId()).getPixelColors());
ivG.setTitle(ivG.getTitle()+ " - Green
removed - R:"+data[0]+" G:"+data[1]+" B:"+data[2]);
data =
pixelIntensities(ImageViewer.getImage(ivB.getViewerId()).getPixelColors());
ivB.setTitle(ivB.getTitle()+ " - Blue
removed - R:"+data[0]+" G:"+data[1]+" B:"+data[2]);
}
private int[] pixelIntensities(Color[][] c) {
int p, r, g, b, w, h, sumR, sumG, sumB;
int[] rGBSignature = new int[3];
w = c[0].length;
h = c.length;
for (int x = 0; x < w; x++) {
sumR = sumG
= sumB = 0;
for (int y
= 0; y < h; y++) {
p
= c[y][x].getRGB();
r
= (p >> 16) & 0xff;
g
= (p >> 8) & 0xff;
b
= (p & 0xff);
sumR
+= r;
sumG
+= g;
sumB
+= b;
}
rGBSignature[0]+=sumR/h;
rGBSignature[1]+=sumG/h;
rGBSignature[2]+=sumB/h;
}
rGBSignature[0]/=w;
rGBSignature[1]/=w;
rGBSignature[2]/=w;
return rGBSignature;
}
- Collecting
user input:
An easy way to collect user input while the program is running is to
use the Scanner class. This works if your MyImageAlgorithms has a main
method that launches a viewer per the previous step. Here is a sample
function that copies a rectangle in one image and places it in another.
This code depends on the user to duplicate the ImageViewer and open an
image in each.
public void copyRectangle()
{
Scanner s = new Scanner(System.in);
System.out.println("Enter top left x:");
int startX
= s.nextInt();
System.out.println("Enter top left y:");
int startY
= s.nextInt();
System.out.println("Enter bottom right x:");
int endX
= s.nextInt();
System.out.println("Enter bottom right y: ");
int endY
= s.nextInt();
Image srcImg = ImageViewer.getImage(2);
Image destImg = ImageViewer.getImage();
Color[][] c = srcImg.getRectangle(startX, startY,
endX - startX, endY- startY);
System.out.println("Enter destination top left
x:");
int destX
= s.nextInt();
System.out.println("Enter destinatino top left
y:");
int destY
= s.nextInt();
destImg.setRectangle(destX, destY, c);
}
My
program runs out of memory, but my system should have more than
enough. What's going on? The java
heap is the
area of RAM reserved for use by the Java virtual machine. You can
specifically ask for more (assuming your system has enough) with the
following command:
% java -Xmx300m -Xms300m -jar algoritharium.jar
|
In
this case, we are asking for 300 MB of memory (note no space between
the switch and size and correct units are none for bytes, k for
kilobytes, m for
megabytes,M for
megabytes, or g for
gigabytes.) The -Xmx sets
the maximum heap size, the -Xms flag
sets the initial heap size. The operating system determines whether
physical ram or paging will be used to achieve the requested memory.