TOP > カテゴリ > フォーマット変換 >

画像ファイルを自動判別して正しい拡張子を取得する

GIF/PNG/JPEGなどの36種類の画像ファイルの拡張子を自動判別する事が出来るサンプルコードです。2000年頃に作成したものですが何かの役に立つかもしれませんので公開しておきます。

対応している画像ファイル

ANI,BMP/RLE/DIB,CAM,CEL,CUR,DPX,EMF,GIF,ICO,IFF/LBM,IMG,JPG,MAG,MIF,MNG/JNG,MSP,PAC,PBM,PCX/DCX,PGM,PI,PIC,PICT/PCT,PNG,PPM,PSD,PSP,RAS/SUN,SCT/CT,SGI,SHG,TGA,TIF/TIFF,TIM,WMF,WPG

拡張子の自動判別

[Extensions.pas]

// 拡張子自動判別ユニット
//

unit Extensions;

interface
uses
  Windows, Messages,SysUtils, Classes, Graphics;

// 画像ファイルを自動判別して正しい拡張子を取得する
function Distinction_Extension(FileName :String; var Ext : String) :Boolean;

implementation

// BMP
function IsBMP(Memory : Pchar):Boolean;
begin
     if ((Memory[0]='B') and (Memory[1]='M')) then
        Result :=True
     else
        Result :=False;
end;

// JPG
function IsJPG(Memory : PBYteArray):Boolean;
begin
     //SOI  Start of Image
     if ((Memory[0]=$FF) and (Memory[1]=$D8) ) then
        Result :=True
     else
        Result :=False;
end;

// PNG
function IsPNG(Memory : PByteArray):Boolean;
begin
     if ((Memory[0]=$89) and (Memory[1]=$50) and (Memory[2]=$4E) and (Memory[3]=$47)) then
        Result :=True
     else
        Result :=False;
end;

// ANI
function IsANI(Memory : Pchar):Boolean;
begin
     if (Memory[0]='R') and (Memory[1]='I')  and (Memory[2]='F') and (Memory[3]='F') and
        (Memory[8]='A') and (Memory[9]='C')  and (Memory[10]='O')and (Memory[11]='N')  then
        Result :=True
     else
        Result :=False;
end;

// CAM
function IsCAM(Memory : PByteArray):Boolean;
begin
     if ((Memory[0]=$07) and (Memory[1]=$20) and (Memory[2]=$4D) and (Memory[3]=$4D) ) then
        Result :=True
     else
        Result :=False;
end;

// CUR
function IsCUR(Memory : PByteArray):Boolean;
begin
     if ((Memory[0]=$00) and (Memory[1]=$00) and (Memory[2]=$02) and (Memory[3]=$00)) then
        Result :=True
     else
        Result :=False;
end;

// ICO
function IsICO(Memory : PByteArray):Boolean;
begin
     if ((Memory[0]=$00) and (Memory[1]=$00) and (Memory[2]=$01) and (Memory[3]=$00)) then
        Result :=True
     else
        Result :=False;
end;

// DPX
function IsDPX(Memory : Pchar):Boolean;
begin
     if ((Memory[0]='D') and (Memory[1]='P') and (Memory[2]='X') ) then
        Result :=True
     else
        Result :=False;
end;

// GIF
function IsGIF(Memory : Pchar):Boolean;
begin
     if ((Memory[0]='G') and (Memory[1]='I') and (Memory[2]='F') ) then
        Result :=True
     else
        Result :=False;
end;

// IFF/LBM
function IsLBM(Memory : Pchar):Boolean;
begin
     if (Memory[0]='F') and (Memory[1]='O')  and (Memory[2]='R') and (Memory[3]='M') and
        (Memory[8]='I') and (Memory[9]='L')  and (Memory[10]='B')and (Memory[11]='M')  then
        Result :=True
     else
        Result :=False;
end;

// IMG
function IsIMG(Memory : PByteArray):Boolean;
begin
     if ((Memory[0]=$00) and (Memory[1]=$01) and (Memory[2]=$00) and (Memory[3]=$08)) then
        Result :=True
     else
        Result :=False;
end;

// MAG
function IsMAG(Memory : Pchar):Boolean;
begin
     if (Memory[0]='M') and (Memory[1]='A')  and (Memory[2]='K') and (Memory[3]='I') and
        (Memory[4]='0') and (Memory[5]='2')   then
        Result :=True
     else
        Result :=False;
end;

// MIF
function IsMIF(Memory : Pchar):Boolean;
begin
     if (Memory[0]='M') and (Memory[1]='I')  and (Memory[2]='M') and (Memory[3]='G') then
        Result :=True
     else
        Result :=False;
end;

// MNG
function IsMNG(Memory : PByteArray):Boolean;
begin
     if ((Memory[0]=$8A) and (Memory[1]=$4D) and (Memory[2]=$4E) and (Memory[3]=$47)) then
        Result :=True
     else
        Result :=False;
end;

// MSP
function IsMSP(Memory : Pchar):Boolean;
begin
     if ((Memory[0]='L') and (Memory[1]='i') and (Memory[2]='n') and (Memory[3]='S'))or
        ((Memory[0]='D') and (Memory[1]='a') and (Memory[2]='n') and (Memory[3]='M'))  then
        Result :=True
     else
        Result :=False;
end;

// PAC
function IsPAC(Memory : Pchar):Boolean;
begin
     if ((Memory[4]='P') and (Memory[5]='G') and (Memory[6]='A') and (Memory[7]='C'))then
        Result :=True
     else
        Result :=False;
end;

// PBM
function IsPBM(Memory : Pchar):Boolean;
begin
     if ((Memory[0]='P') and (Memory[1]='1')) or ((Memory[0]='P') and (Memory[1]='4')) then
        Result :=True
     else
        Result :=False;
end;

// PGM
function IsPGM(Memory : Pchar):Boolean;
begin
     if ((Memory[0]='P') and (Memory[1]='2') and (Memory[2]<>'D')) or ((Memory[0]='P') and (Memory[1]='5')) then
        Result :=True
     else
        Result :=False;
end;

// PPM
function IsPPM(Memory : Pchar):Boolean;
begin
     if ((Memory[0]='P') and (Memory[1]='3')) or ((Memory[0]='P') and (Memory[1]='6')) then
        Result :=True
     else
        Result :=False;
end;

// PCX
function IsPCX(Memory : PBYteArray):Boolean;
begin
     if ((Memory[0]=$0A) and (Memory[1] in [0..5]) and  (Memory[2] in [0,1])) then
        Result :=True
     else
        Result :=False;
end;

// pi
function IsPI(Memory : Pchar):Boolean;
begin
     if ((Memory[0]='P') and (Memory[1] ='i' ) ) then
        Result :=True
     else
        Result :=False;
end;

// psd
function IsPSD(Memory : Pchar):Boolean;
begin
     if ((Memory[0]='8') and (Memory[1] ='B' ) and (Memory[2] ='P' ) and (Memory[3] ='S' )) then
        Result :=True
     else
        Result :=False;
end;

// PSP
function IsPSP(Memory : Pchar):Boolean;
begin
     if ((Memory[0]='P') and (Memory[1] ='a' ) and (Memory[2] ='i' ) and (Memory[3] ='n' ) and (Memory[4] ='t' )) then
        Result :=True
     else
        Result :=False;
end;

// RAS
function IsRAS(Memory : PBYteArray):Boolean;
begin
     if ((Memory[0]=$59) and (Memory[1] =$A6 ) and (Memory[2] =$6A ) and (Memory[3] =$95 ) ) then
        Result :=True
     else
        Result :=False;
end;

// SHG
function IsSHG(Memory : Pchar):Boolean;
begin
     if ((Memory[0]='l') and (Memory[1]='p')) or ((Memory[0]='L')  and (Memory[1]='P') ) then
        Result :=True
     else
        Result :=False;
end;

// TGA
function IsTGA(Memory : PBYteArray):Boolean;
begin
     if ((Memory[1] in [0,1]) and (Memory[2] in [0,1,2,3,9,10,11]) and (Memory[16] in [8,15,16,24,32]) ) then
        Result :=True
     else
        Result :=False;
end;

// TIF
function IsTIF(Memory : Pchar):Boolean;
begin
     if ((Memory[0]='I') and (Memory[1]='I')) or ((Memory[0]='M')  and (Memory[1]='M') ) then
        Result :=True
     else
        Result :=False;
end;
     
// TIM
function IsTIM(Memory : PBYteArray):Boolean;
begin
     if ((Memory[0]=$10) and (Memory[1]=0) and (Memory[2]=0)  and (Memory[3]=0)  and (Memory[4] in [ 0,1,2,3,8,9,10,11])) then
        Result :=True
     else
        Result :=False;
