交换2维数组行?

时间:2017-03-12 18:47:36

标签: java

我是编程的新手,我的一项任务是在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;
&#13;
&#13;

我不应该修改的其他部分是

&#13;
&#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;
&#13;
&#13;

&#13;
&#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;
&#13;
&#13;

&#13;
&#13;
{{1}}
&#13;
&#13;
&#13;

2 个答案:

答案 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++;
        }
        }