在java中编辑像素值

时间:2014-10-06 01:26:46

标签: java pixels

我有一个类Pixel,它有方法getRed,getBlue,getGreen,setRed,setBlue,setGreen(r,g,b) 到目前为止,一切都是单独的,但当我把它放在一起setGreen和setBlue不起作用。我做错了吗?

public class Pixel {
    int pixel;
    public Pixel (int pixel) {
        this.pixel = pixel;
    }
    public int getRed() {
        int red = pixel >> 16;
        red = red & (0xFF);
        return red;   
    }
    public int getGreen() {
        int green = pixel >> 8;
        green = green & (0xFF);
        return green;
    }
    public int getBlue() {
        int blue = pixel;
        blue = blue & (0xFF);
        return blue;
    }
    public void setRed(int red) {
        pixel = (pixel & ~(0xFFFF0000)) << 16;
        pixel= ((red << 16))|pixel ;   
    }
    public void setGreen(int value) {
        pixel = (pixel & ~(0xFF00FF00)) << 8;
        pixel= (value << 8) |pixel; 
    }
    public void setBlue(int value) {
        pixel = (pixel & ~(0xFFFFFF00));
        pixel= (value) |pixel; 
    }
    public static void main(String[] args) {
        Pixel p3 = new Pixel(0xFF000000);
        System.out.printf("rgb = (%d, %d, %d)\n", p3.getRed(), p3.getGreen(), p3.getBlue());

        p3.setRed(42);
        p3.setGreen(18);
        p3.setBlue(225);
        System.out.printf("rgb = (%d, %d, %d)\n", p3.getRed(), p3.getGreen(), p3.getBlue());

        p3.setRed(-1);
        p3.setGreen(500);
        p3.setBlue(1000);
        System.out.printf("rgb = (%d, %d, %d)\n", p3.getRed(), p3.getGreen(), p3.getBlue());
    }   
}

我应该得到这个结果:

rgb = (0, 0, 0)
rgb = (42, 18, 225)
rgb = (255, 244, 232)

但这就是我得到的

rgb = (0, 0, 0)
rgb = (0, 0, 225)
rgb = (0, 3, 232)

1 个答案:

答案 0 :(得分:1)

例如考虑您的setGreen方法:

public void setGreen(int value) {
    pixel = (pixel & ~(0xFF00FF00)) << 8;
    pixel = (value << 8) | pixel; 
}

最初,您的pixelAARRGGBB。首先,您正在将当前值GG中的pixel部分正确设置为0(暂时忽略alpha)。 (pixel & ~(0xFF00FF00)) == (AARRGGBB & 0x00FF00FF) == 00RR00BB。但是,接下来您将该值向左移动8位,因此您得到RR00BB00。接下来,您(正确地)左移您获得的绿色值作为参数。你会得到(000000GG << 8) == 0000GG00。最后,你正在使用之前的值:(RR00BB00 | 0000GG00) == RR00XX00其中X es是一些垃圾,它们起源于或者将旧的蓝色与新的绿色位组合在一起。你能看到要解决的问题吗?

setBlue方法还有另一个问题。 (pixel & ~(0xFFFFFF00)) == (AARRGGBB & 000000FF) == 000000BB。将其与上面setGreen的(正确)掩码进行比较。

最后,您的方法似乎应该优雅地处理无效值(-1,500,1000)。因此,您应该将参数的最后8位设置为0.我只是建议,因为您的所需输出似乎要求它。在编写良好的Java程序中,如果传递超出范围的值,最好抛出异常,而不是静默忽略无效位。或者,您可以更改方法以接受byte而不是int。这将是最好的解决方案,因为现在通过无效的论证是完全不可能的。

将它们放在一起,以下是它的工作原理。我还对代码进行了一些修改,以便我们可以更容易地看到正在发生的事情。 0位的移位当然没用,但我出于光学原因将它们包括在内。

public final class Pixel {

    private int value;

    public Pixel (int rgb) {
        this.value = value;
    }

    public int getRed() {
        return (this.value >> 16) & 0xFF;
    }

    public int getGreen() {
        return (this.value >>  8) & 0xFF;
    }

    public int getBlue() {
        return (this.value >>  0) & 0xFF;
    }

    public void setRed(final int r) {
        this.value = (this.value & 0xFF00FFFF) | ((r & 0xFF) << 16);
    }

    public void setGreen(final int g) {
        this.value = (this.value & 0xFFFF00FF) | ((g & 0xFF) <<  8);
    }

    public void setBlue(final int b) {
        this.value = (this.value & 0xFFFFFF00) | ((b & 0xFF) <<  0);
    }

    @Override
    public String toString() {
        return String.format("rgb = (%3d, %3d, %3d)",
                             this.getRed(),
                             this.getGreen(),
                             this.getBlue());
    }

    public static void main(String[] args) {
        final Pixel pixel = new Pixel(0);
        System.out.println(pixel);
        pixel.setRed(42);
        pixel.setGreen(18);
        pixel.setBlue(225);
        System.out.println(pixel);
        pixel.setRed(-1);
        pixel.setGreen(500);
        pixel.setBlue(1000);
        System.out.println(pixel);
    }
}

运行上述程序的输出:

rgb = (  0,   0,   0)
rgb = ( 42,  18, 225)
rgb = (255, 244, 232)