Массив байтов в оттенках серого. Android сфотографировать

Когда я делаю фотографию в Android, я получаю массив байтов от камеры. Я хотел бы преобразовать этот массив (изображение) в 2 цвета - белый и черный. Любые идеи? Изменение режима камеры на моно/негатив не является решением для меня.

Привет.

EDIT1: код на Java


person CallMePedro    schedule 05.08.2020    source источник


Ответы (1)


Прежде всего, вам нужно создать растровое изображение из вашего массива:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
// data is your byte array
Bitmap bmpOriginal = BitmapFactory.decodeByteArray(data, 0, data.length, options); 
Canvas canvas = new Canvas(bmpOriginal);
Bitmap bmpGrayscale = toGrayscale(bmpOriginal);
bmpOriginal.recycle(); // free memory immediately, as your bitmap is not garbage collected by now.

Затем вы можете передать свое bmpOriginal, цветное изображение, методу преобразования

public Bitmap toGrayscale(Bitmap bmpOriginal) {        
    int width, height;
    height = bmpOriginal.getHeight();
    width = bmpOriginal.getWidth();    

    Bitmap bmpGrayscale = Bitmap.createBitmap(width, height,    Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(bmpGrayscale);
    Paint paint = new Paint();
    ColorMatrix cm = new ColorMatrix();
    cm.setSaturation(0);
    ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
    paint.setColorFilter(f);
    c.drawBitmap(bmpOriginal, 0, 0, paint);
    return bmpGrayscale;
}

Приведенный выше код даст вам растровое изображение в градациях серого. Он просто применяет фильтр нулевой насыщенности к изображению. Так как насыщенность - это чистота цвета, чем меньше чистота - тем меньше цветовая разница. После применения вышеуказанного фильтра единственная разница, которую вы получите, это яркость. Самый яркий — белый, самый темный — черный. Если вы хотите преобразовать его обратно в массив байтов, вы можете попробовать что-то вроде этого:

Bitmap bmpGrayscale = intent.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmpGrayscale.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
bmpGrayscale.recycle(); // free memory immediately, as your bitmap is not garbage collected by now.
person Steyrix    schedule 05.08.2020
comment
К сожалению, фабрика растровых изображений всегда возвращает ноль - person CallMePedro; 05.08.2020
comment
@CallMePedro Я думаю, что этот вопрос может помочь вам преобразовать NV21 в предпочтительный формат stackoverflow.com/questions/32276522/ - person Steyrix; 05.08.2020
comment
Да, я проверил это, но обратного пути к байтовому массиву нет. Сохраняется как IMG и все. После всех преобразований мне все еще нужно вернуться к предыдущему формату байтов, потому что этот массив байтов сканируется как изображение кода qr - person CallMePedro; 05.08.2020
comment
@CallMePedro на самом деле, верхний ответ показывает, как вы можете использовать его для создания растрового объекта. Затем вы можете получить байты из растрового изображения, вероятно - person Steyrix; 05.08.2020
comment
да ты был прав. Однако эта душа дала мне растровое изображение только одного зеленого цвета. Но, по крайней мере, я двигаюсь вперед :) - person CallMePedro; 05.08.2020