Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как вырезать определенные данные из файла (https://javascript.ru/forum/misc/56083-kak-vyrezat-opredelennye-dannye-iz-fajjla.html)

Dimaz 29.05.2015 00:25

Как вырезать определенные данные из файла
 
var reader = new FileReader();
reader.onload = function(){
var dataView = new DataView(reader.result);
var ints = new Int32Array(dataView.byteLength);
delete ints[10];
var blob = new Blob([ints], {type: 'image/jpeg'});
}

Картинка после этого не открывается. Как типизированный массив снова перевести в arraybuffer? В качестве аргумента объекта blob должен выступать как раз таки arraybuffer.

laimas 29.05.2015 02:40

Ну так чего бы она открывалась, если нарушить ее. Вы загнали в буфер данные, а это все, включая и заголовок, а потом чикнули что-то не глядя, вот и результат. Прочесть изображение, поместить его в canvas, вот там будет доступно его тело, можно работать с байтами описывающими цвет.

Dimaz 29.05.2015 10:49

Цитата:

Сообщение от laimas (Сообщение 373029)
Ну так чего бы она открывалась, если нарушить ее. Вы загнали в буфер данные, а это все, включая и заголовок, а потом чикнули что-то не глядя, вот и результат. Прочесть изображение, поместить его в canvas, вот там будет доступно его тело, можно работать с байтами описывающими цвет.

Да ничего я не чикал)) Даже если убрать delete ints[10], она не открывается. Тут дело не в картинке. Её я для примера загрузил. Я просто хочу научиться удалять определенные данные из файла. Но как типизированный массив перевести в blob, чтобы сохранить файл я не разберусь.

laimas 29.05.2015 13:12

FileReader API, как получить и манипулировать данными в сети подробно и неоднократно описаны. Ну просто, ради спортивного интереса, что можно определенного убрать в изображении таким образом? Ну к примеру, можно IPTC, что еще? И даже эта операция потребует изучение заголовка, и сперва получение по нему информации в нем, а уж потом...

Dimaz 29.05.2015 17:09

Цитата:

Сообщение от laimas (Сообщение 373071)
FileReader API, как получить и манипулировать данными в сети подробно и неоднократно описаны.

Разобрался на свежую голову))
var ints = new Int32Array(dataView.byteLength);

Этот код просто создает пустой типизированный массив с таким же количеством байтов, как и у файла. Т.е. все данные в нём состоят из сплошных нулей, поэтому картинка и не открывалась. Да и вообще нужно было использовать не Int32Array, а Int8Array.
Решением было в цикле занести все данные из DataView в пустой типизированный массив.
for (var i = 0; i < ints.length; i++) {
ints[i] = dataView.getInt8(i);
}

Теперь картинка открывается. Однако как вырезать данные из этого массива я так и не разобрался.
Цитата:

Сообщение от laimas (Сообщение 373071)
Ну просто, ради спортивного интереса, что можно определенного убрать в изображении таким образом? Ну к примеру, можно IPTC, что еще? И даже эта операция потребует изучение заголовка, и сперва получение по нему информации в нем, а уж потом...

Я же писал, что картинку я для примера взял, чтобы сразу видеть результат. На самом деле я хочу вырезать данные из mp3 файла - сделать нарезчик.

Dimaz 29.05.2015 17:42

Вопрос решен. Допенькал таки)
var ints = new Int8Array(dataView.byteLength-1800);
for (var i = 0; i < ints.length; i++) {
if(i==800) i+=1800;
ints[i] = dataView.getInt8(i);
}

Пропускает 1800 байт, начиная с 800-го байта при копировании в типизированный массив из DataView.

laimas 29.05.2015 18:43

Нарезки говорите, может ffmpeg и на сервере в таком случае?

Dimaz 29.05.2015 19:07

Цитата:

Сообщение от laimas (Сообщение 373132)
Нарезки говорите, может ffmpeg и на сервере в таком случае?

да слышал я про него. уж больно много лишнего в нем. да и хостер говорит, что нужно vds. На клиенте-то круче все равно)
Только что проверил. Вырезает за доли секунды.

Dimaz 29.05.2015 19:10

Новая проблема. Код выше. Код вырезает 1800 байт, начиная с 800-го байта. Однако он вырезает 1800 байт еще и в конце файла. Что не так?

laimas 29.05.2015 20:28

Цитата:

Сообщение от Dimaz
На клиенте-то круче все равно

Чем? Это надо или сесть самому и библиотеку написать или же взять готовую, а не выпендриваться по каждому поводу. ) Хостер ваш многое вам может наговорить, просто не хотят устанавливать, а кому мол надо чешитесь сами.

Цитата:

Сообщение от Dimaz
Что не так?

Условия итерации значит не верны, не достигается конец данных.

kostyanet 29.05.2015 21:02

Научно делается смещение

for (var j=0,i = 0,len=ints.length; i < len; i++) {
    res[i]=data[i+j];
    if(i==800)
        j=1800;
}


фигню написал, туго у меня с итерациями тоже, но принцип именно такой. Иначе у вас получится эквипенисуальная дыра в адресах результирующего файла. Если бы вы писали его в нормальной программе, в смысле.

kostyanet 29.05.2015 21:13

В нормальных программах мы читаем файлы until end, и тут можно, вот так

for (var res=[], j=0, i=0, b; b=ints[i+j]; i++) {
    res[i]=b;
    if(i==800)
        j=1800;
}


Правда я не понял в чем тут сценарий пропустить кусок потока. Сценарий можно написать в массиве, откуда выбирать следующее значение смещения.

Dimaz 29.05.2015 21:51

Цитата:

Сообщение от laimas (Сообщение 373149)
Условия итерации значит не верны, не достигается конец данных.

Нет. Проблема в этом:
var ints = new Int8Array(dataView.byteLength-1800);

Я вычитаю 1800 байт из dataview, поэтому и пропадает. Надо не из исходника вычитать, а из нового созданного массива.
А вообще всё еще проще оказалось:
var buffer1 = reader.result.slice(0,328000);
var buffer2 = reader.result.slice(8551215);
var blob = new Blob([buffer1], {type: 'audio/mp3'});

Метод slice и не нужно никаких dataview и циклов. Мне же нужно просто скопировать данные, а dataview нужен для изменения данных, а не копирования.
Цитата:

Сообщение от laimas (Сообщение 373149)
Чем? Это надо или сесть самому и библиотеку написать или же взять готовую, а не выпендриваться по каждому поводу. ) Хостер ваш многое вам может наговорить, просто не хотят устанавливать, а кому мол надо чешитесь сами.

Например тем, что все обрезание происходит как я уже писал за доли секунды. В случае с сервером нужно сначала скачать файл из нета на комп, потом закачать его на сервак, потом обрезать, потом уже скачать обрезанный файл на комп.
В общем обрезание происходит успешно, файл после этого воспроизводится без проблем. Вопрос можно закрывать:)

Dimaz 29.05.2015 21:54

kostyanet,
спасибо) уже разобрался. причина выше

laimas 30.05.2015 02:05

Цитата:

Сообщение от Dimaz
В случае с сервером нужно сначала скачать файл из нета на комп, потом закачать его на сервак, потом обрезать, потом уже скачать обрезанный файл на комп.

Это с чего вдруг? Можно подумать, что на локальный компьютер файл из интернета получать не надо? Север может и без посредника взять файл по сетевому ресурсу, сделать с ним что хочется, и либо сохранить эти нарезки, либо вернуть их пользователю... Достаточно серверу указать путь сетевой.

А обрезание успешное гарантируется только у евреев, они то знают что режут. :)

kostyanet 30.05.2015 13:18

Интересно что происходит когда время скачивания с сервера превышает max_execution_time сервера?


Часовой пояс GMT +3, время: 17:16.