我是编程的新手,我的一项任务是在java中转换图像。这部分专门说"调用镜像从上到下反转图像。要从上到下反转,请将第一行替换为最后一行,将第二行替换为倒数第二行,依此类推直到整个图像反转。"
这就是我现在所拥有的,但每当我调用镜像时,它只是将图像转换为一堆难以区分的线条。我迷失了如何处理这个问题!
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Scanner;
public class PictureLibrary {
// Maximum intensity
public static final int MAXVAL = 255;
// Image data
private int[][] image;
// Get image height
public int getHeight() {
return image.length;
}
// Get image width
public int getWidth() {
return image[0].length;
}
// Get image data
public int[][] getData() {
return image;
}
// Set image data
public void setData(int[][] data) {
image = data;
}
// Read PGM file
public void readPGM(String path) throws Exception {
int width;
int height;
int maxval;
try {
Scanner in = new Scanner(new File(path));
String magic = in.next();
if (!magic.equals("P2")) {
in.close();
throw new Exception("ERROR: cannot read .pgm file " + path);
}
width = in.nextInt();
height = in.nextInt();
maxval = in.nextInt();
image = new int[height][width];
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
image[y][x] = in.nextInt();
in.close();
} catch (IOException e) {
throw new Exception("ERROR: cannot read .pgm file " + path);
}
// Scale values to the range 0-MAXVAL
if (maxval != MAXVAL)
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
image[j][i] = (image[j][i] * MAXVAL) / maxval;
return;
}
// Write PGM file
public void writePGM(String path) throws Exception {
int height = getHeight();
int width = getWidth();
try {
PrintStream output = new PrintStream(new FileOutputStream(path));
output.println("P2");
output.println(width + " " + height);
output.println(MAXVAL);
for (int row = 0; row < height; row++)
for (int col = 0; col < width; col++)
output.println(image[row][col]); // One pixel per line!
output.close();
} catch (IOException e) {
throw new Exception("ERROR: cannot write .pgm file " + path);
}
}
}
&#13;
我不应该修改的其他部分是
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.swing.*;
public class ImageProgram extends JFrame implements ActionListener
{
private static final long serialVersionUID = 1L; // get rid of warning
// Program flags
private boolean mIsInitialized; // GUI initialized?
private boolean mIsDirty; // image modified?
// Menu items
private JMenuItem mOpenFile;
private JMenuItem mSaveFile;
private JMenuItem mExitCommand;
private JMenuItem mDecode;
private JMenuItem mSwap;
private JMenuItem mMirror;
private JMenuItem mExchange;
private JLabel mLabel;
// Transforms object from student
private ImageInterface mStudent;
// Array and static code are used to convert a gray scale to RGB
private static int[] pgm2RGB;
static {
pgm2RGB = new int[256];
for (int i = 0; i < 256; i++) {
pgm2RGB[i] = (255 << 24) | (i << 16) | (i << 8) | i;
}
}
// Constructor. Note that very little initialization is done here.
// Since a derived class may override some of the initialization methods
// these methods should NOT be called from a constructor because routines
// in the derived class could be executed before the constructor of the super
// class completes. In general, all code in the super class constructor
// should be executed before ANY code in the derived class is executed.
public ImageProgram () {
super();
setSize(new Dimension(400, 300));
}
// Satisfy the ActionListener interface. Most of the work is delegated to
// the method doAction(). This allows a derived class to override doAction
// (instead of actionPerformed()) and take advantage of the error handling
// done here. If a derived class overrides actionPerformed() in may need
// to duplicate the error handling.
public void actionPerformed (ActionEvent actionEvent) {
try {
doAction(actionEvent);
}
catch (Throwable t) {
t.printStackTrace();
}
}
// This can throw exceptions, because they are caught by performAction()
// If you derive your own class from this class, and add new menus
// or menu items, you would override this method to handle your new
// menu items and delegate the work back to this method if the "action"
// is not one of those you defined in your derived class. There are many
// ways to dispatch from an event to the underlying code. This illustrates
// one simple way of doing that.
protected void doAction (ActionEvent actionEvent) throws Exception {
Object src = actionEvent.getSource();
if (src == mOpenFile) openFile();
else if (src == mSaveFile) saveFile();
else if (src == mExitCommand) exitGUI();
else if (src == mDecode) decode();
else if (src == mSwap) swap();
else if (src == mMirror) mirror();
else if (src == mExchange) exchange();
}
// Override setVisible() to initialize everything the first time the
// component becomes visible
public void setVisible (boolean visible) {
if (visible) {
if (! mIsInitialized) {
startGUI();
mIsInitialized = true;
}
}
super.setVisible(visible);
}
// Build the GUI.
protected void startGUI() {
setJMenuBar(makeMenuBar());
addWindowListener(new WindowAdapter() {
public void windowClosing (WindowEvent we) {
mExitCommand.doClick(); // Press the Exit menu item
}
});
getContentPane().add(makeMainPanel());
}
// Exit the GUI
private void exitGUI() {
if (mIsDirty) {
if (!getYesNo("Data has not been saved.", "Continue?"))
return;
}
System.exit(0);
}
// Creates the main panel of the GUI
protected JPanel makeMainPanel() {
JPanel panel = new JPanel(new BorderLayout());
mLabel = new JLabel();
panel.add(mLabel, BorderLayout.CENTER);
return panel;
}
// Created the menu bar for the GUI. Delegates most of the work to
// methods which create the individual menus. The "adds" should remind you
// of your work with ArrayLists. A JMenuBar is conceptually just a list of
// menus. You will find methods on a JMenuBar to manipulate the elements
// of the list.
protected JMenuBar makeMenuBar() {
JMenuBar mb = new JMenuBar();
mb.add(makeFileMenu());
mb.add(makeActionMenu());
return mb;
}
// Create the file menu. Again, the "adds" (see makeMeniItem)should remind you
// of list manipulation. A JMenu is conceptually a list of JMenuItems.
// Interestingly, a JMenu is a JMenuItem. Why do you think that is??
protected JMenu makeFileMenu() {
JMenu menu = makeMenu("File", 'F');
mOpenFile = makeMenuItem(menu, "Open...", 'O');
mSaveFile = makeMenuItem(menu, "Save...", 'S');
mExitCommand = makeMenuItem(menu, "Exit", 'X');
return menu;
}
// Create the action menu.
protected JMenu makeActionMenu() {
JMenu menu = makeMenu("Action", 'A');
mDecode = makeMenuItem(menu, "Decode" , 'D');
mSwap = makeMenuItem(menu, "Swap" , 'S');
mMirror = makeMenuItem(menu, "Mirror" , 'M');
mExchange = makeMenuItem(menu, "Exchange" , 'E');
return menu;
}
// Convenience method for making JMenu
protected JMenu makeMenu (String name, char mnemonic) {
JMenu menu = new JMenu(name);
menu.setMnemonic(mnemonic);
return menu;
}
// Convenience method for making JMenuItem
protected JMenuItem makeMenuItem (String name, char mnemonic) {
JMenuItem mi = new JMenuItem(name, (int) mnemonic);
mi.addActionListener(this);
return mi;
}
// Convenience method for putting JMenuItem in a menu
protected JMenuItem makeMenuItem (JMenu menu, String name, char mnemonic) {
JMenuItem mi = makeMenuItem(name, mnemonic);
menu.add(mi);
return mi;
}
// Convenience method to get yes/no from user
protected boolean getYesNo (String title, String message) {
int answer = JOptionPane.showInternalConfirmDialog(getContentPane(),
message,
title,
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE);
return (answer == JOptionPane.YES_OPTION);
}
// Open image file
private void openFile() throws Exception {
// Data saved?
if (mIsDirty) {
if (!getYesNo("Open file", "Data has not been saved. Continue?"))
return;
}
String fileName = selectFile("Select file to open", true);
if (fileName != null) {
mStudent = new Transforms();
mStudent.readImage(fileName);
resetImage();
mIsDirty = false;
}
}
// Save image file
private void saveFile() throws Exception {
String fileName = selectFile("Select file name to save", false);
if (fileName != null) {
mStudent.writeImage(fileName);
mIsDirty = false;
}
}
// Other student methods
private void decode() {
if (mStudent != null) {
mStudent.decode();
resetImage();
}
}
private void swap() {
if (mStudent != null) {
mStudent.swap();
resetImage();
}
}
private void mirror() {
if (mStudent != null) {
mStudent.mirror();
resetImage();
}
}
private void exchange() {
if (mStudent != null) {
mStudent.exchange();
resetImage();
}
}
// File selector
private String selectFile (String title, boolean open) {
String fileName = null;
JFileChooser jfc = new JFileChooser();
jfc.setCurrentDirectory(new File("."));
jfc.setDialogTitle(title);
int result;
if (open)
result = jfc.showOpenDialog(this);
else
result = jfc.showSaveDialog(this);
if (result == JFileChooser.APPROVE_OPTION) {
File file = jfc.getSelectedFile();
fileName = file.getAbsolutePath();
}
return fileName;
}
// Reset image
private void resetImage() {
if (mStudent != null) {
// Copy the pixel values
int image[][] = mStudent.imageData();
int rows = image.length;
int cols = image[0].length;
BufferedImage buffer = new BufferedImage(cols, rows, BufferedImage.TYPE_INT_ARGB);
for (int row = 0; row < rows; row++) {
for (int col=0; col < cols; col++) {
int rgb = pgm2RGB[image[row][col]];
buffer.setRGB(col, row, rgb);
}
}
ImageIcon imageIcon = new ImageIcon(buffer);
mLabel.setIcon(imageIcon);
mIsDirty = true;
pack(); // make window just fit image
}
}
// Main program
public static void main (String[] args) throws IOException {
ImageProgram gui = new ImageProgram();
gui.setVisible(true);
}
}
&#13;
public interface ImageInterface {
// Read the image
public void readImage(String inFile);
// Write the image
public void writeImage(String outFile);
// Get image data
public int[][] imageData();
// Decode the pixels
public void decode();
// Swap the nibbles in each pixel
public void swap();
// Mirror the image corner to corner
public void mirror();
// Exchange two rectangles in image
public void exchange();
}
&#13;
{{1}}&#13;
答案 0 :(得分:0)
循环应该是这样的:
for (int i = 0; i < height / 2; i++)
{
for(int j = 0; j < width / 2; j++)
{
int temp = imageData[i][j];
imageData[i][j] = imageData[height-i-1][width-j-1];
imageData[height-i-1][width-j-1] = temp;
}
}
答案 1 :(得分:0)
我要做的是从顶部开始(并将其放在新数组的底部),而不是从图像的底部开始。我也不需要临时矩阵。
public void mirror(){
int [][] imageData = new int[height][width];
int i;
int j;
int x = 0;
for (i = height - 1; i = 0; i--)
{
for(j = 0; j < width; j++)
{
imageData[x][j] = data[i][j];
}
x++;
}
}