I try to work on a java program right now, most of the functions are done but I got confused on the display pf buttons

51 views Asked by At

There will be three buttons be placed on the top of the window, at the initial, button 1 and button 2 should be display. Once button 2 is being clicked, it should execute it function and be change to button3. Other other hand when button 3 is clicked, it should execute it function and be changed to button 2.

Here is the code that I have write so far.

import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import javax.swing.*;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.objdetect.CascadeClassifier;

class FaceArea {
    private String currentImage;

    FaceArea() {
        currentImage = "";
    }

    String getCurrentImage() {
        return currentImage;
    }

    void setCurrentImage(String imageName) {
        currentImage = imageName;
    }

    void FaceAreas(Graphics g, Rect[] faceAreas) {
        if (currentImage.equals("imageV1.jpg")) {
            V1(g, faceAreas);
        } else if (currentImage.equals("imageV2.jpg")) {
            V2(g, faceAreas);
        }
    }

    private void V1(Graphics g, Rect[] faceAreas) {
        g.setColor(Color.yellow);
        for (Rect rect : faceAreas) {
            g.drawRect((rect.x) / 2 - 20, rect.y / 2 + 400, rect.width / 3 + 20, rect.height / 3 + 20);
        }
    }

    private void V2(Graphics g, Rect[] faceAreas) {
        g.setColor(Color.yellow);
        for (Rect rect : faceAreas) {
            g.drawRect((rect.x - 10) / 2, rect.y / 2 + 400, rect.width / 3 + 25, rect.height / 3 + 25);
        }
    }

    void Text(Graphics g, JTextArea textArea) {
        if (currentImage.equals("message.txt")) {
            g.setColor(Color.blue);
            g.setFont(new Font("Arial", Font.PLAIN, 16));
            String[] lines = textArea.getText().split("\n");
            int y = 420;
            for (String line : lines) {
                g.drawString(line, 10, y);
                y += g.getFontMetrics().getHeight();
            }
        }
    }
}

public class PlayWithFace extends JFrame {

    BufferedImage bimage1, bimage2;
    Mat src1, src2;
    String FromCamera = "FromCamera.jpg";
    ArrayList<String> imageFiles;
    Iterator<String> imageIterator;
    String path = "/opt/homebrew/Cellar/opencv/4.8.1_1/share/opencv4/haarcascades/";
    String cascade = "haarcascade_frontalface_alt.xml";
    Rect[] faceArea1 = null;
    Rect[] faceArea2 = null;
    int count = 0;

    JButton button1, button2, button3;
    FaceArea faceArea;
    JTextArea textArea;
    private BufferedImage originalBimage1; // Added for storing the original image

    public PlayWithFace() {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        setTitle("Play with Face");
        setSize(500, 760);
        
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        textArea = new JTextArea();
        faceArea = new FaceArea();
        detect();
        
        repaint();
        
        button1 = new JButton("Next Image");
        button1.addActionListener(e -> loadNextImage());

        button2 = new JButton("Change Face");
        button2.addActionListener(e -> changeFace());

        button3 = new JButton("Return Face");
        button3.addActionListener(e -> returnFace());

        JPanel buttonPanel = new JPanel();
        buttonPanel.add(button1);
        buttonPanel.add(button2);

        setLayout(new BorderLayout());
        add(buttonPanel, BorderLayout.NORTH);

        setVisible(true);
    }
    
    private void Text(String filePath) {
        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
            StringBuilder content = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                content.append(line).append("\n");
            }
            textArea.setText(content.toString());
            faceArea.setCurrentImage("message.txt");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void loadNextImage() {
        if (imageIterator.hasNext()) {
            String nextImage = imageIterator.next();
            if (nextImage.endsWith(".jpg") || nextImage.endsWith(".jpeg") || nextImage.endsWith(".png")) {
                src2 = Imgcodecs.imread(nextImage);
                bimage2 = matToBufferedImage(src2);
                faceArea2 = getArea(cascade, src2);
                faceArea.setCurrentImage(nextImage);
            } else if (nextImage.endsWith(".txt")) {
                Text(nextImage);
            }
            repaint();
        }
    }