end;

// WPG
function IsWPG(Memory : PBYteArray):Boolean;
begin
     if ((Memory[0]=$FF) and (Memory[1]=$57) and (Memory[2]=$50)  and (Memory[3]=$43) ) then
        Result :=True
     else
        Result :=False;
end;

// WMF
function IsWMF(Memory : PBYteArray):Boolean;
begin
     if ((Memory[0]=$D7) and (Memory[1]=$CD) and (Memory[2]=$C6)  and (Memory[3]=$9A) ) then
        Result :=True
     else
        Result :=False;
end;

// SGI
function IsSGI(Memory : PBYteArray):Boolean;
begin
     if ((Memory[0]=$01) and (Memory[1]=$DA)  ) then
        Result :=True
     else
        Result :=False;
end;

// CEL
function IsCEL(Memory : PBYteArray):Boolean;
begin
     if ((Memory[0]=$19) and (Memory[1]=$91)  ) then
        Result :=True
     else
        Result :=False;
end;

// PIC
function IsPIC(Memory : PBYteArray):Boolean;
begin
     if ((Memory[0]=$34) and (Memory[1]=$12)  ) then
        Result :=True
     else
        Result :=False;
end;


// EMF
function IsEMF(FileName : String):Boolean;
var
  Stream : TStream;
  Buffer : array [0..3] of Char;
begin
  Try
     // サイズが少なすぎたら強制的にFalse
     Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
     Try
        Stream.Position:= 40;
        Stream.ReadBuffer(Buffer,4) ;

        if  Buffer=' EMF' then
          Result :=True
        else
          Result :=False;

     finally
        Stream.Free;
     end;
  Except
      Result :=False;
  end;
end;

// SCT
function IsSCT(FileName : String):Boolean;
var
  Stream : TStream;
  Buffer : array [0..1] of Char;
begin
  Try
      // サイズが少なすぎたら強制的にFalse
     Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
     Try
        Stream.Position:= 80;
        Stream.ReadBuffer(Buffer,2) ;

        if  Buffer='CT' then
          Result :=True
        else
          Result :=False;

     finally
        Stream.Free;
     end;
  Except
      Result :=False;
  end;
end;

// PICT
function IsPICT(FileName : String):Boolean;
var
  Stream : TStream;
  OpCode : array [0..3] of BYte;
begin
  Try
    // サイズが少なすぎたら強制的にFalse
    Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
    Try
       Stream.Position:= 512;
       Stream.Position:= Stream.Position+10;
       Stream.ReadBuffer(OpCode,4) ;

       if ( (OpCode[0]=0) and (OpCode[1]=$11) and (OpCode[2]=2) and (OpCode[3]=$FF))then
         Result :=True
       else
         Result :=False;

    finally
       Stream.Free;
    end;
  Except
      Result :=False;
  end;
end;

//------------------------------------------------------------------------------
//
//   画像ファイルを自動判別して正しい拡張子を取得する
//   FileName  自動判別を行うファイル名
//   Ext       正しい拡張子を返す。
//   戻り値
//              True 拡張子は正しい False 拡張子が間違っている
//------------------------------------------------------------------------------
function Distinction_Extension(FileName :String; var Ext : String) :Boolean;
var
  Stream : TStream;
  Buffer : POinter;
  Extention    : String;
