简体   繁体   中英

Change color in image - (Greenscreen in JAVA)

I would like to change the color (background) from one picture to the background which comes from another picture. Here is my code but it doesn´t work 100 %. Here is my current output: http://www.bilder-upload.eu/upload/48a6b6-1471634776.jpg

This are the images: Original: https://github.com/vincentclee/csci1302-software_development/blob/master/p1_green_screen/submission/sagar.jpg?raw=true

New background: https://github.com/vincentclee/csci1302-software_development/blob/master/p1_green_screen/submission/india.jpg?raw=true

    public class StartGreenScreen2 {
    public static void main(String[] args) throws IOException {

        String inputFile = "/Users/testGreenscreen/sagar.jpg";
        String backgroundFile = "/Users/testGreenscreen/india.jpg";

        exceptions(inputFile, backgroundFile, ".jpg", "green");

    }

    /**
     * The exceptions method accepts a String array argument. This method
     * handles exceptions that might bring up.
     * 
     * @param args
     *            Contains parameters for program execution.
     * @throws IOException
     *             For catching file problems.
     */

    public static void exceptions(String inputFile, String backgroundFile, String outputFileType, String color) throws IOException {
        // Creates 7 boolean variables, all of which have to be true for the
        // colorChanger & colorWriter to execute.
        boolean[] bool = new boolean[6];

        // args[0] try & catch statements
        try {
            new FileReader(inputFile);
            bool[0] = true;
        } catch (FileNotFoundException e) {
            System.out.println("Input file for color swap not found.");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("No input file specified.");
        } catch (Exception e) {
            System.out.println("There is a problem with the inputfile.");
        }

        // args[1] try & catch statements
        try {
            new FileReader(backgroundFile);
            bool[1] = true;
        } catch (FileNotFoundException e) {
            System.out.println("Input File not Found");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("No input file specified.");
        } catch (Exception e) {
            System.out.println("There is a problem with the inputfile.");
        }

        // args[2] try & catch statements
        try {
            if (outputFileType.contains("."))
                bool[2] = true;
            else
                System.out.println("Outfile name invalid.");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Output file not specified.");
        } catch (Exception e) {
            System.out.println("There is a problem with the outputfile.");
        }

        // args[3] try & catch statements
        try {
            if (inputFile.endsWith(".png") && backgroundFile.endsWith(".png") && outputFileType.equalsIgnoreCase(".png")) {
                bool[3] = true;
            } else if (inputFile.endsWith(".jpg") && backgroundFile.endsWith(".jpg") && outputFileType.equalsIgnoreCase(".jpg")) {
                bool[3] = true;
            } else
                System.out.println("The extension of all input files do not match!");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Extension not specified.");
        } catch (Exception e) {
            System.out.println("There is a problem with the extension.");
        }

        // args[4] try & catch statements
        try {
            if (color.equalsIgnoreCase("green") || color.equalsIgnoreCase("white")
                    || color.equalsIgnoreCase("auto"))
                bool[4] = true;
            else
                System.out.println("The spedified color is not valid.");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Color of replacement not specified.");
        } catch (Exception e) {
            System.out.println("There is a problem with the color of replacement.");
        }



        // Checks the dimensions of both the input and output image for same
        // dimensions.
        if (bool[0] && bool[1] && bool[2] && bool[3] && bool[4]) {
            BufferedImage imageIn = ImageIO.read(new File(inputFile));

            BufferedImage imageOut = ImageIO.read(new File(backgroundFile));

            if (imageIn.getWidth() == imageOut.getWidth() && imageIn.getHeight() == imageOut.getHeight())
                bool[5] = true;
            else
                System.out.println("The imgaes are not the same dimensions.");
        }

//       All arguments and dimensions have to be true for this to execute.
//       Just to be safe, this has a general exception built in.
        try {
            if (bool[0] && bool[1] && bool[2] && bool[3] && bool[4] && bool[5])
//              colorWriter(colorChanger(inputFile), backgroundFile, color);
            colorWriter(colorChanger(inputFile,backgroundFile, color), outputFileType) ;
            else
                System.out.println("Program Terminated.");
        } catch (Exception e) {
            System.out.println("General Program Failure");
        }
    }

    /**
     * The color Changer method accepts a String array argument. This method
     * changes the colors in the picture.
     * 
     * @param args
     *            Contains parameters for program execution.
     * @return imageIn BufferedImage stream for output
     * @throws IOException
     *             For catching file problems.
     */

    public static BufferedImage colorChanger(String normalFile, String backgroundFile, String color) throws IOException {

        // Open file for replacement through Buffered Image stream.
        BufferedImage imageIn = ImageIO.read(new File(normalFile));

        // Open file background through Buffered Image stream.
        BufferedImage imageOut = ImageIO.read(new File(backgroundFile));

        // Array to store pixel information for calculation on extra credit
        int[][] pixels = new int[imageIn.getHeight()][imageIn.getWidth()];

        // Determines each pixel color and stores it into a 2D array to a
        // corresponding location.
        for (int col = 0; col < imageIn.getWidth(); col++) {
            for (int row = 0; row < imageIn.getHeight(); row++) {
                pixels[row][col] = imageIn.getRGB(col, row);
            }
        }

        // Array to store different colors and their pixel counts.
        int[][] colors = new int[10000][2];
        colors[0][0] = pixels[0][0]; // Sets color value at position (0,0) to
                                        // first array.

        // Gets color information and stores it in a array, then it checks the
        // array for color, and adds count.
        // If the color does not exists, it goes down to a empty space, and
        // creates a new entry, and sets one for count.
        for (int col = 0; col < imageIn.getWidth(); col++) {
            for (int row = 0; row < imageIn.getHeight(); row++) {
                boolean bool = true;
                int counter = 0;
                for (int i = 0; i < colors.length; i++) {
                    if (pixels[row][col] == colors[i][0]) {
                        colors[i][1]++;
                        bool = false;
                    }
                    if (colors[i][0] == 0) {
                        counter = i;
                        break;
                    }
                }
                if (bool) {
                    colors[counter][0] = pixels[row][col];
                    colors[counter][1]++;
                }
            }
        }

        // Prints out array of color, and number of hits greater than 10.
        System.out.println("Top Colors:");
        for (int row = 0; row < colors.length; row++) {
            if (colors[row][0] != 0 && colors[row][1] > 10)
                System.out.println(colors[row][0] + " " + colors[row][1]);
        }

        // Determine's the color with the highest pixel count.
        int high = colors[0][1];
        int backgroundColor = colors[0][0];
        for (int row = 0; row < colors.length; row++) {
            if (colors[row][1] > high) {
                backgroundColor = colors[row][0];
                high = colors[row][1];
            }
        }
        System.out.println("Color: " + backgroundColor + " Count: " + high);

        // Override for args[4] color selector
        if (color.equalsIgnoreCase("green")) {
            backgroundColor = -16711935;
        }

        if (color.equalsIgnoreCase("white")) {
            backgroundColor = -1;
        }

        // Color Changer
        // If the pixel on the image to be changed is the same as the color to
        // be changed, it changes the color.
        // There is also a 50 point tolerance.


        for (int col = 0; col < imageIn.getWidth(); col++) {
            for (int row = 0; row < imageIn.getHeight(); row++) {
                if (imageIn.getRGB(col, row) > (backgroundColor - 8388608)
                        && imageIn.getRGB(col, row) < (backgroundColor + 8388608))
                    imageIn.setRGB(col, row, imageOut.getRGB(col, row));
            }
        }

        return imageIn;
    }

    /**
     * The colorWriter method accepts a BufferedImage stream, and a String array
     * argument.
     * 
     * @param imageIn
     *            A BufferedImage stream for inputImage.
     * @param args
     *            Contains parameters for program execution.
     * @throws IOException
     *             For catching file problems.
     */

    public static void colorWriter(BufferedImage imageIn, String ouputPath) throws IOException {
        // Generates a *.extension String.
        String outputFile = ouputPath + ".jpg";

        String testFile = "/Users/test.jpg";

        // Writes output File
        ImageIO.write(imageIn, "jpg", new File(testFile));
    }

How can I solve this? Or does anybody has an idea to change the code?

  1. You lost informations by JPEG compression, better use PNG.
  2. Not all pixels in your picture have same green color in background. Not replaced green pixels
  3. Your tolerance check isn't good, better use square deviation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM