перенести jpeg с c++ на android (java)

Я борюсь с передачей простого файла jpeg внутри тега ID3v2 из С++ через сокет TCP в java (Android). Библиотека «taglib» предлагает извлечь этот файл, и я могу сохранить jpeg как новый файл.

Функция отправки выглядит так

char *parameter_full = new char[f3->picture().size()+2];
sprintf(parameter_full,"%s\n\0",f3->picture().data());

// send
result = send(c,parameter_full,strlen(parameter_full),0);

delete[] parameter_full;

куда

f3->picture().data() возвращает указатель на внутреннюю структуру данных (она возвращает char*), а f3->picture().size() возвращает размер массива.

Затем Android получает его с помощью

String imageString = inFromServer.readLine();
byte[] imageBytes = imageString.getBytes();
Bitmap cover = BitmapFactory.decodeByteArray(imageBytes,0,imageBytes.length);

Но почему-то decodeByteArray всегда возвращает null. Моя идея заключается в том, что Java неправильно получает изображение, потому что imageString состоит только из 4 символов... в то время как извлеченный файл jpeg имеет размер 12,7 КБ. Но что пошло не так?

Мартин


person martin    schedule 30.03.2011    source источник
comment
Не читайте его как строку. Это не струна. Прочитайте его как необработанные байты.   -  person Matt Ball    schedule 30.03.2011


Ответы (1)


Вы не должны использовать строковые функции для байтовых данных, потому что значения 0 принимаются в качестве разделителей строк. Попробуйте изучить memcpy на стороне C++, если вам нужно скопировать char*, а также функции чтения byte[] для InputStream на стороне Java.

person Matthew Willis    schedule 30.03.2011
comment
Ах, спасибо за эту подсказку! Теперь это работает. Сначала я передаю размер файла в байтах (coverLength), а затем каждый байт картинки с помощью send(c, f3->picture().data(), coverLength, 0). CoverLength получен правильно, но почему-то функция read(byte[], int, int) останавливается слишком рано. int length = inputStream.read(imageBytes, 0, coverLength) всегда возвращает меньше, чем байты coverLength... - person martin; 31.03.2011
comment
Да, вы не обязательно получите весь массив байтов сразу. Вы должны вызвать чтение в цикле и отслеживать, сколько байтов вы прочитали. В качестве альтернативы вы можете использовать Apache commons IOUtils, который имеет хороший служебный метод под названием toByteArray: commons.apache.org/io/api-release/org/apache/commons/io/ - person Matthew Willis; 31.03.2011
comment
Ах, максимальный размер пакета, спасибо! IOUtils недоступен в Android SDK. После тяжелой борьбы передача почти работает. Сначала я отправляю длину: sprintf_s(buf, 10, %d\n, coverLength); отправить (c, buf, strlen (buf), 0); а затем отправляются фрагменты данных. Одновременно считываются данные. CoverLength с inFromServer.readLine() и данные с for (int count = 0; count ‹ coverLength; count++) imageBytes[count] = (byte)inputStream.read(); Но это работает только тогда, когда я прерываю процедуру отправки между ними. В противном случае read() блокируется. Что случилось сейчас? - person martin; 31.03.2011
comment
Вероятно, вы пытаетесь прочитать слишком много байтов из потока. Попробуйте поиграть с coverLength. Также обратите внимание, что чтение в массивы байтов намного эффективнее, чем чтение по одному байту за раз. - person Matthew Willis; 31.03.2011
comment
Я также пробовал это с inputStream.read(imageBytes, 0, coverLength); но проблема остается. Даже с файлом всего 383 байта... Извините :| - person martin; 31.03.2011
comment
Вы должны проверить количество байтов, фактически возвращенное read, а затем обновить свое начало и смещение. - person Matthew Willis; 31.03.2011
comment
Извините, но я думаю, что исходная проблема все еще присутствует. Даже с read() внутри цикла while я могу заставить его работать, но только тогда, когда я прерываю процедуру отправки с помощью отладчика. В противном случае read() всегда блокируется, и даже inputStream. available() внутри цикла while всегда возвращает 0... - person martin; 31.03.2011
comment
Он блокируется при первом вызове, поэтому не передается ни одного блока. Как будто в потоке нет байтов... - person martin; 31.03.2011