Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 03.01.2012, 20:36
Kaktuz Kaktuz вне форума
Начинающий
 
Регистрация: 30.10.2011
Сообщения: 149
Репутация: 10
По умолчанию Определение формата файла

Столкнулся с проблемой определения формата файла. Есть такой код:
Код:
if OpenPictureDialog1.Execute then
  begin
  Bmp := TBitmap.Create;
  Jpg := TJPEGImage.Create;
  Jpg.LoadFromFile(OpenPictureDialog1.FileName);
  Bmp.Assign(Jpg);
  Image1.Picture.Assign(Bmp);
  end;
Как видно мы выбираем файл *.jpg и преобразовываем его в *.bmp после чего уже работаем с ним. Все отлично работает. но вот получается что открывать мы может только *.jpg файлы. хотя можем работать и с *.bmp.
Так вот. Задача состоит в том что бы определить тип открываемого файла и в последствии уже если это *.jpg преобразовать его в *.bmp, а если это и есть *.bmp то оставить без изменений.
Использовать обычный метод определения - это когда по имени файла вырезается текст после точки и определяется тип, как бы так не особо актуален. точек может быть много, да и, а что если *.bmp изображение просто переименован формат на *.jpg. В программах он отображается, но вот в нашем случае тогда возникнет ошибка.
Как то так вообщем чуток запутанно для меня это получилось.
Ответить с цитированием
  #2  
Старый 03.01.2012, 20:54
Аватар для Amgsys HQ
Amgsys HQ Amgsys HQ вне форума
Начинающий
 
Регистрация: 11.11.2011
Адрес: Загрузочный сектор
Сообщения: 115
Версия Delphi: 7, XE
Репутация: 538
По умолчанию

Первые байты файла - индентификатор файла, его настоящее расширение. Считывай их и проверяй.
__________________
Работа пpогpаммиста и шамана имеет очень много общего:
оба боpмочyт непонятные слова, совеpшают непонятные действия и не могyт объяснить, как оно pаботает.
Ответить с цитированием
  #3  
Старый 03.01.2012, 21:02
Pyro Pyro вне форума
Так проходящий
 
Регистрация: 18.07.2011
Сообщения: 805
Версия Delphi: 7Lite
Репутация: 6063
По умолчанию

Цитата:
...обычный метод определения...
ExtractFileExt
Ответить с цитированием
  #4  
Старый 03.01.2012, 21:30
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Я проверяю так:
Код:
type
  TTypeFile		= (tfBMP, tfICON, tfCURSOR, tfWAVE, tfMIDI, 
			   tfHUC, tfJPG,  tfGIF,    tfTIF,  tfMO3, 
			   tfPNG, tfPCX,  tfUnknown);
const
  THeaderFile		: array[0..11, 0..6] of Byte = (
  {BMP}			($42, $4D,   0,   0,   0,   0, 2),
  {ICON}  		(  0,   0,   1,   0,   0,   0, 4),
  {CURSOR}		(  0,   0,   2,   0,   0,   0, 4),
  {WAVE}		($52, $49, $46, $46,   0,   0, 4),
  {MIDI}		($4D, $54, $68, $64,   0,   0, 4),
  {HUC}			($48, $55, $43,   0,   0,   0, 3),
  {JPG}			($FF, $D8, $FF,   0,   0,   0, 3),
  {GIF}			($47, $49, $46, $38,   0,   0, 4),
  {TIF}			($49, $49, $2A, $00,   0,   0, 4),
  {MO3}			($4D, $4F, $33, $04,   0,   0, 4),
  {PNG}			($89, $50, $4E, $47, $0D, $0A, 6),
  {PCX}			($0A, $05,   0,   0,   0,   0, 2));

function CheckTypeFile(P : Pointer) : TTypeFile;
var
  I	: Integer;
begin
  Result := tfUnknown;
  for I := Low(THeaderFile) to High(THeaderFile) do
    if CompareMem(P, @THeaderFile[i], THeaderFile[i][High(THeaderFile[0])]) then
    begin
      Result := TTypeFile(I);
      Break;
    end;
end;
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #5  
Старый 03.01.2012, 22:33
Kaktuz Kaktuz вне форума
Начинающий
 
Регистрация: 30.10.2011
Сообщения: 149
Репутация: 10
По умолчанию

Побайтно... Первые символы... Вроде понятно. Но! Это получается идут HEX данные, с которыми я так толком и не разобрался
Ответить с цитированием
  #6  
Старый 03.01.2012, 22:39
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Чего с ними разбираться? 255=$FF и так далее. Обычный калькулятор меняет представление с HEX на DEC и обратно по клавишам F5, F6.
Читаешь файл или часть файла в MemoryStream и отадаёшь в функцию:
Код:
var
  TF : TTypeFile;
begin
...
  // что в потоке
  TF := CheckTypeFile(MemStream.Memory);
