Разбор файла .cube
Во-первых, вам нужно проанализировать файл .cube. OpenColorIO показывает, как это сделать на C++. У него есть несколько способов анализа файлов LUT, таких как .cube, .lut и т. д. Например, FileFormatIridasCube.cpp показывает, как обрабатывать файл .cube.
Вы можете легко получить размер с помощью LUT_3D_SIZE. Я связался с инженером по алгоритмам обработки изображений. Вот что он сказал:
- Как правило, в отрасли куб 17 ^ 3 считается предварительным, 33 ^ 3 - нормальным и 65 ^ 3 - для вывода самого высокого качества.
Обратите внимание, что в файле .cube мы можем получить 3*LUT_3D_SIZE^3 числа с плавающей запятой. Ключевым моментом является то, что делать с массивом float. Мы не можем установить этот массив в куб в ScriptIntrinsic3DLUT с Распределением. Прежде чем сделать это, нам нужно обработать массив с плавающей запятой.
Обработка данных в файле .cube
Как мы знаем, каждый компонент RGB является 8-битным целым, если он имеет 8-битную глубину. R находится в старших 8 битах, G — в середине, а B — в младших 8 битах. Таким образом, 24-битный int может содержать эти три компонента одновременно.
В файле .cube каждая строка данных содержит 3 числа с плавающей запятой. Обратите внимание: синий компонент идет первым!!!
Я делаю этот вывод методом проб и ошибок. (Или кто-то может дать более точное объяснение.)
Каждое число с плавающей запятой представляет собой коэффициент компонента по 255. Следовательно, нам нужно вычислить реальное значение с этими тремя компонентами:
int getRGBColorValue(float b, float g, float r) {
int bcol = (int) (255 * clamp(b, 0.f, 1.f));
int gcol = (int) (255 * clamp(g, 0.f, 1.f));
int rcol = (int) (255 * clamp(r, 0.f, 1.f));
return bcol | (gcol << 8) | (rcol << 16);
}
Таким образом, мы можем получить целое число из каждой строки данных, которая содержит 3 числа с плавающей запятой. И, наконец, мы получаем целочисленный массив, длина которого составляет LUT_3D_SIZE^3. Ожидается, что этот массив будет применен к кубу.
ScriptIntrinsic3DLUT
RsLutDemo показывает, как применять ScriptIntrinsic3DLUT.
RenderScript mRs;
Bitmap mBitmap;
Bitmap mLutBitmap;
ScriptIntrinsic3DLUT mScriptlut;
Bitmap mOutputBitmap;
Allocation mAllocIn;
Allocation mAllocOut;
Allocation mAllocCube;
...
int redDim, greenDim, blueDim;
int[] lut;
if (mScriptlut == null) {
mScriptlut = ScriptIntrinsic3DLUT.create(mRs, Element.U8_4(mRs));
}
if (mBitmap == null) {
mBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.bugs);
mOutputBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), mBitmap.getConfig());
mAllocIn = Allocation.createFromBitmap(mRs, mBitmap);
mAllocOut = Allocation.createFromBitmap(mRs, mOutputBitmap);
}
...
// get the expected lut[] from .cube file.
...
Type.Builder tb = new Type.Builder(mRs, Element.U8_4(mRs));
tb.setX(redDim).setY(greenDim).setZ(blueDim);
Type t = tb.create();
mAllocCube = Allocation.createTyped(mRs, t);
mAllocCube.copyFromUnchecked(lut);
mScriptlut.setLUT(mAllocCube);
mScriptlut.forEach(mAllocIn, mAllocOut);
mAllocOut.copyTo(mOutputBitmap);
Демо
Я закончил демонстрацию, чтобы показать работу. Вы можете просмотреть его на Github.
Спасибо.
person
Vensent Wang
schedule
09.03.2018