    private void changeFace() {
        if (faceArea2 != null) {
            Rect[] faceArea2Copy = Arrays.copyOf(faceArea2, faceArea2.length);
            if (bimage1 != null && bimage2 != null) {
                Graphics2D g2d = bimage1.createGraphics();
                if (faceArea.getCurrentImage().equals("imageV1.jpg")) {
                    for (Rect rect : faceArea2Copy) {
                        BufferedImage facePart = bimage2.getSubimage(rect.x, rect.y, rect.width, rect.height);
                        g2d.drawImage(facePart, rect.x + 45, rect.y - 140,
                                rect.width + 360, rect.height + 390, this);
                    }
                } else if (faceArea.getCurrentImage().equals("imageV2.jpg")) {
                    for (Rect rect : faceArea2Copy) {
                        BufferedImage facePart = bimage2.getSubimage(rect.x, rect.y, rect.width, rect.height);
                        g2d.drawImage(facePart, rect.x + 305, rect.y - 30,
                                rect.width + 295, rect.height + 325, this);
                    }
                }

                g2d.dispose();
            }
            repaint();
        }
    }

    private void returnFace() {
        if (originalBimage1 != null) {
            // Restore the original image
            bimage1 = deepCopy(originalBimage1);
            faceArea1 = getArea(cascade, matFromBufferedImage(bimage1));
            repaint();
        }
    }

    public void paint(Graphics g) {
        if (bimage1 != null) {
            g.drawImage(bimage1, 10, 70, bimage1.getWidth() / 3, bimage1.getHeight() / 3, this);
        }

        if (bimage2 != null) {
            g.drawImage(bimage2, 10, 400, bimage2.getWidth() / 2 - 60, bimage2.getHeight() / 2 - 10, this);
        }

        if (faceArea1 != null) {
            g.setColor(Color.red);
            for (Rect rect : faceArea1) {
                g.drawRect((rect.x + 20) / 3, (rect.y + 60) / 2, rect.width / 3 + 10, rect.height / 3 + 20);
            }
        }

        if (faceArea2 != null) {
            faceArea.FaceAreas(g, faceArea2);
        }



        faceArea.Text(g, textArea);
    }

    private void detect() {
        src1 = Imgcodecs.imread(FromCamera);
        bimage1 = matToBufferedImage(src1);
        originalBimage1 = deepCopy(bimage1); // Create a deep copy of the original image
        faceArea1 = getArea(cascade, src1);

        imageFiles = new ArrayList<>();
        imageFiles.add("message.txt");
        imageFiles.add("imageV1.jpg");
        imageFiles.add("imageV2.jpg");
        imageIterator = imageFiles.iterator();
        loadNextImage();
    }

    private Rect[] getArea(String str, Mat src) {
        Rect[] area = null;
        CascadeClassifier faceDetector = new CascadeClassifier(path + str);
        MatOfRect faceDetections = new MatOfRect();
        faceDetector.detectMultiScale(src, faceDetections);
        area = faceDetections.toArray();
        return area;
    }

    private BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int) matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;

        matrix.get(0, 0, data);

        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                byte b;
                for (int i = 0; i < data.length; i = i + 3) {
                    b = data[i];
                    data[i] = data[i + 2];
                    data[i + 2] = b;
                }
                break;
            default:
                return null;
        }

        BufferedImage out = new BufferedImage(cols, rows, type);
        out.getRaster().setDataElements(0, 0, cols, rows, data);
        return out;
    }

    private Mat matFromBufferedImage(BufferedImage image) {
        Mat mat = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC3);
        byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
        mat.put(0, 0, data);
        return mat;
    }

    private BufferedImage deepCopy(BufferedImage bi) {
        ColorModel cm = bi.getColorModel();
        boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
        WritableRaster raster = bi.copyData(null);
        return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new PlayWithFace());
    }
}

As mention above, I want button 2 to be replace to button 3 when it being clicked, and button 3 to be replace to button 2 when it being clicked.

I have tried many ways but I have no idea how to do it.

Please let me know if you need further information.

0

There are 0 answers