This is to be programmed in Java. Write a library of static methods RawPicture w
ID: 3605442 • Letter: T
Question
This is to be programmed in Java.
Write a library of static methods RawPicture with read() and write() methods for saving and reading pictures from a file. The write method takes a Picture and the name of a file as arguments and writes the picture to the specified file, using the following format: if the picture is w-by-h,write w,then h, then w * h triples of integers representing the pixel color values,in row major order. The read() method takes the name of a picture file as an argument and returns a picture,which it creates by reading a picture from the specified file, in the format described. Note: Be aware that this will use up much more disk space than necessary-- the standard formats compress this information so that it will not take up so much space.
This is the original HW problem but I must meet the following criteria instead:
Do not write a library of static methods, but an instantiable Java class RawPicture. That is, each RawPicture should be an object that contains all its data in private fields. You will need members/fields/variables for:
Height.
Width.
All the pixel values, each of which is a Color triple. Use the java.awt.Color to represent each.
File name it was read from, if any.
File name it would be written to by the write() method.
Picture, for when you create a RawPicture from a Picture.
BifferedImage, for when you create a RawPicture from a file read into a BufferedImage (see below).
Use the IPJ Picture.java library to read in a GIF, JPG or PNG image from a file, and then the get() method to get the pixel values.
Your class should have four constructors:
A default constructor that creates an empty RawPicture. Afterwards it can be filled in with read() as specified below.
A constructor that takes a filename of a GIF, JPG or PNG image. Use the corresponding Picture constructor to read from file.
A constructor that takes a Picture. This is equivalent with the previous, but skips the reading from a file. You assume that the Picture has been initialized already.
A constructor that takes a filename of a GIF, JPG or PNG image, but does not use the Picture constructor directly. You should study the Picture(String filename) constructor for how a File is open and the data read into an image of the classes javax.imageio.ImageIO (Links to an external site.)Links to an external site. and java.awt.image.BufferedImage (Links to an external site.)Links to an external site. are used to read. Use this code to read the image. After performing this, you should still populate your own internal representation, contained in the first three fields specified above.
A constructor that takes a filename of a RAW (see below) image and reads it in. Note: We will talk about file I/O and show how it is done.
The read() and write() methods should not work with Picture objects.
read() should read a RawPicture from a RAW file (see below). Note: We will talk about file I/O and show how it is done.
write() should write from a RawPicture to a file. Use the extension RAW.
Explanation / Answer
// Picture.java
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.KeyStroke;
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>width</tt>-by-<tt>height</tt> picture, with <tt>width</tt> columns
* and <tt>height</tt> rows, where each pixel is black.
*/
public Picture(int width, int height) {
if (width < 0) throw new IllegalArgumentException("width must be nonnegative");
if (height < 0) throw new IllegalArgumentException("height must be nonnegative");
this.width = width;
this.height = height;
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// set to TYPE_INT_ARGB to support transparency
filename = width + "-by-" + height;
}
/**
* Initializes a new picture that is a deep copy of <tt>picture</tt>.
*/
public Picture(Picture picture) {
width = picture.width();
height = picture.height();
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
filename = picture.filename;
for (int col = 0; col < width(); col++)
for (int row = 0; row < height(); row++)
image.setRGB(col, row, picture.get(col, row).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.
* @return the <tt>JLabel</tt>
*/
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);
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.
* @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;
}
public Color get(int col, int row) {
if (col < 0 || col >= width()) throw new IndexOutOfBoundsException("col must be between 0 and " + (width()-1));
if (row < 0 || row >= height()) throw new IndexOutOfBoundsException("row must be between 0 and " + (height()-1));
if (isOriginUpperLeft) return new Color(image.getRGB(col, row));
else return new Color(image.getRGB(col, height - row - 1));
}
public void set(int col, int row, Color color) {
if (col < 0 || col >= width()) throw new IndexOutOfBoundsException("col must be between 0 and " + (width()-1));
if (row < 0 || row >= height()) throw new IndexOutOfBoundsException("row must be between 0 and " + (height()-1));
if (color == null) throw new NullPointerException("can't set Color to null");
if (isOriginUpperLeft) image.setRGB(col, row, color.getRGB());
else image.setRGB(col, height - row - 1, color.getRGB());
}
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 col = 0; col < width(); col++)
for (int row = 0; row < height(); row++)
if (!this.get(col, row).equals(that.get(col, row))) 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 static void main(String[] args) {
Picture picture = new Picture(args[0]);
System.out.printf("%d-by-%d ", picture.width(), picture.height());
picture.show();
}
}
===============================================================================
// RawPicture.java
import java.awt.Color;
public class RawPicture {
public static void read() {
int w = StdIn.readInt();
int h = StdIn.readInt();
Picture pic = new Picture(w,h);
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
int red = StdIn.readInt();
int green = StdIn.readInt();
int blue = StdIn.readInt();
pic.set(i, j, new Color(red, green, blue));
}
}
pic.show();
}
public static void write(String fileName) {
Picture pic = new Picture(fileName);
int w = pic.width();
int h = pic.height();
System.out.println(w + " " + h);
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
Color color = pic.get(i, j);
System.out.println(color.getRed() + " " + color.getGreen() + " " + color.getBlue());
}
}
}
public static void main(String[] args) {
read();
}
}
===================================================================================
// StdIn.java
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.Locale;
import java.util.Scanner;
import java.util.regex.Pattern;
public final class StdIn {
// it doesn't make sense to instantiate this class
private StdIn() { }
private static Scanner scanner;
/*** begin: section (1 of 2) of code duplicated from In to StdIn */
// assume Unicode UTF-8 encoding
private static final String CHARSET_NAME = "UTF-8";
// assume language = English, country = US for consistency with System.out.
private static final Locale LOCALE = Locale.US;
// the default token separator; we maintain the invariant that this value
// is held by the scanner's delimiter between calls
private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\p{javaWhitespace}+");
// makes whitespace characters significant
private static final Pattern EMPTY_PATTERN = Pattern.compile("");
// used to read the entire input
private static final Pattern EVERYTHING_PATTERN = Pattern.compile("\A");
public static boolean isEmpty() {
return !scanner.hasNext();
}
public static boolean hasNextLine() {
return scanner.hasNextLine();
}
public static boolean hasNextChar() {
scanner.useDelimiter(EMPTY_PATTERN);
boolean result = scanner.hasNext();
scanner.useDelimiter(WHITESPACE_PATTERN);
return result;
}
/**
* Reads and returns the next line, excluding the line separator if present.
* @return the next line, excluding the line separator if present
*/
public static String readLine() {
String line;
try { line = scanner.nextLine(); }
catch (Exception e) { line = null; }
return line;
}
public static char readChar() {
scanner.useDelimiter(EMPTY_PATTERN);
String ch = scanner.next();
assert (ch.length() == 1) : "Internal (Std)In.readChar() error!"
+ " Please contact the authors.";
scanner.useDelimiter(WHITESPACE_PATTERN);
return ch.charAt(0);
}
public static String readAll() {
if (!scanner.hasNextLine())
return "";
String result = scanner.useDelimiter(EVERYTHING_PATTERN).next();
// not that important to reset delimeter, since now scanner is empty
scanner.useDelimiter(WHITESPACE_PATTERN); // but let's do it anyway
return result;
}
/**
* Reads the next token and returns the <tt>String</tt>.
* @return the next <tt>String</tt>
*/
public static String readString() {
return scanner.next();
}
public static int readInt() {
return scanner.nextInt();
}
public static double readDouble() {
return scanner.nextDouble();
}
public static float readFloat() {
return scanner.nextFloat();
}
public static long readLong() {
return scanner.nextLong();
}
public static short readShort() {
return scanner.nextShort();
}
public static byte readByte() {
return scanner.nextByte();
}
public static boolean readBoolean() {
String s = readString();
if (s.equalsIgnoreCase("true")) return true;
if (s.equalsIgnoreCase("false")) return false;
if (s.equals("1")) return true;
if (s.equals("0")) return false;
throw new InputMismatchException();
}
/**
* Reads all remaining tokens from standard input and returns them as an array of strings.
* @return all remaining tokens on standard input, as an array of strings
*/
public static String[] readAllStrings() {
// we could use readAll.trim().split(), but that's not consistent
// because trim() uses characters 0x00..0x20 as whitespace
String[] tokens = WHITESPACE_PATTERN.split(readAll());
if (tokens.length == 0 || tokens[0].length() > 0)
return tokens;
// don't include first token if it is leading whitespace
String[] decapitokens = new String[tokens.length-1];
for (int i = 0; i < tokens.length - 1; i++)
decapitokens[i] = tokens[i+1];
return decapitokens;
}
/**
* Reads all remaining lines from standard input and returns them as an array of strings.
* @return all remaining lines on standard input, as an array of strings
*/
public static String[] readAllLines() {
ArrayList<String> lines = new ArrayList<String>();
while (hasNextLine()) {
lines.add(readLine());
}
return lines.toArray(new String[0]);
}
public static int[] readAllInts() {
String[] fields = readAllStrings();
int[] vals = new int[fields.length];
for (int i = 0; i < fields.length; i++)
vals[i] = Integer.parseInt(fields[i]);
return vals;
}
public static double[] readAllDoubles() {
String[] fields = readAllStrings();
double[] vals = new double[fields.length];
for (int i = 0; i < fields.length; i++)
vals[i] = Double.parseDouble(fields[i]);
return vals;
}
/*** end: section (2 of 2) of code duplicated from In to StdIn */
// do this once when StdIn is initialized
static {
resync();
}
/**
* If StdIn changes, use this to reinitialize the scanner.
*/
private static void resync() {
setScanner(new Scanner(new java.io.BufferedInputStream(System.in), CHARSET_NAME));
}
private static void setScanner(Scanner scanner) {
StdIn.scanner = scanner;
StdIn.scanner.useLocale(LOCALE);
}
public static int[] readInts() {
return readAllInts();
}
public static double[] readDoubles() {
return readAllDoubles();
}
public static String[] readStrings() {
return readAllStrings();
}
/**
* Interactive test of basic functionality.
*/
public static void main(String[] args) {
System.out.println("Type a string: ");
String s = StdIn.readString();
System.out.println("Your string was: " + s);
System.out.println();
System.out.println("Type an int: ");
int a = StdIn.readInt();
System.out.println("Your int was: " + a);
System.out.println();
System.out.println("Type a boolean: ");
boolean b = StdIn.readBoolean();
System.out.println("Your boolean was: " + b);
System.out.println();
System.out.println("Type a double: ");
double c = StdIn.readDouble();
System.out.println("Your double was: " + c);
System.out.println();
}
}
=====================================================================================
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.