Потеря пикселей при конвертации

211
11 июля 2018, 20:40

Суть задачи: Есть массив субтитров (long start, long end, string text). Мне нужно в зависимости от времени показа изменять ширину (int) для соответствующего item в RecyclerView. Если конец и начало следующего не совпадает по времени, то добавляю между ними пустой елемент

subs.add(new Subtitle(subtitles.get(i - 1).getEnd(), subtitles.get(i).getStart(), ""));

secInPx = 50; - количесвто пикселей на 1 секунду времени. Сначала пробовал сделать так:

int width = (int) ((end - start)*secInPx)/1000

на каждом субтитре здесь удет потеря долей пикселей.за 45 минут видео (примерно 2000 субтитров) получаю смещение около 400 пикселей.

потом решил добавлять к следующему елементу все то что потеряли ранее. rvWidth - ширина RecyclerView,

rvWidth = (videoDuration / 1000) * Constant.secInPx;
for (int i = 0; i < subtitles.size(); i++) {
     widthSums.add((int) ((subtitles.get(i).getEnd()*rvWidth)/videoDuration));
}
subtitles.get(0).setWidth(widthSums.get(0));
for (int i = 1; i < subtitles.size(); i++) {
    subtitles.get(i).setWidth(widthSums.get(i) - widthSums.get(i-1));
}

сейчас получается смещение примерно в 30 пикселей, те же 45минут, 2000 субтитров.

Как можно еще более точно определать ширину елементов?

Красные линии то где должен начатся показ и конец субтитров "did the allfather"

Answer 1

Если я правильно понял, то происходит накапливание погрешности. Нужно постоянно считать текущее положение от желаемого и прибавлять эту погрешность к следующему кадру. Как пример, когда нужно разделить 100 на 6 кадров, то его ширина каждого кадра должна быть 16.(6), мы округляем и показываем 16(или 17, по желанию), после добавляем эти значения в лог. Так для каждого следующего будет длинна общая желаемая будет как

16.(6) + 16.(6) = 33.(3) 

а действительной

16 + 16 = 32

Вот тут и нужно найти разницу между желаемым и действительным и добавить разницу к последнему кадру. Так разница выходит

33.3 - 32 = 1 

и мы добавляем его к последнему кадру, также увеличивая и реальную ширину на 1, получаем 33. Выходит первый кадр был размером 16, а второй 17 и так они будут чередоваться, оставляя погрешность всегда не более одного пикселя. В таком методе еще есть погрешность округления самого действительного числа, но она не существенна.

ред.

i

nt summWidth = 0;
int expectedWidht = 0;
...

int width = (int) ((end - start)*secInPx)/1000;
summWidth+=width;

здесь все вроде правильно, это получается ширина элемента. Добавить ее в накопленную ширину

expectedWidht = (int) (end*secInPx)/1000

это получается ожидаемая ширина всех элементов

int diff = expectedWidht - summWidth;

Это разница между желаемой шириной и действительной

width+=diff;
summWidth+=diff;

добавить разницу к последнему элементу и в суммарную ширину. Данное действие выполнить для каждого элемента

READ ALSO
Вернуться в начало цикла [дубликат]

Вернуться в начало цикла [дубликат]

На данный вопрос уже ответили:

219
Android studio 3.1.3 проблема с Gradle

Android studio 3.1.3 проблема с Gradle

После установки Windows 10 установил Android Studio, установил нужные пакеты, но при создании нового проекта вылетает ошибка:

278
Удаление часть текста из String (java)

Удаление часть текста из String (java)

Есть строка String N , она имеет какой то текст: Жили были баб-да деда , была у них внучка Люба, очень красивая

223
native-методы в Java

native-методы в Java

Всем доброго времени суток! У меня появился вопрос примерно следующего характераВсё никак не могу понять, где именно хранится реализация...

170