init
This commit is contained in:
35
c2/mondrian/Client.java
Normal file
35
c2/mondrian/Client.java
Normal file
@@ -0,0 +1,35 @@
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
|
||||
public class Client {
|
||||
public static void main(String[] args) throws Exception {
|
||||
Scanner console = new Scanner(System.in);
|
||||
System.out.println("Welcome to the CSE 123 Mondrian Art Generator!");
|
||||
|
||||
int choice = 0;
|
||||
while (choice != 1 && choice != 2) {
|
||||
System.out.print("Enter 1 for a basic Mondrian or 2 for a complex Mondrian: ");
|
||||
choice = console.nextInt();
|
||||
}
|
||||
System.out.print("Enter image width (>= 300px): ");
|
||||
int width = console.nextInt();
|
||||
System.out.print("Enter image height (>= 300px): ");
|
||||
int height = console.nextInt();
|
||||
|
||||
Mondrian mond = new Mondrian();
|
||||
Picture pic = new Picture(width, height);
|
||||
Color[][] pixels = pic.getPixels();
|
||||
|
||||
if (choice == 1) {
|
||||
mond.paintBasicMondrian(pixels);
|
||||
} else { // choice == 2
|
||||
mond.paintComplexMondrian(pixels);
|
||||
}
|
||||
|
||||
pic.setPixels(pixels);
|
||||
pic.save(choice == 1 ? "basic.png" : "extension.png");
|
||||
pic.show();
|
||||
System.out.println("Enjoy your artwork!");
|
||||
}
|
||||
}
|
||||
|
||||
97
c2/mondrian/Mondrian.java
Normal file
97
c2/mondrian/Mondrian.java
Normal file
@@ -0,0 +1,97 @@
|
||||
import java.awt.*;
|
||||
import java.util.Random;
|
||||
|
||||
public class Mondrian {
|
||||
|
||||
private int canvasWidth;
|
||||
private int canvasHeight;
|
||||
private static final int MIN_REGION_SIZE = 10;
|
||||
private Random rand;
|
||||
|
||||
public void paintBasicMondrian(Color[][] pixels) {
|
||||
rand = new Random();
|
||||
int width = pixels[0].length;
|
||||
int height = pixels.length;
|
||||
this.canvasWidth = width;
|
||||
this.canvasHeight = height;
|
||||
|
||||
divideCanvas(pixels, 0, width, 0, height);
|
||||
}
|
||||
|
||||
public void paintComplexMondrian(Color[][] pixels) {
|
||||
|
||||
}
|
||||
|
||||
private void divideCanvas(Color[][] pixels, int x1, int x2, int y1, int y2) {
|
||||
if (x2 - x1 >= MIN_REGION_SIZE * 3 && y2 - y1 >= MIN_REGION_SIZE * 3) {
|
||||
//int hSplit = (x2 - x1) / 2 + x1;
|
||||
//int vSplit = (y2 - y1) / 2 + y1;
|
||||
|
||||
int hSplit = rand.nextInt(x1+1, x2-10);
|
||||
int vSplit = rand.nextInt(y1+1, y2-10);
|
||||
|
||||
//if (x2 - x1 >= canvasWidth / 4) {
|
||||
//int rangeX = (x2 - x1 - MIN_REGION_SIZE * 2) / MIN_REGION_SIZE;
|
||||
// hSplit = rand.nextInt(rangeX) * MIN_REGION_SIZE + x1 + MIN_REGION_SIZE;
|
||||
// hSplit = Math.min(hSplit, x2 - MIN_REGION_SIZE); // Ensure hSplit is within canvas bounds
|
||||
// hSplit = Math.max(hSplit, x1 + MIN_REGION_SIZE); // Ensure hSplit is at least MIN_REGION_SIZE away from the canvas edge
|
||||
//}
|
||||
|
||||
//if (y2 - y1 >= canvasHeight / 4) {
|
||||
// int rangeY = (y2 - y1 - MIN_REGION_SIZE * 2) / MIN_REGION_SIZE;
|
||||
// vSplit = rand.nextInt(rangeY) * MIN_REGION_SIZE + y1 + MIN_REGION_SIZE;
|
||||
// vSplit = Math.min(vSplit, y2 - MIN_REGION_SIZE); // Ensure vSplit is within canvas bounds
|
||||
// vSplit = Math.max(vSplit, y1 + MIN_REGION_SIZE); // Ensure vSplit is at least MIN_REGION_SIZE away from the canvas edge
|
||||
//}
|
||||
|
||||
//// Additional constraints for the horizontal splitting points to prevent rectangles wider than canvasWidth/4
|
||||
//if (x2 - x1 >= canvasWidth / 4) {
|
||||
// hSplit = Math.min(hSplit, x1 + (x2 - x1) / 2); // Ensure hSplit is not farther than halfway across the canvas
|
||||
//}
|
||||
|
||||
fill(pixels, x1, x2, y1, y2);
|
||||
|
||||
if (x2 - x1 >= canvasWidth / 4 && y2 - y1 >= canvasHeight / 4) {
|
||||
divideCanvas(pixels, x1, hSplit, y1, vSplit);
|
||||
divideCanvas(pixels, hSplit, x2, y1, vSplit);
|
||||
divideCanvas(pixels, x1, hSplit, vSplit, y2);
|
||||
divideCanvas(pixels, hSplit, x2, vSplit, y2);
|
||||
} else if (x2 - x1 >= canvasWidth / 4) {
|
||||
divideCanvas(pixels, x1, hSplit, y1, y2);
|
||||
divideCanvas(pixels, hSplit, x2, y1, y2);
|
||||
} else if (y2 - y1 >= canvasHeight / 4) {
|
||||
divideCanvas(pixels, x1, x2, y1, vSplit);
|
||||
divideCanvas(pixels, x1, x2, vSplit, y2);
|
||||
}
|
||||
} else {
|
||||
fill(pixels, x1, x2, y1, y2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void fill(Color[][] pixels, int x1, int x2, int y1, int y2) {
|
||||
Color region = getRandomColor();
|
||||
for (int i = y1; i < y2; i++) {
|
||||
pixels[i][x1] = Color.BLACK;
|
||||
pixels[i][x2 - 1] = Color.BLACK;
|
||||
}
|
||||
|
||||
for (int j = x1; j < x2; j++) {
|
||||
pixels[y1][j] = Color.BLACK;
|
||||
pixels[y2 - 1][j] = Color.BLACK;
|
||||
}
|
||||
|
||||
for (int i = y1 + 1; i < y2 - 1; i++) {
|
||||
for (int j = x1 + 1; j < x2 - 1; j++) {
|
||||
pixels[i][j] = region;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Color getRandomColor() {
|
||||
Color[] colors = {Color.RED, Color.YELLOW, Color.CYAN, Color.WHITE};
|
||||
return colors[rand.nextInt(4)];
|
||||
}
|
||||
}
|
||||
|
||||
505
c2/mondrian/Picture.java
Normal file
505
c2/mondrian/Picture.java
Normal file
@@ -0,0 +1,505 @@
|
||||
/******************************************************************************
|
||||
* Compilation: javac Picture.java
|
||||
* Execution: java Picture imagename
|
||||
* Dependencies: none
|
||||
*
|
||||
* Data type for manipulating individual pixels of an image. The original
|
||||
* image can be read from a file in JPG, GIF, or PNG format, or the
|
||||
* user can create a blank image of a given dimension. Includes methods for
|
||||
* displaying the image in a window on the screen or saving to a file.
|
||||
*
|
||||
* % java Picture mandrill.jpg
|
||||
*
|
||||
* Remarks
|
||||
* -------
|
||||
* - pixel (x, y) is column x and row y, where (0, 0) is upper left
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.FileDialog;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
|
||||
/**
|
||||
* This class provides methods for manipulating individual pixels of
|
||||
* an image using the RGB color format. The alpha component (for transparency)
|
||||
* is not currently supported.
|
||||
* The original image can be read from a {@code PNG}, {@code GIF},
|
||||
* or {@code JPEG} file or the user can create a blank image of a given dimension.
|
||||
* This class includes methods for displaying the image in a window on
|
||||
* the screen or saving it to a file.
|
||||
* <p>
|
||||
* Pixel (<em>col</em>, <em>row</em>) is column <em>col</em> and row <em>row</em>.
|
||||
* By default, the origin (0, 0) is the pixel in the top-left corner,
|
||||
* which is a common convention in image processing.
|
||||
* The method {@link #setOriginLowerLeft()} change the origin to the lower left.
|
||||
* <p>
|
||||
* The {@code get()} and {@code set()} methods use {@link Color} objects to get
|
||||
* or set the color of the specified pixel.
|
||||
* The {@code getRGB()} and {@code setRGB()} methods use a 32-bit {@code int}
|
||||
* to encode the color, thereby avoiding the need to create temporary
|
||||
* {@code Color} objects. The red (R), green (G), and blue (B) components
|
||||
* are encoded using the least significant 24 bits.
|
||||
* Given a 32-bit {@code int} encoding the color, the following code extracts
|
||||
* the RGB components:
|
||||
* <blockquote><pre>
|
||||
* int r = (rgb >> 16) & 0xFF;
|
||||
* int g = (rgb >> 8) & 0xFF;
|
||||
* int b = (rgb >> 0) & 0xFF;
|
||||
* </pre></blockquote>
|
||||
* Given the RGB components (8-bits each) of a color,
|
||||
* the following statement packs it into a 32-bit {@code int}:
|
||||
* <blockquote><pre>
|
||||
* int rgb = (r << 16) + (g << 8) + (b << 0);
|
||||
* </pre></blockquote>
|
||||
* <p>
|
||||
* A <em>W</em>-by-<em>H</em> picture uses ~ 4 <em>W H</em> bytes of memory,
|
||||
* since the color of each pixel is encoded as a 32-bit <code>int</code>.
|
||||
* <p>
|
||||
* For additional documentation, see
|
||||
* <a href="https://introcs.cs.princeton.edu/31datatype">Section 3.1</a> of
|
||||
* <i>Computer Science: An Interdisciplinary Approach</i>
|
||||
* by Robert Sedgewick and Kevin Wayne.
|
||||
* See {@link GrayscalePicture} for a version that supports grayscale images.
|
||||
*
|
||||
* @author Robert Sedgewick
|
||||
* @author Kevin Wayne
|
||||
*/
|
||||
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
|
||||
|
||||
/**
|
||||
* Creates a {@code width}-by-{@code height} picture, with {@code width} columns
|
||||
* and {@code height} rows, where each pixel is black.
|
||||
*
|
||||
* @param width the width of the picture
|
||||
* @param height the height of the picture
|
||||
* @throws IllegalArgumentException if {@code width} is negative or zero
|
||||
* @throws IllegalArgumentException if {@code height} is negative or zero
|
||||
*/
|
||||
public Picture(int width, int height) {
|
||||
if (width <= 0) throw new IllegalArgumentException("width must be positive");
|
||||
if (height <= 0) throw new IllegalArgumentException("height must be positive");
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
// set to TYPE_INT_ARGB here and in next constructor to support transparency
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new picture that is a deep copy of the argument picture.
|
||||
*
|
||||
* @param picture the picture to copy
|
||||
* @throws IllegalArgumentException if {@code picture} is {@code null}
|
||||
*/
|
||||
public Picture(Picture picture) {
|
||||
if (picture == null) throw new IllegalArgumentException("constructor argument is null");
|
||||
|
||||
width = picture.width();
|
||||
height = picture.height();
|
||||
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
filename = picture.filename;
|
||||
isOriginUpperLeft = picture.isOriginUpperLeft;
|
||||
for (int col = 0; col < width(); col++)
|
||||
for (int row = 0; row < height(); row++)
|
||||
image.setRGB(col, row, picture.image.getRGB(col, row));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a picture by reading an image from a file or URL.
|
||||
*
|
||||
* @param name the name of the file (.png, .gif, or .jpg) or URL.
|
||||
* @throws IllegalArgumentException if cannot read image
|
||||
* @throws IllegalArgumentException if {@code name} is {@code null}
|
||||
*/
|
||||
public Picture(String name) {
|
||||
if (name == null) throw new IllegalArgumentException("constructor argument is null");
|
||||
|
||||
this.filename = name;
|
||||
try {
|
||||
// try to read from file in working directory
|
||||
File file = new File(name);
|
||||
if (file.isFile()) {
|
||||
image = ImageIO.read(file);
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
// resource relative to .class file
|
||||
URL url = getClass().getResource(filename);
|
||||
|
||||
// resource relative to classloader root
|
||||
if (url == null) {
|
||||
url = getClass().getClassLoader().getResource(name);
|
||||
}
|
||||
|
||||
// or URL from web
|
||||
if (url == null) {
|
||||
url = new URL(name);
|
||||
}
|
||||
|
||||
image = ImageIO.read(url);
|
||||
}
|
||||
|
||||
if (image == null) {
|
||||
throw new IllegalArgumentException("could not read image: " + name);
|
||||
}
|
||||
|
||||
width = image.getWidth(null);
|
||||
height = image.getHeight(null);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
throw new IllegalArgumentException("could not open image: " + name, ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a picture by reading the image from a PNG, GIF, or JPEG file.
|
||||
*
|
||||
* @param file the file
|
||||
* @throws IllegalArgumentException if cannot read image
|
||||
* @throws IllegalArgumentException if {@code file} is {@code null}
|
||||
*/
|
||||
public Picture(File file) {
|
||||
if (file == null) throw new IllegalArgumentException("constructor argument is null");
|
||||
|
||||
try {
|
||||
image = ImageIO.read(file);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
throw new IllegalArgumentException("could not open file: " + file, ioe);
|
||||
}
|
||||
if (image == null) {
|
||||
throw new IllegalArgumentException("could not read file: " + file);
|
||||
}
|
||||
width = image.getWidth(null);
|
||||
height = image.getHeight(null);
|
||||
filename = file.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link JLabel} containing this picture, for embedding in a {@link JPanel},
|
||||
* {@link JFrame} or other GUI widget.
|
||||
*
|
||||
* @return the {@code JLabel}
|
||||
*/
|
||||
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. This is the default.
|
||||
*/
|
||||
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);
|
||||
// use getMenuShortcutKeyMaskEx() in Java 10 (getMenuShortcutKeyMask() deprecated)
|
||||
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);
|
||||
if (filename == null) frame.setTitle(width + "-by-" + height);
|
||||
else frame.setTitle(filename);
|
||||
frame.setResizable(false);
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
// draw
|
||||
frame.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the height of the picture.
|
||||
*
|
||||
* @return the height of the picture (in pixels)
|
||||
*/
|
||||
public int height() {
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width of the picture.
|
||||
*
|
||||
* @return the width of the picture (in pixels)
|
||||
*/
|
||||
public int width() {
|
||||
return width;
|
||||
}
|
||||
|
||||
private void validateRowIndex(int row) {
|
||||
if (row < 0 || row >= height())
|
||||
throw new IllegalArgumentException("row index must be between 0 and " + (height() - 1) + ": " + row);
|
||||
}
|
||||
|
||||
private void validateColumnIndex(int col) {
|
||||
if (col < 0 || col >= width())
|
||||
throw new IllegalArgumentException("column index must be between 0 and " + (width() - 1) + ": " + col);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color of pixel ({@code col}, {@code row}) as a {@link java.awt.Color}.
|
||||
*
|
||||
* @param col the column index
|
||||
* @param row the row index
|
||||
* @return the color of pixel ({@code col}, {@code row})
|
||||
* @throws IllegalArgumentException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
|
||||
*/
|
||||
public Color get(int col, int row) {
|
||||
validateColumnIndex(col);
|
||||
validateRowIndex(row);
|
||||
int rgb = getRGB(col, row);
|
||||
return new Color(rgb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color of pixel ({@code col}, {@code row}) as an {@code int}.
|
||||
* Using this method can be more efficient than {@link #get(int, int)} because
|
||||
* it does not create a {@code Color} object.
|
||||
*
|
||||
* @param col the column index
|
||||
* @param row the row index
|
||||
* @return the integer representation of the color of pixel ({@code col}, {@code row})
|
||||
* @throws IllegalArgumentException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
|
||||
*/
|
||||
public int getRGB(int col, int row) {
|
||||
validateColumnIndex(col);
|
||||
validateRowIndex(row);
|
||||
if (isOriginUpperLeft) return image.getRGB(col, row);
|
||||
else return image.getRGB(col, height - row - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color of pixel ({@code col}, {@code row}) to given color.
|
||||
*
|
||||
* @param col the column index
|
||||
* @param row the row index
|
||||
* @param color the color
|
||||
* @throws IllegalArgumentException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
|
||||
* @throws IllegalArgumentException if {@code color} is {@code null}
|
||||
*/
|
||||
public void set(int col, int row, Color color) {
|
||||
validateColumnIndex(col);
|
||||
validateRowIndex(row);
|
||||
if (color == null) throw new IllegalArgumentException("color argument is null");
|
||||
int rgb = color.getRGB();
|
||||
setRGB(col, row, rgb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color of pixel ({@code col}, {@code row}) to given color.
|
||||
*
|
||||
* @param col the column index
|
||||
* @param row the row index
|
||||
* @param rgb the integer representation of the color
|
||||
* @throws IllegalArgumentException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
|
||||
*/
|
||||
public void setRGB(int col, int row, int rgb) {
|
||||
validateColumnIndex(col);
|
||||
validateRowIndex(row);
|
||||
if (isOriginUpperLeft) image.setRGB(col, row, rgb);
|
||||
else image.setRGB(col, height - row - 1, rgb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this picture is equal to the argument picture.
|
||||
*
|
||||
* @param other the other picture
|
||||
* @return {@code true} if this picture is the same dimension as {@code other}
|
||||
* and if all pixels have the same color; {@code false} otherwise
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (other == this) return true;
|
||||
if (other == null) return false;
|
||||
if (other.getClass() != this.getClass()) return false;
|
||||
Picture that = (Picture) other;
|
||||
if (this.width() != that.width()) return false;
|
||||
if (this.height() != that.height()) return false;
|
||||
for (int col = 0; col < width(); col++)
|
||||
for (int row = 0; row < height(); row++)
|
||||
if (this.getRGB(col, row) != that.getRGB(col, row)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this picture.
|
||||
* The result is a <code>width</code>-by-<code>height</code> matrix of pixels,
|
||||
* where the color of a pixel is represented using 6 hex digits to encode
|
||||
* the red, green, and blue components.
|
||||
*
|
||||
* @return a string representation of this picture
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(width +"-by-" + height + " picture (RGB values given in hex)\n");
|
||||
for (int row = 0; row < height; row++) {
|
||||
for (int col = 0; col < width; col++) {
|
||||
int rgb = 0;
|
||||
if (isOriginUpperLeft) rgb = image.getRGB(col, row);
|
||||
else rgb = image.getRGB(col, height - row - 1);
|
||||
sb.append(String.format("#%06X ", rgb & 0xFFFFFF));
|
||||
}
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* This operation is not supported because pictures are mutable.
|
||||
*
|
||||
* @return does not return a value
|
||||
* @throws UnsupportedOperationException if called
|
||||
*/
|
||||
public int hashCode() {
|
||||
throw new UnsupportedOperationException("hashCode() is not supported because pictures are mutable");
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the picture to a file in either PNG or JPEG format.
|
||||
* The filetype extension must be either .png or .jpg.
|
||||
*
|
||||
* @param name the name of the file
|
||||
* @throws IllegalArgumentException if {@code name} is {@code null}
|
||||
*/
|
||||
public void save(String name) {
|
||||
if (name == null) throw new IllegalArgumentException("argument to save() is null");
|
||||
save(new File(name));
|
||||
filename = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the picture to a file in a PNG or JPEG image format.
|
||||
*
|
||||
* @param file the file
|
||||
* @throws IllegalArgumentException if {@code file} is {@code null}
|
||||
*/
|
||||
public void save(File file) {
|
||||
if (file == null) throw new IllegalArgumentException("argument to save() is null");
|
||||
filename = file.getName();
|
||||
if (frame != null) frame.setTitle(filename);
|
||||
String suffix = filename.substring(filename.lastIndexOf('.') + 1);
|
||||
if ("jpg".equalsIgnoreCase(suffix) || "png".equalsIgnoreCase(suffix)) {
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit tests this {@code Picture} data type.
|
||||
* Reads a picture specified by the command-line argument,
|
||||
* and shows it in a window on the screen.
|
||||
*
|
||||
* @param args the command-line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
Picture picture = new Picture(args[0]);
|
||||
System.out.printf("%d-by-%d\n", picture.width(), picture.height());
|
||||
picture.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pixels in the picture as a two-dimensional array.
|
||||
*
|
||||
* @return a two-dimensional array of the colors of the pixels in the picture.
|
||||
*/
|
||||
public Color[][] getPixels() {
|
||||
Color[][] pixels = new Color[height][width];
|
||||
for (int i = 0; i < width; i++) {
|
||||
for (int j = 0; j < height; j++) {
|
||||
pixels[j][i] = get(i, j);
|
||||
}
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all pixels in the picture based on the given two-dimensional array.
|
||||
*
|
||||
* @param pixels the new colors of the pixels for the picture
|
||||
* @throws IllegalArgumentException if the dimensions of {@code pixels} do not match
|
||||
* the dimensions of the picture
|
||||
*/
|
||||
public void setPixels(Color[][] pixels) {
|
||||
if (pixels.length != height || pixels[0].length != width) {
|
||||
throw new IllegalArgumentException("Wrong dimensions of pixel array");
|
||||
}
|
||||
|
||||
for (int i = 0; i < width; i++) {
|
||||
for (int j = 0; j < height; j++) {
|
||||
set(i, j, pixels[j][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
c2/mondrian/basic.png
Normal file
BIN
c2/mondrian/basic.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
2
c2/mondrian/compile.sh
Executable file
2
c2/mondrian/compile.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
javac *.java && java Client && rm *.class
|
||||
Reference in New Issue
Block a user