【问题标题】:signed int to unsigned byte and vice versa有符号整数到无符号字节,反之亦然
【发布时间】:2011-08-09 07:01:57
【问题描述】:

我有一个签名值,例如-7368817 当我将其转换为字节时,它将类似于:-113 我将它转换为无符号字节再见& 0xff,它将类似于 143 现在我操纵这个字节值,然后我想完全回来!获取新字节的有符号整数。 :)

更新

整个故事:

我有一个 8 位深度和灰度的图像!这意味着所有像素都使用 1 字节呈现

BufferedImage image = ImageIO.read(new File("my_grayscal_8bit_photo.jpg"));

int intPixel = image.getRGB(1, 1);

现在我需要对这个像素进行一些位操作,但由于它是 int 我必须先将其转换为字节:

byte bytePixel = (byte) intPixel;

并使其无符号:

int intPixel2 = bytePixel & 0xff;

现在我进行位操作,并希望将其转换为 int 并执行以下操作:

image.setRGB(1, 1, neworiginalint);

【问题讨论】:

  • 我假设你知道 java 没有无符号类型(除了 char)
  • 而且一个字节只能保存 256 个值,即 2^8 作为它的 8 位。恕我直言,如果您愿意,您可以将字节用作无符号,您不会从 Java 中获得太多帮助。
  • 最后一次从 byte 转换为 int 的结果应该是什么?由于 byte 的整个值范围适合 int 它仍然是 143?您究竟想通过这种转化做什么?
  • 顺便说一句:如果您可以将每个可能的值放入 1 字节 byte 中,那么拥有 4 字节 int 的意义何在 ;)
  • 我知道Java没有无符号类型,所以我把无符号字节放在一个int中。

标签: java byte int pixel unsigned


【解决方案1】:

您是在问如何在有符号 int 中操作最低有效字节,而不触及更高有效字节?
可以这样做:

int i = -7368817; // 0xFF8F 8F8F
int b = i & 0xFF; // "signed byte", = 0x8F = 143
b += 0x2C; // your manipulation, result = 0xBB
i = (i & 0xFFFFFF00) | (b & 0xFF); // result of LSB modification = 0xFF8F8FBB

或者在一个步骤中:i = (i & 0xFFFFFF00) | ((i + 0x2C) & 0xFF);,如果这是一个简单的操作。

如果操作永远不会产生溢出,您可以简单地对整个 int 进行操作:
i ^= 0x34; // i = 0xFF8F8FBB

【讨论】:

    【解决方案2】:

    getRGB(int x, int y) 方法总是TYPE_INT_ARGB 颜色模型中返回一个int 像素。要手动提取像素的红色、绿色、蓝色和 alpha 值,您可以这样做:

    int pixel = image.getRGB(1, 1);
    int a = (pixel >> 24) & 0xFF;
    int r = (pixel >> 16) & 0xFF;
    int g = (pixel >> 8) & 0xFF;
    int b = pixel & 0xFF;
    

    或者为了方便使用Color(int rgba, boolean hasalpha)构造函数(以性能为代价)。处理完红色、绿色、蓝色和 alpha 值(范围为 0 到 255)后,您可以将它们重新组合成 int 以设置像素:

    int newPixel = (a << 24) | (r << 16) | (g << 8) | b;
    

    使用您在此代码中提到的 -7368817 像素,alpha 为 255(因此没有透明度),红色、绿色和蓝色值均为 143。由于您正在处理灰度,您可以选择任何红色,绿色或蓝色以获得灰度值。然而,在设置像素时,您将设置所有三个以保持灰度,因为它是 RGB。你可以这样简化它:

    int pixel = image.getRGB(1, 1);
    
    // extract your gray value from blue, assume red and green are same
    int gray = pixel & 0xFF; 
    
    // this method does your manipulation on the gray value, 0 to 255
    gray = manipulate(gray);
    
    // recombine back into int, preserving the original alpha
    int newPixel = (pixel & 0xFF000000) | (gray << 16) | (gray << 8) | gray;
    
    // now you can set your new pixel
    image.setRGB(1, 1, nexPixel);
    

    基本上,诀窍是使用int 作为您的无符号字节。只要确保将值保持在 0 到 255 之间,一切都会正常工作。

    【讨论】:

      猜你喜欢
      • 2019-07-23
      • 2011-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-08
      • 2012-03-06
      相关资源
      最近更新 更多