In: Computer Science
package imageblocks;
import java.awt.Color;
import utils.Picture;
public class ImageBlocks {
static Color BLACK = new Color(0,0,0);
static Color WHITE = new Color(255,255,255);
private int height;
private int width;
boolean [][] visited;
Picture pic;
public ImageBlocks(Picture pic) {
this.pic = pic;
height = pic.height();
width = pic.width();
}
private boolean isBlack(int x,int y){
return pic.get(x,y).equals(BLACK);
}
private boolean isWhite(int x,int y){
return pic.get(x,y).equals(WHITE);
}
/**
* METHOD TO BE COMPLETED
* count the number of image blocks in the given image
* Counts the number of connected blocks in the binary digital
image
* @return number of black blocks
*/
public int countConnectedBlocks(){
//TODO
}
}
== Picture Class for Help ==
public final class Picture implements ActionListener {
private BufferedImage image; // the rasterized image
private JFrame frame; // on-screen view
private String filename; // name of file
private boolean isOriginUpperLeft = true; // location of origin
private final int width, height; // width and height
/**
* Initializes a blank <tt>w</tt>-by-<tt>h</tt> picture, where each pixel is black.
*/
public Picture(int w, int h) {
if (w < 0) throw new IllegalArgumentException("width must be nonnegative");
if (h < 0) throw new IllegalArgumentException("height must be nonnegative");
width = w;
height = h;
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
// set to TYPE_INT_ARGB to support transparency
filename = w + "-by-" + h;
}
/**
* Initializes a new picture that is a deep copy of <tt>pic</tt>.
*/
public Picture(Picture pic) {
width = pic.width();
height = pic.height();
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
filename = pic.filename;
for (int x = 0; x < width(); x++)
for (int y = 0; y < height(); y++)
image.setRGB(x, y, pic.get(x, y).getRGB());
}
/**
* Initializes a picture by reading in a .png, .gif, or .jpg from
* the given filename or URL name.
*/
public Picture(String filename) {
this.filename = filename;
try {
// try to read from file in working directory
File file = new File(filename);
if (file.isFile()) {
image = ImageIO.read(file);
}
// now try to read from file in same directory as this .class file
else {
URL url = getClass().getResource(filename);
if (url == null) { url = new URL(filename); }
image = ImageIO.read(url);
}
width = image.getWidth(null);
height = image.getHeight(null);
}
catch (IOException e) {
// e.printStackTrace();
throw new RuntimeException("Could not open file: " + filename);
}
}
/**
* Initializes a picture by reading in a .png, .gif, or .jpg from a File.
*/
public Picture(File file) {
try { image = ImageIO.read(file); }
catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Could not open file: " + file);
}
if (image == null) {
throw new RuntimeException("Invalid image file: " + file);
}
width = image.getWidth(null);
height = image.getHeight(null);
filename = file.getName();
}
/**
* Returns a JLabel containing this picture, for embedding in a JPanel,
* JFrame or other GUI widget.
*/
public JLabel getJLabel() {
if (image == null) { return null; } // no image available
ImageIcon icon = new ImageIcon(image);
return new JLabel(icon);
}
/**
* Sets the origin to be the upper left pixel.
*/
public void setOriginUpperLeft() {
isOriginUpperLeft = true;
}
/**
* Sets the origin to be the lower left pixel.
*/
public void setOriginLowerLeft() {
isOriginUpperLeft = false;
}
/**
* Displays the picture in a window on the screen.
*/
public void show() {
// create the GUI for viewing the image if needed
if (frame == null) {
frame = new JFrame();
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
menuBar.add(menu);
JMenuItem menuItem1 = new JMenuItem(" Save... ");
menuItem1.addActionListener(this);
menuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
menu.add(menuItem1);
frame.setJMenuBar(menuBar);
frame.setContentPane(getJLabel());
// f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setTitle(filename);
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
}
// draw
frame.repaint();
}
/**
* Returns the height of the picture (in pixels).
*/
public int height() {
return height;
}
/**
* Returns the width of the picture (in pixels).
*/
public int width() {
return width;
}
/**
* Returns the color of pixel (<em>x</em>, <em>y</em>).
*/
public Color get(int x, int y) {
if (x < 0 || x >= width()) throw new IndexOutOfBoundsException("x must be between 0 and " + (width()-1));
if (y < 0 || y >= height()) throw new IndexOutOfBoundsException("y must be between 0 and " + (height()-1));
if (isOriginUpperLeft) return new Color(image.getRGB(x, y));
else return new Color(image.getRGB(x, height - y - 1));
}
/**
* Sets the color of pixel (<em>x</em>, <em>y</em>) to given color.
*/
public void set(int x, int y, Color color) {
if (x < 0 || x >= width()) throw new IndexOutOfBoundsException("x must be between 0 and " + (width()-1));
if (y < 0 || y >= height()) throw new IndexOutOfBoundsException("y must be between 0 and " + (height()-1));
if (color == null) throw new NullPointerException("can't set Color to null");
if (isOriginUpperLeft) image.setRGB(x, y, color.getRGB());
else image.setRGB(x, height - y - 1, color.getRGB());
}
/**
* Is this Picture equal to obj?
*/
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null) return false;
if (obj.getClass() != this.getClass()) return false;
Picture that = (Picture) obj;
if (this.width() != that.width()) return false;
if (this.height() != that.height()) return false;
for (int x = 0; x < width(); x++)
for (int y = 0; y < height(); y++)
if (!this.get(x, y).equals(that.get(x, y))) return false;
return true;
}
/**
* Saves the picture to a file in a standard image format.
* The filetype must be .png or .jpg.
*/
public void save(String name) {
save(new File(name));
}
/**
* Saves the picture to a file in a standard image format.
*/
public void save(File file) {
this.filename = file.getName();
if (frame != null) { frame.setTitle(filename); }
String suffix = filename.substring(filename.lastIndexOf('.') + 1);
suffix = suffix.toLowerCase();
if (suffix.equals("jpg") || suffix.equals("png")) {
try { ImageIO.write(image, suffix, file); }
catch (IOException e) { e.printStackTrace(); }
}
else {
System.out.println("Error: filename must end in .jpg or .png");
}
}
/**
* Opens a save dialog box when the user selects "Save As" from the menu.
*/
public void actionPerformed(ActionEvent e) {
FileDialog chooser = new FileDialog(frame,
"Use a .png or .jpg extension", FileDialog.SAVE);
chooser.setVisible(true);
if (chooser.getFile() != null) {
save(chooser.getDirectory() + File.separator + chooser.getFile());
}
}
public int countConnectedBlocks(Picture picture) {
if (picture.length == 0) {
return 0;
}
int blobCount = 0;
visited = new boolean[picture.length][picture[0].length];
for (int i = 0; i < picture.length; i++) {
for (int j = 0; j < picture[i].length; j++) {
if (!visited[i][j]) {
if (isBlack(i, j)) {
countHelper(i, j);
blobCount++;
}
visited[i][j] = true;
}
}
}
return blobCount;
}
private void countHelper(int i, int j) {
visited[i][j] = true;
if (isBlack(i, j)) {
for (int deltaI = -1; deltaI <= 1; deltaI++) {
for (int deltaJ = -1; deltaJ <= 1; deltaJ++) {
int adjI = i + deltaI;
int adjJ = j + deltaJ;
if (inBounds(adjI, adjJ) && !visited[adjI][adjJ]) {
countHelper(adjI, adjJ);
}
}
}
}
}
private boolean inBounds(int i, int j) {
return i >= 0 && j >= 0 && i < picture.length && j < picture[i].length;
}