begin

  Ext :=''; 
  // 最初の17byteを取得  16でなく17なのはTGAのため
  Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  GetMem(Buffer,17) ;
  try
    Stream.ReadBuffer(Buffer^,17) ;
    Extention:= ExtractFileExt(FileName) ;
  Except
    // ファイルが読み込めない場合は終了
    Stream.Free;
    Result :=True;
    if Buffer<>nil then FreeMem(Buffer);
    Exit;
  End;
  Stream.Free;

  // 一つの形式で複数の拡張子がある場合は比較する拡張子を変更
  if AnsiCompareText(Extention,'.jpeg')=0 then Extention :='.jpg';
  if AnsiCompareText(Extention,'.rle')=0  then Extention :='.bmp';
  if AnsiCompareText(Extention,'.dib')=0  then Extention :='.bmp';
  if AnsiCompareText(Extention,'.iff')=0  then Extention :='.lbm';
  if AnsiCompareText(Extention,'.jng')=0  then Extention :='.mng';
  if AnsiCompareText(Extention,'.dcx')=0  then Extention :='.pcx';
  if AnsiCompareText(Extention,'.sun')=0  then Extention :='.ras';
  if AnsiCompareText(Extention,'.tiff')=0 then Extention :='.tif';
  if AnsiCompareText(Extention,'.ct')=0   then Extention :='.sct';
  if AnsiCompareText(Extention,'.pct')=0  then Extention :='.pict';

  // ファイル探索
  While True do
  begin
       if  IsBMP(Buffer)  then begin   Ext :='.bmp' ;  Break;   end;
       if  IsJPG(Buffer)  then begin   Ext :='.jpg' ;  Break;   end;
       if  IsPNG(Buffer)  then begin   Ext :='.png' ;  Break;   end;
       if  IsANI(Buffer)  then begin   Ext :='.ani' ;  Break;   end;
       if  IsCAM(Buffer)  then begin   Ext :='.cam' ;  Break;   end;
       if  IsICO(Buffer)  then begin   Ext :='.ico' ;  Break;   end;
       if  IsDPX(Buffer)  then begin   Ext :='.dpx' ;  Break;   end;
       if  IsGIF(Buffer)  then begin   Ext :='.gif' ;  Break;   end;
       if  IsLBM(Buffer)  then begin   Ext :='.lbm' ;  Break;   end;
       if  IsIMG(Buffer)  then begin   Ext :='.img' ;  Break;   end;
       if  IsMAG(Buffer)  then begin   Ext :='.mag' ;  Break;   end;
       if  IsMIF(Buffer)  then begin   Ext :='.mif' ;  Break;   end;
       if  IsMNG(Buffer)  then begin   Ext :='.mng' ;  Break;   end;
       if  IsMSP(Buffer)  then begin   Ext :='.msp' ;  Break;   end;
       if  IsPAC(Buffer)  then begin   Ext :='.pac' ;  Break;   end;
       if  IsPBM(Buffer)  then begin   Ext :='.pbm' ;  Break;   end;
       if  IsPGM(Buffer)  then begin   Ext :='.pgm' ;  Break;   end;
       if  IsPPM(Buffer)  then begin   Ext :='.ppm' ;  Break;   end;
       if  IsPCX(Buffer)  then begin   Ext :='.pcx' ;  Break;   end;
       if  IsPI(Buffer)   then begin   Ext :='.pi'  ;  Break;   end;
       if  IsPSD(Buffer)  then begin   Ext :='.psd' ;  Break;   end;
       if  IsPSP(Buffer)  then begin   Ext :='.psp' ;  Break;   end;
       if  IsRAS(Buffer)  then begin   Ext :='.ras' ;  Break;   end;
       if  IsSHG(Buffer)  then begin   Ext :='.shg' ;  Break;   end;
       if  IsTIM(Buffer)  then begin   Ext :='.tim' ;  Break;   end;
       if  IsTGA(Buffer)  then begin   Ext :='.tga' ;  Break;   end;
       if  IsTIF(Buffer)  then begin   Ext :='.tif' ;  Break;   end;
       if  IsWPG(Buffer)  then begin   Ext :='.wpg' ;  Break;   end;
       if  IsSGI(Buffer)  then begin   Ext :='.sgi' ;  Break;   end;
       if  IsWMF(Buffer)  then begin   Ext :='.wmf' ;  Break;   end;
       if  IsCEL(Buffer)  then begin   Ext :='.cel' ;  Break;   end;
       if  IsPIC(Buffer)  then begin   Ext :='.pic' ;  Break;   end;
       if  IsCUR(Buffer)  then begin   Ext :='.cur' ;  Break;   end;

       // 以下、情報の取得に難がある。
       if  IsPICT(FileName)  then begin   Ext :='.pict' ;  Break;   end;
       if  IsEMF(FileName)   then begin   Ext :='.emf' ;  Break;   end;
       if  IsSCT(FileName)   then begin   Ext :='.sct' ;  Break;   end;

       //メタファイル

       // ここまできたら、そのファイルは自動判別出来るファイルではない。
       FreeMem(Buffer);
       Result :=True;
       Exit;
  end;

  FreeMem(Buffer);

  // 拡張子の比較
  if AnsiCompareText(Extention,Ext)=0 then
   Result :=True
  else
   Result :=False;

end;

end.

使い方はDistinction_Extension()関数を呼び出すだけです。引数や戻り値などはソース下部に記述しています。





関連記事



公開日:2015年02月27日
記事NO:00308