Запись бинарных данных в файл

bessru

Новичок
Доброго времени суток, уважаемые!
Никогда не думал, что это станет для меня камнем преткновения...

Есть потребность генерить картинку проприетарного формата размером 1х1 пиксель.

Пример содержимого такой картинки:



Здесь:
01000000 - размер по горизонтали
01000000 - размер по вертикали
000000 - RGB пикселя
99 - значение альфа-канала

Размер картинки для моей задачи всегда фиксирован, т.е. первые 16 байт - константа. А вот RGB с альфой мне нужно иметь возможность задать произвольно строкой, например "99000000" (порядок следования слов в строке - обратный).

Пробовал и последовательностью чаров, и паком - все тлен. Проблема в том, что длинные нулевые последовательности неведомым образом сокращаются до 00, и вместо нужного файла длиной 22 байта, я получаю обрубок 12,13 и т.д. байт в зависимости от содержимого строки с RGB+альфа.

Есть у кого соображения как это победить? И почему так происходит?
 

AnrDaemon

Продвинутый новичок
Показывайте, как пробовали. У меня pack влёт прошёл.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Щас окажется, что человек думает, что \x00 — это два байта.
 

bessru

Новичок
24 байт, 1 байт = 8 бит (0-F)

Нерабочий код с паком:

PHP:
$color = str_split('0F000000', 2);
file_put_contents(dirname(__FILE__).'/test.txt', pack('LLhhhh', 1, 1, $color[0], $color[1], $color[2], $color[3]));
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Ну если так пробовать, то конечно не получится.
 

bessru

Новичок
Ладно, пусть будет 12 байт, не суть. Каковы ваши предложения? И почему длинные нулевые последовательности сокращаются?
 

bessru

Новичок
Пробую:
Код:
$color = str_split('0F000000', 2);
$w = 1;
$h = 1;
$r = $color[0];
$g = $color[1];
$b = $color[2];
$a = $color[3];
file_put_contents(dirname(__FILE__).'/test.txt', pack("V2C4", $w, $h, $r, $g, $b, $a));
На выходе:
 

bessru

Новичок
Так тоже не работает:
Код:
$w = 1;
$h = 1;
$r = 0;
$g = 0;
$b = 0;
$a = 1;
file_put_contents(dirname(__FILE__).'/test.txt', pack("V2C4", $w, $h, $r, $g, $b, $a));
На выходе 01 00 01 00 00 С4 80
 

bessru

Новичок
Так мне надо в файл писать, и что на выходе получается - показываю. Да, print bin2hex($packed); выдает правильный результат, т.е. $packed содержит верные данные. Но почему при записи в файл данные искажаются?
 

AnrDaemon

Продвинутый новичок
Потому что ты явно делаешь не то, что показываешь нам.
 

bessru

Новичок
Ну как это не то?! Я же код привожу, и результат. Вы можете у себя набрать и убедиться.

Кстати, изменил входные данные:
Код:
$color = str_split('010203FF', 2);
$w = 1;
$h = 1;
$r = $color[0];
$g = $color[1];
$b = $color[2];
$a = $color[3];
$packed = pack("V2C4", $w, $h, $r, $g, $b, $a));
print bin2hex($packed);
И на выходе 010000000100000001020300, т.е. в конце 00 а не FF

Помогите, плиз, отблагодарю материально.
 

bessru

Новичок
В процессе экспериментов обнаружил, что используемый мной Notepad++ как HEX вьювер - брешет. Тьфу на него, снес к чертям! Поставил WinHEX и убедился, что код, подсказанный уважаемым AnrDaemon, рабочий (извиняюсь за нубство). В итоге получилось следующее:
Код:
$hex_rgb_alpha = '99010203';
$color = str_split($hex_rgb_alpha, 2);
file_put_contents(dirname(__FILE__).'/test.txt', pack("V2C4", 1, 1, hexdec($color[3]), hexdec($color[2]), hexdec($color[1]), hexdec($color[0])));
Спасибо большое, будьте осторожней с Notepad++
 
Последнее редактирование:
Сверху