...
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #7  
Старый 03.01.2012, 23:00
Kaktuz Kaktuz вне форума
Начинающий
 
Регистрация: 30.10.2011
Сообщения: 149
Репутация: 10
По умолчанию

Цитата:
Сообщение от angvelem
Чего с ними разбираться? 255=$FF и так далее. Обычный калькулятор меняет представление с HEX на DEC и обратно по клавишам F5, F6.
Читаешь файл или часть файла в MemoryStream и отадаёшь в функцию:
Код:
var
  TF : TTypeFile;
begin
...
  // что в потоке
  TF := CheckTypeFile(MemStream.Memory);
...
Для того кто понял суть как это работает все просто, но мне пока месть еще не совсем понятно. Уже пытались объяснить, но опять таки все одни догадки...
Ответить с цитированием
  #8  
Старый 03.01.2012, 23:05
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Мой экстрасенсорный дар подсказывает мне, что у мсье сложности с 16-ричной системой счисления?
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #9  
Старый 03.01.2012, 23:12
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Собственно, для начала, хватит и тех форматов, что у меня описаны. Лишние не сложно выбросить (HUC нигде и никогда не встретишь).
К примеру:
Код:
  {BMP}			($42, $4D,   0,   0,   0,   0, 2),
последний число (2) показывает, сколько чисел нужно сравнить. Для BMP, как раз достаточно 2.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.

Последний раз редактировалось angvelem, 03.01.2012 в 23:16.
Ответить с цитированием
  #10  
Старый 03.01.2012, 23:44
Kaktuz Kaktuz вне форума
Начинающий
 
Регистрация: 30.10.2011
Сообщения: 149
Репутация: 10
По умолчанию

Вообщем у меня так получилось. не знаю на сколько это правильно. Хотя для проверки этого будет достаточно, но вот для преобразования всего файла в HEX данные нет.
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  Typ: TStringList;
  a,b: string;
begin
If OpenDialog1.Execute then
  begin
  Typ := TStringList.Create;
  Typ.LoadFromFile(OpenDialog1.FileName);
  a:=Typ.Text;
  b :=
  IntToHex(Ord(a[1]), 2)+
  IntToHex(Ord(a[2]), 2)+
  IntToHex(Ord(a[3]), 2);
  // --- ///
  if b = '89504E' then ShowMessage('PNG');
  if b = 'FFD8FF' then ShowMessage('JPG');
  if b = '424DFA' then ShowMessage('BMP');
  end;
end;
Ответить с цитированием
  #11  
Старый 03.01.2012, 23:48
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Понял твою проблему. Понятие DEC, HEC это для человека. Комп работает в бинарной системе. Ничего не нужно конвертить, считываешь в поток и отдаёшь функции. А уж ответ проверяешь через case.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #12  
Старый 04.01.2012, 01:07
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,088
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от Kaktuz
Вообщем у меня так получилось. не знаю на сколько это правильно. Хотя для проверки этого будет достаточно, но вот для преобразования всего файла в HEX данные нет.
<skip>

Маньяк.

Код:
var
  Stream : TFileStream;
  Buf : Pointer;
begin
  GetMEm(Buf,5);
  Stream := TFileStream.Create(AFileName,fmOpenRead);
  Try
    Stream.ReadBuffer(Buf^,5);
    case CheckTypeFile(Buf) of // Функуию тебе дали...
       // Здесь работаешь уже с опр. типом
      tfBMP : Begin ... End;
      Else Raise Exception.Create('Unknown format');
    end;
  Finally
    Stream.Free;
    FreeMem(Buf,5);
  End;
end;
Ответить с цитированием
  #13  
Старый 04.01.2012, 01:16
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Только маленькая поправка, запросить нужно 7 байт. 6 на определение формата и дополнительный - на длину проверки. Хотя... как определение типа переписать.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #14  
Старый 04.01.2012, 03:23
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,088
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Не, запрашивать надо 6 (моя ошибка, невнимательно посмотрел), а функцию тоже надо поправить, что бы она проверяла кол-во байт, которое указано в последнем элементе массива. Или массив по другому организовать, например как-то так:
Код:
type
  TFormatSample = record
     CheckLength : Integer;
     Sample : Array [0..5] Of Byte;
  end;

const
  THeaderFile	: array[0..11] of TFormatSample = (
  {BMP}	        CheckLength: 2; Sample: ($42, $4D,   0,   0,   0,   0),
                        ...);

Ну и функцию соотв. образом поправить.
Ответить с цитированием
  #15  
Старый 04.01.2012, 04:00
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Если таким способом, то да 6 байт, но я особенно не заморачивался с созданием структуры, хотя так удобнее, а "танцевал" от формата PNG, у него самая длинная "шапка" для определения и добавил 7-ой байт с длиной проверки. И функция не проверяет длину, а просто подставляет в CompareMem последний байт из массива.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.

Последний раз редактировалось angvelem, 04.01.2012 в 04:04.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


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


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025