u012643122
思想永无止境
采纳率100%
2015-03-04 10:42

如何才能看懂别人写的位运算代码?

210
已采纳
 import java.awt.Color;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.PixelGrabber;

/**
 * 我知道位运算是什么,怎么运算的,但我实在看不懂别人写的位运算代码,求高人指点我如何才能看懂别人写的位运算代码?
 * 
 * 希望能得到详细的回答,除了将这个类的所有位运算都解释一遍,还请将位运算在java图像处理中有哪些应用告诉我,谢谢!
 */
public class DyedImageUtils {

    /**
     * 根据指定颜色过滤像素
     * 
     * @param pixel
     * @param filterColor
     * @return
     */
    private static int filter(int pixel, Color filterColor) {
        int alpha = pixel >> 24 & 0xff;// 为什么要将pixel进行">> 24"呢,又为什么要"& 0xff"呢,能解释解释这句代码的意义吗?
        if (alpha > 0) {
            pixel = gray(pixel);
            return pixel & filterColor.getRGB();// 同上,这句"按位与"的代码我也不明白为什么要这么做
        } else {
            return 0;
        }
    }

    /**
     * 处理颜色灰度
     * 
     * @param rgb
     * @return
     */
    private static int gray(int rgb) {
        int a = rgb & 0xff000000;// 同上,这句"按位与"的代码我也不明白为什么要这么做
        int r = rgb >> 16 & 0xff;// 同上,不明白为什么要这么做
        int g = rgb >> 8 & 0xff;// 同上
        int b = rgb & 0xff;// 同上
        rgb = r * 77 + g * 151 + b * 28 >> 8;// 同上
        return a | rgb << 16 | rgb << 8 | rgb;// 同上
    }

    /**
     * 对图片进行着色
     * 
     * @param image
     * @param color
     * @return
     */
    public static Image createDyedImage(Image image, Color color) {
        if (color == null) {
            return image;
        } else {
            if (image != null) {

                int w = image.getWidth(null);
                int h = image.getHeight(null);

                int[] pixels = new int[w * h];

                PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h, pixels, 0, w);

                try {

                    pg.grabPixels();

                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                    return null;
                }

                BufferedImage bi = new BufferedImage(w > 1 ? w : 1, h > 1 ? h : 1, BufferedImage.TYPE_INT_ARGB);

                for (int i = 0; i < pixels.length; i++) {

                    int pixel = pixels[i];

                    int row = i / w;
                    int col = i % w;

                    if (color != null) {
                        if (pixel != 0) {

                            pixel = filter(pixel, color);

                        }
                    }
                    bi.setRGB(col, row, pixel);
                }

                return bi;
            } else {
                return null;
            }
        }
    }
}
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

4条回答

  • danielinbiti danielinbiti 6年前

    你要理解RGB的2进制格式,R,G,B的取值范围是0-255,如果是ARGB,前面还有一个透明度0-255。255在2进制中占8位,也就是
    ARGB像素格式(左边最高位,右边最低位):00000000RRRRRRRRGGGGGGGGBBBBBBBB。
    到这个格式你那位移就清楚了,取A得值,只要后面24位都置成0,前8位为1,做与就行了。当然你要>>24&0xff也可以,只是没必要。>>24后,再最后处理完灰度后还得<<24回来。
    取R,G,B都一样原理。

    点赞 2 评论 复制链接分享
  • caozhy 从今以后生命中的每一秒都属于我爱的人 6年前

    很容易理解,>>24就是取一个整数二进制的25~32位。它代表alpha(透明度)通道。
    &0xff就是将这个整数的高位全部置为0,只保留它的低位。
    比如
    int rgb = 1110 0001 1011 0000 1100 0010 0010 0000 (这样写是不合法的,但是为了让你看清,我写成二进制形式)
    a = rgb >> 24 就是往右边移24位,因为最高位是1,所以移动后最高位会填充1。
    此时a = 1111 1111 1111 1111 1111 1111 1110 0001
    然后&0xff就是按位and 0000 0000 0000 0000 0000 0000 1111 1111
    结果就是 0000 0000 0000 0000 0000 0000 1110 0001
    也就是1110 0001,可见将rgb的最高8位取了出来。
    以此类推。

    点赞 4 评论 复制链接分享
  • henuyx Heart09 6年前

    首先,你知道位运算是什么,也知道怎么运算的,这就足够了
    其次,要想看懂别人代码,先要搞明白这段代码是干什么用的
    比如这个filter,目的的根据指定颜色过滤像素的,
    而且通过观察,会发现是一个一个像素进行处理的

    这段代码中,你共提出了八处不理解的
    这个颜色rgb值,你应该明白吧,百度一下就知道了。
    每个值是0到255,占一个byte,rgb共占3个byte。
    而这里一个像素用一个int表示的,int有4个byte。
    那还有1个byte应该是标志什么玩意儿的,这个具体标志什么,应该和你做的项目有一定的关系。
    下面来过一下8处位运算
    首先假设当前像素值为:0xAABBCCDD
    1. 右移24位,即得到0x00000000AA,位与0xff即取得最低的一个byte,即0xAA
    为什么要位与0xff呢,可能是担心高位有不为0的值,其实一般情况下得到的就是0xAA了,
    再位与一下0xff,只是一个保护措施,也是一个很好的习惯。
    还有一种右移可能是循环右移,这样右移24位之后得到的是0xBBCCDDAA,这就很有必要位与一下0xff。
    保证得到的是原来0xAABBCCDD最高的那个0xAA。当然,最后这种可能纯属个人意淫,可以略过。
    2. 当前像素经过gray处理之后,又位与了一个getRGB,这个值可能是一个常量,就像掩码一样。
    比如getRGB得到的是0x0000FF00,就表示,只保留RGB中的G的值。
    再说明白点,就是保留getRGB的值中为1的位。
    3. 这里是保留最高位,这个最高位就是上面说的当前像素的标志位(不属于RGB值)
    在最后那个return处,也可以看到,a又位或返回了,说明当前像素的标志位没有改变
    4. 5. 6. 这三个地方,分别得到了当前像素的R、G、B值
    7. 这个计算有点意思,应该是灰度处理的一种算法,具体怎么得到这个公式的呢?
    你问我,我也只能百度,估计也百度不出来,所以你可以查阅你当前的项目,或许可以查到灰度处理的这个公式。
    8. 这个就是讲最后灰度处理之后的值,返回了。
    那个左移16,左移8,这个还应该是上面说的某种公式,要这么做。
    不过要注意一点的是,这个时候最高位a处的值,可能会被改变,而且这种位或也可能互相影响了RGB值。
    具体什么作用,我也不装x解释了,因为关于颜色RGB灰度处理公式的玩意儿,我也不知道怎么回事!

    最后,你问的那个,位运算在java图象处理中有哪些应用。这个要你自己查一下了。
    你既然研究图象处理,肯定要自己多多查阅相关资料了。
    希望这点儿解释能有帮到你什么忙。

    点赞 1 评论 复制链接分享
  • meng20166 乐古 6年前

    如果是基本的看懂得话,记着关键字,等结合它本身的意思,把变量带入就可以了。看代码时在头脑里一步一步的“执行”下去!其实就像读课文以样,都有固定的模式,多读几遍也就熟了

    点赞 评论 复制链接分享

相关推荐