MSSQL и картинки в нём
Модератор: Модераторы
MSSQL и картинки в нём
Есть БД MSSQL и в ней, в поле типа image, хранятся небольшие GIF-картинки.
Проблема вот в чём. Хранятся они там не просто так, а каким-то непонятным образом. Вот для примера:
http://files.kraslib.ru/pic/01.jpg
Первые семь байт в этом поле - это нечто, потом идут байты, очень похожие на нормальный GIF, а последние 4 байта - это опять нечто непонятное. Соответственно, если загрузить этот набор байтов себе в программу, никакой картинки не будет.
Если удалить первые 7 байт и последние 4, опять же картинка не получается, вместо реальной картинки выходит какая-то билибирда, т.к. в сравнении с настоящей картинкой там ряд байтов заменены по непонятному мне алгоритму.
Рытьё в интернете понимания мне не принесло. Подскажите кто-нибудь, в чём может быть проблема...
Проблема вот в чём. Хранятся они там не просто так, а каким-то непонятным образом. Вот для примера:
http://files.kraslib.ru/pic/01.jpg
Первые семь байт в этом поле - это нечто, потом идут байты, очень похожие на нормальный GIF, а последние 4 байта - это опять нечто непонятное. Соответственно, если загрузить этот набор байтов себе в программу, никакой картинки не будет.
Если удалить первые 7 байт и последние 4, опять же картинка не получается, вместо реальной картинки выходит какая-то билибирда, т.к. в сравнении с настоящей картинкой там ряд байтов заменены по непонятному мне алгоритму.
Рытьё в интернете понимания мне не принесло. Подскажите кто-нибудь, в чём может быть проблема...
alexs
Я не сохраняю. БД досталась уже готовая. К ней была программа, которую писали на Дельфи ещё в 2001 году. С тех пор нет ни исходников, ни программиста, который это писал. Осталась только база, а вот прога на Windows 7 глючит иногда. Причину почему мы так и не выяснили. Хотел прогу переписать на Lazarus.
Я не сохраняю. БД досталась уже готовая. К ней была программа, которую писали на Дельфи ещё в 2001 году. С тех пор нет ни исходников, ни программиста, который это писал. Осталась только база, а вот прога на Windows 7 глючит иногда. Причину почему мы так и не выяснили. Хотел прогу переписать на Lazarus.
-
Padre_Mortius
- энтузиаст
- Сообщения: 1265
- Зарегистрирован: 29.05.2007 17:38:07
- Откуда: Спб
Vadim, формат поля в базе какой?
Чтоб наверняка , поставьте MS Access и через ODBC подрубитесь к базе, Акцесс понимает формат Микрософта
Сам с таким сталкивался, для Lazarus для отображения OLE нужен костыль, гдето была процедура
Сам с таким сталкивался, для Lazarus для отображения OLE нужен костыль, гдето была процедура
-
Padre_Mortius
- энтузиаст
- Сообщения: 1265
- Зарегистрирован: 29.05.2007 17:38:07
- Откуда: Спб
Не увидел тип поля... попробуйте преобразовать данное поле в тип binary с помощью convert(binary, FieldName)
По идее этого должно хватить.
По идее этого должно хватить.
Padre_Mortius
Спасибо, сегодня попробую.
Добавлено спустя 8 часов 25 минут 24 секунды:
Padre_Mortius
К сожалению Ваш совет не помог. По всей видимости тип image и тип binary - в mssql одно и то же. На выходе при конвертировании тоже самое, что и без.
Спасибо, сегодня попробую.
Добавлено спустя 8 часов 25 минут 24 секунды:
Padre_Mortius
К сожалению Ваш совет не помог. По всей видимости тип image и тип binary - в mssql одно и то же. На выходе при конвертировании тоже самое, что и без.
возможно не по теме:
1. судя по гуглению то gif хранятся как отдельные картинки: картинка + № (http://msdn.microsoft.com/en-us/library/aa275080%28SQL.80%29.aspx)
2. http://stackoverflow.com/questions/959160/load-jpg-gif-bitmap-and-convert-to-bitmap х.з. может чет даст.
Хотя, по куску "хекса" судить о ситуации. Барабан нужен боольщщщой... т.е. "мацальный" рефлекс := нет. Осталось гадание.
1. судя по гуглению то gif хранятся как отдельные картинки: картинка + № (http://msdn.microsoft.com/en-us/library/aa275080%28SQL.80%29.aspx)
2. http://stackoverflow.com/questions/959160/load-jpg-gif-bitmap-and-convert-to-bitmap х.з. может чет даст.
Хотя, по куску "хекса" судить о ситуации. Барабан нужен боольщщщой... т.е. "мацальный" рефлекс := нет. Осталось гадание.
В архиве два файла:
- 3.gif - то, что должно быть на рисунке;
- 3.out - то, что хранится в БД в поле рисунка.
http://files.kraslib.ru/pic/out.zip
Рисунок самый обычный, "одиночный".
Добавлено спустя 3 минуты 17 секунд:
Вопрос вдогонку: кто-нибудь занимался вытаскиванием OLE-объектов из БД? Вполне возможно, что рисунок там хранится в виде OLE-объекта.
- 3.gif - то, что должно быть на рисунке;
- 3.out - то, что хранится в БД в поле рисунка.
http://files.kraslib.ru/pic/out.zip
Рисунок самый обычный, "одиночный".
Добавлено спустя 3 минуты 17 секунд:
Вопрос вдогонку: кто-нибудь занимался вытаскиванием OLE-объектов из БД? Вполне возможно, что рисунок там хранится в виде OLE-объекта.
Тебе не это случаем нужно?
http://www.codeproject.com/Articles/909 ... ype-in-SQL
Вообще, если в лоб пойти...
у тебя, если посмотришь, оригинал занимает 17 041 байт, а итоговый файл после обработки 17 057 байт. Если откроешь файл в hex редакторе или блокноте, то увидишь что по сравнению с начальным итог отличается наличием в начале и конце приписанных байтов. Судя по статье выше, это маркеры. Если убрать в начале и конце байты то получится размер 17 046.. т.е. еще 5 байт где то сидят(я блокнотом редактировал, может он просто не отображает как символы какие то байты). Если пройдешься сравнением байт, между двумя образцами, то сможешь найти где что не совпадает.
Добавлено спустя 38 минут 32 секунды:
Это как автор БД захочет. К примеру при установке форума на сервак, у админа есть возможность выбирать, как хранить картинки в отдельной папке или же в самой БД.
http://www.codeproject.com/Articles/909 ... ype-in-SQL
Вообще, если в лоб пойти...
у тебя, если посмотришь, оригинал занимает 17 041 байт, а итоговый файл после обработки 17 057 байт. Если откроешь файл в hex редакторе или блокноте, то увидишь что по сравнению с начальным итог отличается наличием в начале и конце приписанных байтов. Судя по статье выше, это маркеры. Если убрать в начале и конце байты то получится размер 17 046.. т.е. еще 5 байт где то сидят(я блокнотом редактировал, может он просто не отображает как символы какие то байты). Если пройдешься сравнением байт, между двумя образцами, то сможешь найти где что не совпадает.
Добавлено спустя 38 минут 32 секунды:
pupsik писал(а):судя по гуглению то gif хранятся как отдельные картинки: картинка
Это как автор БД захочет. К примеру при установке форума на сервак, у админа есть возможность выбирать, как хранить картинки в отдельной папке или же в самой БД.
-
Padre_Mortius
- энтузиаст
- Сообщения: 1265
- Зарегистрирован: 29.05.2007 17:38:07
- Откуда: Спб
Судя по всему, используется какой-то алгоритм замены байт местами. Очень познавательную разницу выдает команда fc если убрать первые несколько байт до заголовка GIF-файла и после символа двоеточия в конце. Как раз видно, что определенные байты поменяны местами.
Начало очень интересное. (x-1)93 байт меняется местами с (x)93 байтом. И это продолжается достаточно долго (158 повторов). Если нужно, то могу попробовать вскрыть алгоритм данного шифрования. Думаю, что эти "лишние" байты совсем не лишние.
Начало очень интересное. (x-1)93 байт меняется местами с (x)93 байтом. И это продолжается достаточно долго (158 повторов). Если нужно, то могу попробовать вскрыть алгоритм данного шифрования. Думаю, что эти "лишние" байты совсем не лишние.
Vadim писал(а):Вопрос вдогонку: кто-нибудь занимался вытаскиванием OLE-объектов из БД? Вполне возможно, что рисунок там хранится в виде OLE-объекта.
Я делал загон в Access bmp картинок
Так вот OLE поле в картинке добавляет свои заголовки, и если обращаться к OLE полю как просто к набору байтов будет ошибка, нужно извечь из OLE само содержимое картинки, для этого надо знать как убрать заголовки
Как пример с bmp, обратите внимание на head
http://www.c-faq.narod.ru/faq/pic2bmp.html
Код: Выделить всё
procedure SavePictureToDB(p:TPicture);
var str,strb:TMemoryStream;
h:longint;
hb:array [1..4] of byte;
i:integer;
const
head1=#21#28#51#0#2#0#0#0#17#0#14#0#20#0#37#0;
head2='яяяяТочечный рисунок'#0'Paint.Picture';
head3=#0#1#5#0#0#2#0#0#0#7#0#0#0;
head4='PBrush'#0#0#0#0#0#0#0#0#0;
tail1=#0#0#0#0#0#0#0#0;
tail2=#0#0#1#5#0#0#0#0#0#0#0#173#5#254;
begin
str:=TMemoryStream.Create;
strb:=TMemoryStream.Create;
p.Bitmap.SaveToStream(strb);
str.Write(head1,16);
str.Write(head2,34);
str.Write(head3,13);
str.Write(head4,15);
h:=strb.Size+26;
for i:=1 to 4 do begin
hb[i]:=h mod 256;
h:=h div 256;
end;
str.Write(hb,4);
strb.Seek(0,soFromBeginning);
str.CopyFrom(strb,strb.Size);
str.Write(tail1,8);
str.Write(tail1,8);
str.Write(tail1,8);
str.Write(tail2,14);
strb.Seek(0,soFromBeginning);
ADOTablepicture.LoadFromStream(str);
strb.Free;
str.Free;
end;
То же самое с Gif и jpg , они пакуются в контейнер со спецзаголовками, чтоб программы на OLE понимали что в контейнере
Добавлено спустя 38 минут 38 секунд:
Посмотрел в HEX редакторе 3,out , не очень похоже на OLE, многие байты в теле изменены, судя по всему побиты окончания строк рисунка и это както связано с заголовком блоба
Вот здесь описание как выдрать файл из OLE http://blogs.msdn.com/b/pranab/archive/ ... bject.aspx
Добавлено спустя 16 минут 27 секунд:
Здесь экспорт из блоба на диск средствами самого MSSQL http://saveadba.blogspot.com/2012/02/ex ... abase.html
Без вашей помощи никак не обойтись. 
Вот что удалось выяснить после обсуждения здесь и дополнительных исследований:
- В поле для картинки хранится именно зашифрованный файл (не OLE
);
- Если удалить из файла 1.out (см. прилагаемый архив) 7 первых байт и 4 последних (начало должно быть GIF, конец - точка с запятой), то:
- В 93-ий байт нужно подставлять 1-ый байт из исходного (где первые 7 байт не удалены) файла 1.out;
- начиная с 193 байта нужно менять местами байты с этого места с байтом из 293 места. Т.е. получается файл разделён на блоки по 200 байт (от 0 до 199 включительно) и в этих блоках меняются местами нулевой и сотый байты;
- Выяснилось так же, что такие замены могут быть и не до конца файла, а только до какого-то определённого места.
Как тут уже высказывался Padre_Mortius, последний нюанс может быть скрыт в первых 7-ми байтах (точнее с 1 по 7-ой) или в последних четырёх. Но я сколько в них не пялился, так и не смог понять каким образом.
Может кто-нибудь, кто собаку съел на шифровках, сможет помочь?
http://files.kraslib.ru/pic/files.zip
Вот что удалось выяснить после обсуждения здесь и дополнительных исследований:
- В поле для картинки хранится именно зашифрованный файл (не OLE
- Если удалить из файла 1.out (см. прилагаемый архив) 7 первых байт и 4 последних (начало должно быть GIF, конец - точка с запятой), то:
- В 93-ий байт нужно подставлять 1-ый байт из исходного (где первые 7 байт не удалены) файла 1.out;
- начиная с 193 байта нужно менять местами байты с этого места с байтом из 293 места. Т.е. получается файл разделён на блоки по 200 байт (от 0 до 199 включительно) и в этих блоках меняются местами нулевой и сотый байты;
- Выяснилось так же, что такие замены могут быть и не до конца файла, а только до какого-то определённого места.
Как тут уже высказывался Padre_Mortius, последний нюанс может быть скрыт в первых 7-ми байтах (точнее с 1 по 7-ой) или в последних четырёх. Но я сколько в них не пялился, так и не смог понять каким образом.
Может кто-нибудь, кто собаку съел на шифровках, сможет помочь?
http://files.kraslib.ru/pic/files.zip
Сделай себе статистику по десятку картинок. Какой байт был, на что поменялся. И посмотри что получается.
