JAVA学习笔记--图像、二进制位运算

图像处理

图片的组成原理:

  • 图片是由若干个像素点组成的。当我们把图片无限放大时,可以看到不同颜色的若干个矩形,这就是像素的形状,所以说一个像素是一个矩阵,并且由一种颜色填充。

  • red、green、blue是计算机中的三基色,每种颜色用1byte(8bit)存储。

    • red:1000 0010 —— 130
    • green:1101 0010 —— 210
    • blue:0101 0101 —— 85
  • 一般的,一个像素点用一个int来存储,由于1int–4byte–32bit,所以可以把int看成一个每行有8位二进制码,一共四行的矩阵:

    • 0000 0000
      0000 0000
      0000 0000
      0000 0000

    如果一个像素的颜色是由红、绿、蓝三者合成的,那么存储它的int就是:

    • 0000 0000
      1000 1000 (R)
      1101 0010 (G)
      0101 0101 (B)

    然后这一串1和0会被转换成一个int类型的数字呈现给我们,这里是8_573_525。

那么问题来了,当我们只有一个int的数字时,我们该如何知道它的R、G、B分别对应的数是多少呢?
毕竟我们在new Color(r,g,b)时,传入的三个参数只是32个bit中的某8个对应的十进制数,而不是8,573,525这样的东西。

位移运算符

  • 位移运算符分为 >>(右移),<<(左移),以及>>>(无符号右移)三种,由于int有且只有32位,所以我以 1100 0101 1011 1001 这样一个数为例,如果我们想取得它的 9–16位,只需要将它右移8位,这样后面的 1011 1001 就被踢出了这个int。
		int x = 50617;		//BIN: 1100 0101 1011 1001
        int x1 = x>>8;
        System.out.println(x1);		//DEC = 197	和我计算器中只计算1100 0101的结果相同
  • 同理,如果我们想要得到1 - 8位,只需要先将这个数左移24位,把9位以后的数全从左侧挤出去,然后再右移回来。需要注意的是,int最左边(32位上)的0和1是表示符号的,当原先第8位的1走到32位时,它不在有计数的意义,而是相当于一个负号。所以在右移时,应当用>>>。
		int x =  50617;		//BIN: 1100 0101 1011 1001
		int x2 = (x<<24)>>24;	//DEC = -71  错误
        int x3 = (x<<24)>>>24;	//DEC = 185  正确
  • 但是这个方法有些麻烦,更为简单的方法是利用&(与运算)。我们把需要的数先右移到最右侧,然后我们想保留几位,就和几个1做&运算(这里的1是二进制码)。
    以1100 0101 1011 1001为例,要获得1 - 8位,就拿这个数 &(0000 0000 1111 1111),前面8个0会消去9 - 16位上的1,而后面8个1则会保留1 - 8位上的1。
		int x = 50617;
		int y = 255;	//将1111 1111 转换为十进制
		int x4 = x & y;		//x4的值仍为185
  • 所以对于上面提到的8_573_525,要得到它的RGB,做法如下:
		int rgb = 8_573_525;	/*BIN = 0000 0000 
										1000 1000
										1101 0010
										0101 0101 */

		int red = (rgb>>16)&255;	//DEC = 130
		int green = (rgb>>8)&255;	//DEC = 210
		int blue = rgb&255;			//DEC = 85
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值