Отрицательные значения оттенков серого — растровое изображение

Я использую следующий код, чтобы получить значения R, G, B для изображения в градациях серого (все они будут одинаковыми). Но на выходе я получаю отрицательные значения.

Почему это так? Я совершенно сбит с толку.

for (int i=0;i<bb.getWidth();i++){
                            for (int j=0;j<bb.getHeight();j++){
                                    long temp=bb.getPixel(i, j);
                                    int a=(int)temp;
                                    ByteBuffer b = ByteBuffer.allocate(4);
                                    b.putInt(a  );
                                    byte[] result = b.array();                                      
                                    Log.d("gray value is=", String.valueOf((int)result[1]));
                                //  Log.d("gray value is=", String.valueOf(getLastBytes(a)));
                            }
                        }

Здесь результат[1] должен соответствовать значению 'R'. Так как же это отрицательно?


person Aakash Anuj    schedule 07.12.2012    source источник
comment
Проверьте размер переменной результата. Оттенки серого не имеют RGB, это только 2-мерный   -  person nayab    schedule 08.12.2012
comment
@Надош Как это поможет?   -  person Aakash Anuj    schedule 08.12.2012
comment
@Nadosh Вы неверно истолковали это ... с точки зрения хранения в оттенках серого в Android есть 8 полей ... изображения в оттенках серого имеют равные байты R, G, B с точки зрения хранения. Например. temp имеет такие значения, как 133585214   -  person Aakash Anuj    schedule 08.12.2012
comment
Оттенки серого являются двухмерными, вы не можете получить r, g, b; также проверьте значение самого «а»   -  person nayab    schedule 08.12.2012
comment
@Надош Ты, пожалуйста, прочитай об этом. Значение a очень велико, что эквивалентно десятичному представлению шестнадцатеричного значения.   -  person Aakash Anuj    schedule 08.12.2012


Ответы (2)


Попробуй это

        long temp=bb.getPixel(i, j);
        R = Color.red(temp);
        G = Color.green(temp);
        B = Color.blue(temp);
person nayab    schedule 07.12.2012
comment
Спасибо !! Вот с этим все было так просто :) - person Aakash Anuj; 08.12.2012

Это происходит из-за всех изменений типов, связанного с ними приведения и того факта, что эти типы подписаны.

Прежде всего, начальное возвращаемое значение getPixel() равно int (32 бита или 4 байта, один байт для ARGB). Помещение его в длинное здесь кажется ненужным, потому что вы просто возвращаете его обратно в int. Но пока все хорошо.

Когда вы получаете массив байтов, вы правы, что четыре байта для ARGB идут по порядку, поэтому result[1] должно быть красным значением. Однако, когда вы неявно приводите этот байт к типу int в своем операторе журнала, возникает проблема.

Поскольку int имеет длину четыре байта, а int и byte являются знаковыми типами, к результату применяется знаковое расширение, т.е.

  • Байт 0x48 будет расширяться до int как 0x00000048.
  • Байт 0x88 будет расширяться до int как 0xFFFFFF88.

Поэтому, когда вы печатаете результат в журнал, он интерпретирует десятичное значение ваших данных как отрицательное число. По общему признанию, даже если вы не приводили и просто печатали значение byte, этот тип все еще подписан (т. е. он идет от -128 до 127, а не от 0 до 255, а 0x88 означает -120), поэтому вывод журнала будет тоже самое.

Если вы хотите вывести фактическое значение 0-255, измените свой код, чтобы замаскировать данные пикселей, чтобы отменить расширение знака в int:

int red = (int)(result[1] & 0xFF);
Log.d("gray value is=", String.valueOf(red));
person devunwired    schedule 07.12.2012