【问题标题】:How to correctly convert from rgb565 to rgb888如何正确从 rgb565 转换为 rgb888
【发布时间】:2014-06-15 11:37:25
【问题描述】:

我正在尝试将值从 rgb565 转换为 rgb888,但我似乎无法正确处理。 我还检查了一些现有答案,例如 this one,但有些值似乎没有正确转换。

这是我迄今为止尝试过的:

PImage picker;
int c;
void setup(){
  size(285,240);
  picker = loadImage("hsv.gif");
  int c = color(255,255,255);
  byte[] word = colorToWord(c);
  int[] rgb = wordToRGB(word);

  noStroke();
  fill(c);
  rect(0,0,50,100);
  fill(rgb[0],rgb[1],rgb[2]);
  rect(50,0,50,100);
}
void draw(){
  image(picker,0,0);
  if((mouseX >= 0 && mouseX <= picker.width)&&
     (mouseY >= 0 && mouseY <= picker.height)) c = picker.get(mouseX,mouseY);

  byte[] word = colorToWord(c);
  int[] rgb = wordToRGB(word);
//  int[] rgb = rgbWordToRGB(word);
  int cc = color(rgb[0],rgb[1],rgb[2]);

  fill(c);
  rect(0,159,142,80);
  fill(cc);
  rect(142,159,143,80);
  fill(0);
  text("original\n"+hex(c),10,185);
  text("converted\n"+hex(cc),152,185);
}

byte[] colorToWord(int c){
  int r = (c >> 16) & 0xFF;
  int g = (c >> 8)  & 0xFF;
  int b =  c        & 0xFF;
  return new byte[]{(byte)((r&248)|g>>5),(byte)((g&28)<<3|b>>3)};
}
int[] wordToRGB3(byte[] data){
// Reconstruct 16 bit rgb565 value from two bytes
  int rgb565 = (data[0] & 255) | ((data[1] & 255) << 8);

  // Extract raw component values (range 0..31 for g and b, 0..63 for g)  
  int b5 = rgb565 & 0x1f;
  int g6 = (rgb565 >> 5) & 0x3f;
  int r5 = (rgb565 >> 11) & 0x1f;

  // Scale components up to 8 bit: 
  // Shift left and fill empty bits at the end with the highest bits,
  // so 00000 is extended to 000000000 but 11111 is extended to 11111111
  int b = (b5 << 3) | (b5 >> 2);
  int g = (g6 << 2) | (g6 >> 4);
  int r = (r5 << 3) | (r5 >> 2); 
  return new int[]{r,g,b};
}
int[] wordToRGB2(byte[] word){
  int r = word[0]&248;
  int g = (word[0]<<5) | ((word[1]&28)>>3);
  int b = word[1] << 3;
  r <<= 3;
  g <<= 2;
  b <<= 3;
  return new int[]{r,g,b};
}
int[] wordToRGB(byte[] word){
  int c = (word[0] << 8) | (word[1]);
  //RGB565
  int r = (c >> (6+5)) & 0x01F;
  int g = (c >> 5) & 0x03F;
  int b = (c) & 0x01F;
  //RGB888 - amplify
  r <<= 3;
  g <<= 2;
  b <<= 3; 
  return new int[]{r,g,b};
}
final int RGB565_MASK_RED       = 0xF800;
final int RGB565_MASK_GREEN     = 0x07E0;  
final int RGB565_MASK_BLUE      = 0x001F; 

int[] rgbWordToRGB(byte[] word){
 int rgb565 = (word[0] << 8) | (word[1]);
 int[] rgb24 = new int[3];
 rgb24[2] = (rgb565 & RGB565_MASK_RED) >> 11;     
 rgb24[1] = (rgb565 & RGB565_MASK_GREEN) >> 5;  
 rgb24[0] = (rgb565 & RGB565_MASK_BLUE);  

 //amplify the image  
 rgb24[2] <<= 3;  
 rgb24[1] <<= 2;  
 rgb24[0] <<= 3; 
 return rgb24;
}

将此图像用作调色板:

问题在于某些值:

为什么会这样?有没有办法解决这个问题?

【问题讨论】:

  • 嘿伙计:D 如果我可以添加一些代码来帮助您在绘图函数中进行调试: for(int i = 0; i

标签: java colors bit-manipulation processing


【解决方案1】:

好的,如果我理解正确,这就是解决方法:

在你的 wordToRGB() 方法中替换第一行:

int c = (word[0] << 8) | (word[1]);

  int c = (word[0] << 8) | (word[1] & 0xFF);

从 byte 转换为 int 时会出现问题。示例 1:

int a = 255;
println(binary(a));

int b = (byte) 255;
println(binary(b));

打印:

00000000000000000000000011111111
11111111111111111111111111111111

示例 2:

int a = 127;
println(binary(a));

int b = (byte) 127;
println(binary(b));

打印:

00000000000000000000000001111111
00000000000000000000000001111111

无论你最后一点是什么,左边的处理垫,所以基本上在那之后,你的 |扭曲了所有的价值观。

【讨论】:

  • 一开始我以为它只会用 1 填充,所以我想知道为什么它碰巧没有显示红色...
  • 带 0xFF 掩码的 d'oh 时刻 :) 谢谢 Petros!
【解决方案2】:

&gt;&gt; 是算术移位,所以它会符号扩展值。改用逻辑移位&gt;&gt;&gt;

在 C 中,没有 &gt;&gt;&gt; 运算符,右移取决于实现,但如果变量是无符号的,大多数会进行逻辑移位,所以只需将其强制转换或定义为无符号

【讨论】:

  • 感谢 Lưu,这很方便 (+1)
  • &gt;&gt; on unsigned always 是 C 中的一个逻辑转换(毕竟,你为什么要对一个不可能的整数进行符号扩展?消极的?)。它是有符号的,可以是算术的也可以是逻辑的。
猜你喜欢
  • 2011-01-27
  • 1970-01-01
  • 1970-01-01
  • 2017-12-02
  • 1970-01-01
  • 1970-01-01
  • 2013-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多