0

I have the following constructor for a RecoloredImage that takes an old image, and replaces every old colored pixel with a new colored pixel. However, the image doesn't actually change. The code between the comments is purely for testing purposes, and the resulting printed line is not at all the new color I want.

public RecoloredImaged(Image inputImage, Color oldColor, Color newColor) {
    int width = (int) inputImage.getWidth();
    int height = (int) inputImage.getHeight();
    WritableImage outputImage = new WritableImage(width, height);
    PixelReader reader = inputImage.getPixelReader();
    PixelWriter writer = outputImage.getPixelWriter();
    // -- testing --
    PixelReader newReader = outputImage.getPixelReader();
    // -- end testing --
    int ob = (int) oldColor.getBlue() * 255;
    int or = (int) oldColor.getRed() * 255;
    int og = (int) oldColor.getGreen() * 255;
    int nb = (int) newColor.getBlue() * 255;
    int nr = (int) newColor.getRed() * 255;
    int ng = (int) newColor.getGreen() * 255;
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            int argb = reader.getArgb(x, y);
            int a = (argb >> 24) & 0xFF;
            int r = (argb >> 16) & 0xFF;
            int g = (argb >>  8) & 0xFF;
            int b =  argb        & 0xFF;
            if (g == og && r == or && b == ob) {
                r = nr;
                g = ng;
                b = nb;
            }
            argb = (a << 24) | (r << 16) | (g << 8) | b;
            writer.setArgb(x, y, argb);
            // -- testing -- 
            String s = Integer.toHexString(newReader.getArgb(x, y));
            if (!s.equals("0"))
                System.out.println(s);
            // -- end testing --
        }
    }
    image = outputImage;
}
G L
  • 833
  • 1
  • 6
  • 10
  • You aren't changing the input image, you are creating a new image (the outputImage) and writing to that. You have a line of code `image = outputImage;`, I don't know that that is supposed to do (`image` is undefined). My guess is that your routine might be working, but you just aren't making use of the output image anywhere. – jewelsea Oct 28 '19 at 18:15
  • Possible duplicate of: [Reduce number of colors](https://stackoverflow.com/questions/12941600/reduce-number-of-colors-and-get-color-of-a-single-pixel) – jewelsea Oct 28 '19 at 18:17
  • image is an instance variable. Sorry about that. – G L Oct 28 '19 at 18:24

1 Answers1

1

The cast operator has a higher precedence than the multiplication operator. Your calculations for the or, ..., nb values are therefore compiled to the same bytecode as this code:

int ob = ((int) oldColor.getBlue()) * 255;
int or = ((int) oldColor.getRed()) * 255;
int og = ((int) oldColor.getGreen()) * 255;
int nb = ((int) newColor.getBlue()) * 255;
int nr = ((int) newColor.getRed()) * 255;
int ng = ((int) newColor.getGreen()) * 255;

Just add brackets to tell java to do the multiplication before casting. Otherwise you'll only get values 0 or 255 as results.

int ob = (int) (oldColor.getBlue() * 255);
int or = (int) (oldColor.getRed() * 255);
int og = (int) (oldColor.getGreen() * 255);
int nb = (int) (newColor.getBlue() * 255);
int nr = (int) (newColor.getRed() * 255);
int ng = (int) (newColor.getGreen() * 255);
fabian
  • 80,457
  • 12
  • 86
  • 114