画像ファイルを自動判別して正しい拡張子を取得する
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()関数を呼び出すだけです。引数や戻り値などはソース下部に記述しています。
スポンサーリンク
関連記事
前の記事: | MIDIファイルを作成する(Delphi) |
次の記事: | EXE/DLLファイルを分析・解析する |
公開日:2015年02月27日
記事NO:00308