Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 6 of 6

Thread: Passing an array as a parameter to a method - all elements after [0] generate an error.

  1. #1
    Junior Member
    Join Date
    Jan 2019
    Posts
    12
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Passing an array as a parameter to a method - all elements after [0] generate an error.

    I'm writing a simple blur effect and have run into a problem I can't figure out.

    I have an array of colors and I want to get an RGBA average for each channel to color a pixel. Here is the code:

    import java.awt.image.BufferedImage;
    import java.awt.Color;
     
    public class BlurEffects {
     
        public static BufferedImage GaussianBlur(BufferedImage img, int clrAvgX, int clrAvgY) {
     
            //Create the image that will have the "blurred" pixels
            BufferedImage blurredImage = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
     
            //This variable is used to get and assign the number of array elements for various arrays
            int numArrayElements;
     
            /*Get the number of array elements for the pixel matrix used to get a color channel
            average for each pixel of img
            */
            numArrayElements = (((clrAvgX * 2) + 1) * ((clrAvgY * 2) + 1));
     
            //Create the pixel matrix array used to get a color channel average for each pixel of img
            Color[] clrAvgArray;
            clrAvgArray = new Color[numArrayElements];
     
            Color avgColor = new Color(0, 0, 0, 0);
     
            //Create x and y variables to loop through img
            int imgX;
            int imgY;
     
            //Create x and y variables to through the pixel matrix
            int arrX;
            int arrY;
     
            //Create x and y variables to track pixel matrix locations
            int getX;
            int getY;
     
            //Create a pixelMatrix index counter
            int ctr = 0;
     
            //Create a integers for getting and setting pixel colors
            int clr;
            int a;
            int r;
            int g;
            int b;
            int pixel;
     
            /*Loop through each pixel of img, get the pixel matrix average of any pixel
            that isn't empty and write it to the corresponding pixel of blurredImage
             */
            for (imgY = 0; imgY <= (img.getHeight() - 1); imgY++) {
                for (imgX = 0; imgX <= (img.getWidth() - 1); imgX++) {
     
                    //Reset the counter
                    ctr = 0;
     
                    /*Determine if the pixel at the x,y coordinates is empty
                    If it isn't, get the pixel matrix average of any pixel that
                    isn't empty and write it to the corresponding pixel of blurredImage
                     */
                    //Loop through the color averaging pixel matrix
                    //Top to bottom
                    for (arrY = 0; arrY <= (clrAvgY * 2); arrY++) {
                        //Left to right
                        for (arrX = 0; arrX <= (clrAvgX * 2); arrX++) {
                            getX = (imgX - clrAvgX) + arrX;
                            getY = (imgY - clrAvgY) + arrY;
                            //Make sure that getX and getY are in the bounds of the image. If not, zero out the ARGB values
                            if ((getX < 0) || (getY < 0) || (getX > (img.getWidth() - 1)) || (getY > (img.getHeight() - 1))) {
                                clrAvgArray[ctr] = new Color(0, 0, 0, 0);
                            }
                            else {
                                clr = img.getRGB(getX, getY);
                                a = (clr >> 24) & 0xff;
                                r = (clr >> 16) & 0xff;
                                g = (clr >> 8) & 0xff;
                                b = clr & 0xff;
                                clrAvgArray[ctr] = new Color(r, g, b, a);
                            }
     
                            //Get the pixel's average color
                            avgColor = ColorAveraging.ColorAverageByArray(clrAvgArray);
     
                            //Increment the counter
                            ctr++;
                        }
                    }
                    //Assign the colors to the channels
                    a = avgColor.getAlpha();
                    r = avgColor.getRed();
                    g = avgColor.getGreen();
                    b = avgColor.getBlue();
     
                    //Bitshift and OR the color channels into the pixel
                    pixel = (a<<24) | (r<<16) | (g<<8) | b;
     
                    //Color the pixel
                    blurredImage.setRGB(imgX, imgY, pixel);
                }
            }
     
            return blurredImage;
        }
    }

    import java.awt.Color;
     
    public class ColorAveraging {
     
        public static Color ColorAverageByArray(Color colors[]) {
     
            Color myAvgColor = new Color(0, 0, 0, 0);
     
            int i;
            int sumA = 0;
            int sumR = 0;
            int sumG = 0;
            int sumB = 0;
            int avgA = 0;
            int avgR = 0;
            int avgG = 0;
            int avgB = 0;
     
            //Loop through the colors array and get a combined value for each channel
            for (i = 0; i < colors.length; i++) {
                sumA += colors[i].getAlpha();
                sumR += colors[i].getRed();
                sumG += colors[i].getGreen();
                sumB += colors[i].getBlue();
            }
     
            avgA = sumA / colors.length;
            avgR = sumR / colors.length;
            avgG = sumG / colors.length;
            avgB = sumB / colors.length;
     
            //Create the new color
            myAvgColor = new Color(avgR, avgG, avgB, avgA);
     
            //System.out.println("It seems to work!");
            return myAvgColor;
     
        }
    }

    The user passes an image to GaussianBlur along with an X and Y value. These values represent the width and height of a matrix of pixels that surround each pixel of the image. For example, if x=2 and y=2, then for each pixel of the image, there will be a 5x5 pixel matrix with the sampled pixel at the center. In otherwords, moving 2 pixels out around the sampled pixel. If x=1 and y=3, then the matrix would be 3x7, 1 pixel out in the x directions, 3 pixels out in the y directions.

    Here is what I have verified:
    There is definitely data in every element of the clrAvgArray when it is passed to ColorAverageByArray from GaussianBlur.
    There is definitely data in colors[0] in ColorAverageByArray.
    colors.length is correct. If, from GaussianBlur, x=2 and y=2, then colors.length is 25. If x=1 and y=3 then, colors.length is 21.
    An exception error is thrown if an attempt is made to access any element of the colors[] array other than [0].

    So I'm stuck at sumA += colors[i].getAlpha() as soon as i is 1. What I can't figure out is, what happened to the fully stocked array from the time it was passed to the time it is accessed?

  2. #2
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,042
    Thanks
    63
    Thanked 2,708 Times in 2,658 Posts

    Default Re: Passing an array as a parameter to a method - all elements after [0] generate an error.

    An exception error is thrown if an attempt is made to access any element of the colors[] array other than [0].
    What is the exception?
    What line of the source program does that happen on?


    How are you trying to debug the code?
    The Arrays toString method is useful to print out the contents of an array.

    What is in clrAvgArray when the ColorAverageByArray method is called? Print its contents to see.
    If you don't understand my answer, don't ignore it, ask a question.

  3. #3
    Junior Member
    Join Date
    Jan 2019
    Posts
    12
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Passing an array as a parameter to a method - all elements after [0] generate an error.

    sumA += colors[i].getAlpha()

    In the loop, as soon as i is 1, then that's where the exception occurs. So it gets the RGBA values from element [0] but as soon as it gets to element [1] it throws the exception.

    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at ColorAveraging.ColorAverageByArray(ColorAveraging. java:21)

    I'm writing to the console to see the contents of the clrAvgArray array. It's what you would expect for an array of colors: RGBA values for each element of the array.

  4. #4
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,042
    Thanks
    63
    Thanked 2,708 Times in 2,658 Posts

    Default Re: Passing an array as a parameter to a method - all elements after [0] generate an error.

    Did you try printing the contents of the array using the Arrays class's toString method to see what is in it?

    as soon as it gets to element [1] it throws the exception.
    Where does the code add entries to the array? How many entries have been added to the array when the exception happens?
    If you don't understand my answer, don't ignore it, ask a question.

  5. #5
    Junior Member
    Join Date
    Jan 2019
    Posts
    12
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Passing an array as a parameter to a method - all elements after [0] generate an error.

    No, I did not use the toString method of the array. I used this:

    System.out.println(ctr + " >>> " + clrAvgArray[ctr].getRed() + " : " + clrAvgArray[ctr].getGreen() + " : " + clrAvgArray[ctr].getBlue() + " : " + clrAvgArray[ctr].getAlpha());

    Because this: 22 >>> 124 : 87 : 219 : 255 is more informative than this: [Ljava.awt.Color;@62e1820e, which is what I get if use: System.out.println(clrAvgArray.toString());

    The answers to your other questions are in the code. I'll try and explain it better> You pass an image to GuassianBlur along with an x and x parameter. Those parameters determine how far from a pixel in the x and t directions a matrix of pixel is used to get a color average.

    The code loops through each pixel of the original image. For each of those pixels, it gets the color of each pixel surrounding it in the x and y directions. Those colors are what are put into the clrAvgArray[] array.

    Suppose that you are looping through the passed image and are at the pixel located at x=207, y=112.

    If your passed x and y parameters for color averaging are x=2 and y=2, then the matrix would like this:

    (205, 110)(206, 110)(207, 110)(208, 110)(209, 110)
    (205, 111)(206, 111)(207, 111)(208, 111)(209, 111)
    (205, 112)(206, 112)(207, 112)(208, 112)(209, 112)
    (205, 113)(206, 113)(207, 113)(208, 113)(209, 113)
    (205, 114)(206, 114)(207, 114)(208, 114)(209, 114)

    If your passed x and y parameters for color averaging are x=1 and y=3, then the matrix would like this:

    (206, 109)(207, 109)(208, 109)
    (206, 110)(207, 110)(208, 110)
    (206, 111)(207, 111)(208, 111)
    (206, 112)(207, 112)(208, 112)
    (206, 113)(207, 113)(208, 113)
    (206, 114)(207, 114)(208, 114)
    (206, 115)(207, 115)(208, 115)

    If your passed x and y parameters for color averaging are x=2 and y=1, then the matrix would like this:

    (205, 111)(206, 111)(207, 111)(208, 111)(209, 111)
    (205, 112)(206, 112)(207, 112)(208, 112)(209, 112)
    (205, 113)(206, 113)(207, 113)(208, 113)(209, 113)

    So each one of those (x,y) is a pixel and that pixel has a color. Those colors are what are in the clrAvgArray[] array. I have verified that every element in the array has a color in it before it is passed to ColorAverageByArray.

    As I stated in the original post, when clrAvgArray is passed to ColorAverageByArray, the number of array elements in colors[] is correct: If the x and y parameters passed to GaussianBlur were x=2, y=2, then the pixel matrix would be 5x5 or 25 pixels. colors.length should equal 25 and it does. If the x and y parameters passed to GaussianBlur were x=2, y=1, then the pixel matrix would be 5x3 or 15 pixels. colors.length should equal 15 and it does.

    So if I am passing clrAvgArray to ColorAverageByArray, then colors[] should be the same array as clrAvgArray as far as length and a color inside each element.

    The problem is that colors[] has the correct number of elements but only colors[0] has a color in it; colors[1] onward have nothing and that is where the exception is thrown.

    If clrAvgArray has a color in every element when it is passed to ColorAverageByArray, what happens to all of the colors in elements after [0]?

  6. #6
    Junior Member
    Join Date
    Jan 2019
    Posts
    12
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Passing an array as a parameter to a method - all elements after [0] generate an error.

    Well, that was pretty stupid.

    I was trying to send the entire pixel matrix avgColor = ColorAveraging.ColorAverageByArray(clrAvgArray); from inside of the loop that was creating it:
    /*Loop through each pixel of img, get the pixel matrix average of any pixel
            that isn't empty and write it to the corresponding pixel of blurredImage
             */
            for (imgY = 0; imgY <= (img.getHeight() - 1); imgY++) {
                for (imgX = 0; imgX <= (img.getWidth() - 1); imgX++) {
     
                    //Reset the counter
                    ctr = 0;
     
                    /*Determine if the pixel at the x,y coordinates is empty
                    If it isn't, get the pixel matrix average of any pixel that
                    isn't empty and write it to the corresponding pixel of blurredImage
                     */
                    //Loop through the color averaging pixel matrix
                    //Top to bottom
                    for (arrY = 0; arrY <= (clrAvgY * 2); arrY++) {
                        //Left to right
                        for (arrX = 0; arrX <= (clrAvgX * 2); arrX++) {
                            getX = (imgX - clrAvgX) + arrX;
                            getY = (imgY - clrAvgY) + arrY;
                            //Make sure that getX and getY are in the bounds of the image. If not, zero out the ARGB values
                            if ((getX < 0) || (getY < 0) || (getX > (img.getWidth() - 1)) || (getY > (img.getHeight() - 1))) {
                                clrAvgArray[ctr] = new Color(0, 0, 0, 0);
                            }
                            else {
                                clr = img.getRGB(getX, getY);
                                a = (clr >> 24) & 0xff;
                                r = (clr >> 16) & 0xff;
                                g = (clr >> 8) & 0xff;
                                b = clr & 0xff;
                                clrAvgArray[ctr] = new Color(r, g, b, a);
                            }
     
                            //Get the pixel's average color
                            avgColor = ColorAveraging.ColorAverageByArray(clrAvgArray);
     
                            //Increment the counter
                            ctr++;
                        }
                    }

    All I had to do was move it outside of the loop:

    for (arrY = 0; arrY <= (clrAvgY * 2); arrY++) {
                        //Left to right
                        for (arrX = 0; arrX <= (clrAvgX * 2); arrX++) {
                            getX = (imgX - clrAvgX) + arrX;
                            getY = (imgY - clrAvgY) + arrY;
                            //Make sure that getX and getY are in the bounds of the image. If not, zero out the ARGB values
                            if ((getX < 0) || (getY < 0) || (getX > (img.getWidth() - 1)) || (getY > (img.getHeight() - 1))) {
                                clrAvgArray[ctr] = new Color(0, 0, 0, 0);
                            }
                            else {
                                clr = img.getRGB(getX, getY);
                                a = (clr >> 24) & 0xff;
                                r = (clr >> 16) & 0xff;
                                g = (clr >> 8) & 0xff;
                                b = clr & 0xff;
                                clrAvgArray[ctr] = new Color(r, g, b, a);
                            }
     
                            //Increment the counter
                            ctr++;
                        }
                    }
     
                    avgColor = ColorAveraging.ColorAverageByArray(clrAvgArray);

Similar Threads

  1. Replies: 6
    Last Post: February 9th, 2019, 12:48 PM
  2. [SOLVED] Parameterized array type as a method parameter
    By Lediator in forum What's Wrong With My Code?
    Replies: 3
    Last Post: August 1st, 2014, 01:08 AM
  3. Passing an element from an array to a Method
    By camaleonx13 in forum What's Wrong With My Code?
    Replies: 1
    Last Post: September 29th, 2013, 06:36 PM
  4. Passing array method error
    By floorplay in forum What's Wrong With My Code?
    Replies: 2
    Last Post: March 31st, 2013, 09:07 AM
  5. [SOLVED] Passing 2D array to method
    By drgroove777 in forum What's Wrong With My Code?
    Replies: 2
    Last Post: October 24th, 2012, 02:08 AM