Название: Запись unsigned char в XML Отправлено: Yuriy от Сентябрь 01, 2011, 16:56 Доброго времени суток!
Есть задача - в файл XML записать изображение предварительного просмотра. получаю unsigned char * с помощью QImage::bits(); соответственно записываю полученные значения в виде строки <stroka>132 255 0 12 и т.д.</stroka> Считывается и записывается изумительно, только вот размер сохраненного XML увеличивается больше чем на размер картинки, аж в 4 раза. Думаю было бы круто кодировать строку вида 132 255 0 12 в кодировку ASCII string, например ABCDEF и т.д Посоветуйте, пожалуйста, как лучше сделать, чтобы не шибко увеличивался размер сохраненного XML-файла. если кодировать, тогда я не набиру 255 символов стандартным набором ASCII, взять заглавные и прописные буквы = 52 символа, + 10 цифр. Итого 62 значения, а требуется 255. Спасибо, за любую помощь ! Название: Re: Запись unsigned char в XML Отправлено: shar от Сентябрь 01, 2011, 17:50 Код: QByteArray::toBase64(); Код: QDataStream & operator<< ( QDataStream & stream, const QImage & image ); Название: Re: Запись unsigned char в XML Отправлено: Yuriy от Сентябрь 01, 2011, 17:59 от base 64 кодирования файл будет еще больше...
Название: Re: Запись unsigned char в XML Отправлено: Пантер от Сентябрь 01, 2011, 18:05 qCompress, а полученное в base64.
Название: Re: Запись unsigned char в XML Отправлено: Yuriy от Сентябрь 01, 2011, 18:43 Млин, просто мозг "заплыл". Получаю вписанное 1:1 изображение:
char(aUnsCharValue); вот и все. ANSI как раз от 0 до 255 задается. Название: Re: Запись unsigned char в XML Отправлено: Yuriy от Сентябрь 01, 2011, 19:16 Теперь пишет 1:1 а считать XML не может. Судя по всему какие-то управляющие символы забиваются. Как их обойти ума не приложу!
Название: Re: Запись unsigned char в XML Отправлено: Yuriy от Сентябрь 01, 2011, 19:58 Unexpected end of file
А какие вообще данные можно в XML закинуть, чтобы он их потом считал, я так понимаю, что в XML много управляющих символов, таких как [, ], <,> и поэтому их нужно избегать при записи. Я думаю, что я не первый кто пытается записать двоичные данные в XML, при этом с возмоностью их зачитать потом Название: Re: Запись unsigned char в XML Отправлено: Пантер от Сентябрь 01, 2011, 20:00 Читай про CDATA и записывай в base64.
Название: Re: Запись unsigned char в XML Отправлено: Странник от Сентябрь 01, 2011, 20:02 Теперь пишет 1:1 а считать XML не может. Судя по всему какие-то управляющие символы забиваются. Как их обойти ума не приложу! XML - текстовый формат, поэтому двоичные данные для хранения необходимо кодировать в Base64. если не устраивает рост размера файла - меняйте формат хранения данных.Название: Re: Запись unsigned char в XML Отправлено: Yuriy от Сентябрь 01, 2011, 20:11 Двоичный формат тоже подцепил, там то как раз и нет проблем. Просто пишу программу, и хочу чтобы она была как можно более открытой, потому как XML можно будет открыть на любой машине и взять с него что угодно, прикрутить плагины и т.д.. Так вот, нужно знать какие управляющие символы из ANSI XML съедает, а какие примет как текст и собрать строку. типа abCfDDFf 137 sdfdf 17 , где 137 и 17 - символы недопустимые для текстовой строки.
Название: Re: Запись unsigned char в XML Отправлено: Yuriy от Сентябрь 01, 2011, 21:40 Наткнулся на такую тему:
http://wladm.narod.ru/C_Sharp/xml003.html Только непонятно как получить формат X2 строки. Название: Re: Запись unsigned char в XML Отправлено: Странник от Сентябрь 02, 2011, 08:25 зачем сооружать велосипед с бесплатным геморроем из материала заказчика, если есть типовые решения? = ) Base64-кодирование увеличит размер картинки на треть, что в вашем случае совершенно не критично. и открытость увеличится - в дебри вашей системы кодирования никому вникать не придется.
Название: Re: Запись unsigned char в XML Отправлено: Fregloin от Сентябрь 02, 2011, 11:31 можно переводить каждый бай в hex.
Название: Re: Запись unsigned char в XML Отправлено: Yuriy от Сентябрь 02, 2011, 14:06 Ок, только 1 к 1 все равно не получится. Сейчас уже получше 1:2:
std::string aValueStr; for (; i <= upper; i++) { char s[33]; itoa(array->Value(i),s,16); std::string aValue(s); if (strlen(s) == 1) aValue = ' '+aValue; aValueStr += aValue; } соответственно получаем строку вида: >89504e47 d a1a a 0 0 0 d49484452 0 0 1f9 0 0 ... а раньше она была бы: >137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 ... А для считывания: for (unsigned int i = 0; i < strlen(aValueStr)/2; ++i) { char * ptr; aValue = strtol (aStrValue.c_str(), &ptr, 16); array->SetValue(i+array->Lower(), aValue); } Итого получаем экономию 100%% и считывание из любого плагина, написанного на ассемблере Название: Re: Запись unsigned char в XML Отправлено: Странник от Сентябрь 02, 2011, 15:21 майн готт. HEX-кодирование и даст 1:2. или вам кажется, что 1:2 лучше, чем 3:4? % )
Название: Re: Запись unsigned char в XML Отправлено: Yuriy от Сентябрь 02, 2011, 19:03 Вот результаты:
Image size: 15 384 XML without image: 104 332 XML with image no encoding: 159 624 XML with image encoded with FF: 139 264 XML with image encoded with base: 178 011 (!) XML with image encoded with default ANSI string: 124 116 Только вот ANSI стринг также содержит ряд управляющих символов... Если бы убрать разделители пробелом, только вот непонятна длина символа, сейчас я строю 3t28261z d a q a 0 0 0 d21201 и анализирую по два символа, а без пробелов реально обойтись ??? Название: Re: Запись unsigned char в XML Отправлено: Fregloin от Сентябрь 05, 2011, 15:09 Код: std::string aValueStr; 002АFFB0... т.е. проблема с управляющими символами решена, но размер файла будет ровно в 2 раза больше чем размер картинки в байтах. Название: Re: Запись unsigned char в XML Отправлено: Странник от Сентябрь 05, 2011, 15:34 Вот результаты: с реализацией кодирования у вас явно беда. HEX всей картинки должно было дать 135 100, а BASE64 всей картинки ~124 844.Image size: 15 384 XML without image: 104 332 XML with image no encoding: 159 624 XML with image encoded with FF: 139 264 XML with image encoded with base: 178 011 (!) XML with image encoded with default ANSI string: 124 116 Название: Re: Запись unsigned char в XML Отправлено: Yuriy от Сентябрь 06, 2011, 17:04 Спасибо, Fregloin
Еще проще без itoa, потому как в Linux его к сожалению нет, а городить его не хотелось бы.... std::string aValueStr; char append[2]; for (; i <= upper; i++) { sprintf(append,"%02x",array->Value(i)); aValueStr += append; } XmlObjMgt::SetStringValue (theTarget, aValueStr.c_str(), Standard_True); теперь вод думаю, как сделать это без использования std::string. Копировать char в char* или все-таки оставить std::string? |