2014-10-06 22 views
2

我有一个类像素,它具有方法getRed,getBlue,getGreen,setRed,setBlue,setGreen(r,g,b) 并且到目前为止所有东西都单独工作,但是当我把它放在一起时setGreen和setBlue不工作。我是否在掩蔽方面做错了什么?在java中编辑像素值

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) 
+0

你怎么想在你的'int'位布局?它应该是标准的'RRGGBB'(其中一个字母表示四位)? – 5gon12eder 2014-10-06 01:53:41

+0

一个像素是一个32位的int值,可以解释为四个8位值的序列。第一个8位值是alpha通道。我们会忽略这一点。接下来的三个8位值分别是像素的红色,绿色和蓝色分量。 – Panthy 2014-10-06 01:54:14

+0

他们是8位而不是4我相信 – Panthy 2014-10-06 01:56:39

回答

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其中XES是一些垃圾,它们起源于旧的蓝色或新的绿色位。你能看到要修复的东西吗?

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) 
+0

是我转移价值的问题? – Panthy 2014-10-06 02:16:46

+0

是的,“像素”的左移(或者在某些部分出来之后仍然存在)是错误的。 – 5gon12eder 2014-10-06 02:18:36

+0

我刚才拿出第一个左移,然后它仍然不起作用 – Panthy 2014-10-06 02:19:40