在JAVA中,将图像的RGB值转换为二进制的最快方法是什么?

Syn*_*nia 1 java binary rgb image type-conversion

我试图将图像上任何给定像素的RGB值变为12位二进制,每个通道由4位表示.例如,如果一个像素的红色通道位于"255"或二进制"11111111".我希望将其转换为"1111".

我有一个代码工作,但它很慢,我想知道是否有更好的方法来做到这一点.

这就是我所做的.

  1. 我使用方法getRGB(x,y)来获取一个像素的RGB值.例如-4278864
  2. 我把它转换成3个独立的通道,例如r 190 g 181 b 176
  3. 我将它除以16得到4位表示的整数等价
  4. 我将数字转换为二进制数.
  5. 如果生成的二进制小于4位,则在二进制文件前面添加0.
  6. 连接到12位二进制以表示12位颜色输出.例如101110111011

这是我的代码:

import java.awt.Component;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class LoadImageApp extends Component {
    private static int[] rgbArray;
    private static double bitPerColor = 4.0;

    public static void main(String[] args) {

       BufferedImage img = null;
       String fileName = "Image.jpg";

       try {
           //Read in new image file
           img = ImageIO.read(new File("src/"+fileName));
       } 
       catch (IOException e){
       }

       if (img == null) {
             System.out.println("No image loaded");
        } 
       else {

                //Get RGB Value
                int val = img.getRGB(500, 500);
                System.out.println("rgbValue from getRGB is: " + val);


                //Convert to three separate channels
                int a = (0xff000000 & val) >>> 24;
                int r = (0x00ff0000 & val) >> 16;
                int g = (0x0000ff00 & val) >> 8;
                int b = (0x000000ff & val);

                System.out.println("rgbValue in RGB is: ");
                System.out.println("a " + a + " r " + r + " g " + g + " b " + b);

                double power = Math.pow(2.0, bitPerColor);
                //Convert each channel to binary
                String r4bit = Integer.toBinaryString((int)(r/(power)));
                String g4bit = Integer.toBinaryString((int)(g/(power)));
                String b4bit = Integer.toBinaryString((int)(b/(power)));



                //Convert concatonate 0's in front to get desired bit count
                int rDifference = (int)bitPerColor - r4bit.length();
                int gDifference = (int)bitPerColor - g4bit.length();
                int bDifference = (int)bitPerColor - b4bit.length();


                for (int i = rDifference; i > 0; i--){
                    r4bit="0"+r4bit;}

                for (int i = gDifference; i > 0; i--){
                    g4bit = "0"+g4bit;}

                for (int i = bDifference; i > 0; i--){
                    b4bit = "0"+b4bit;}

                //Concatonate three channel together to form one binary
                String rgbValue = r4bit + g4bit + b4bit;

                System.out.println("rgbValue in binary is: " + rgbValue);


           }     
       }
}
Run Code Online (Sandbox Code Playgroud)

这一切都可以正常工作.然而,只是读取一个像素,它只是真的,非常难看,而且很慢,只需2-3秒.我希望一次使用代码来读取图像的一部分,但我可以用AGES对它进行成像.

所以任何帮助都将非常感激.

提前致谢.

Jim*_*son 5

您的原始代码(十六进制)是0x00rrggbb.你想将其转换为0x00000rgb.这样做:

int rgb24 = ....;
int rgb12 = (rgb24 & 0x00f00000) >> 12 + 
            (rgb24 & 0x0000f000) >> 8  + 
            (rgb24 & 0x000000f0) >> 4;
Run Code Online (Sandbox Code Playgroud)

如果你想"舍入"到最近的颜色而不是截断你可以这样做:

int r = (rgb24 & 0x00ff0000);
int g = (rgb24 & 0x0000ff00);
int b = (rgb24 & 0x000000ff);
r += (r >= 0x00f00000) ? 0x00080000 : 0;
g += (g >= 0x0000f000) ? 0x00000800 : 0;
b += (b >= 0x000000f0) ? 0x00000008 : 0;
int rgb12 = (r & 0x00f00000) >> 12 + (g & 0x0000f000) >> 8 + (b & 0x000000f0) >> 4;
Run Code Online (Sandbox Code Playgroud)

只有当高阶4位不是1111时才会向上舍入(当你冒险溢出时).

  • 如果将8位值转换为4位值,则不可避免地丢弃低位信息.正如将价格四舍五入到最接近的美元一样会损失细节而不是整体幅度.至于颜色是否移位,这也是不可避免的,因为现在每个通道只有16个可能的级别而不是256个. (2认同)