Forum > Other
Identify image Types
(1/1)
DreamVB:
Hi,
this is a little console app with a function that can be used to check the first few bytes of a file to test if it is an image type, When I was doing work experience in a school I remember the IT person what have to check the students folders for images and delete them, something like this might of been handy as some students like to try and make it harder to find the and rename them as MP3 or DOC files or other file types anyway hope you find the code useful if you can think of other formats you can easy add them.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---//Little function that can be used to check the type of image. program identimage; {$mode objfpc}{$H+} uses Classes, StrUtils, SysUtils; type TImageType = (IUnknown, iPNG, iBMP, iJPEG, iGIF, iTIFF, iPSD, iPCX); function GetImageType(Filename: string): TImageType; var f: file of byte; header: array[0..6] of byte; iType: TImageType; X : Integer; begin //File to read AssignFile(f, Filename); Reset(f); //Read in the first 5 bytes of the file into header array for X := 0 to 5 do begin Read(f, header[X]); end; //Close file CloseFile(f); //Check for PNG if (header[0] = $89) and (header[1] = $50) and (header[2] = $4E) and (header[3] = $47) then begin iType := TImageType.iPNG; end //Check for JPEG else if (header[0] = $FF) and (header[1] = $D8) and (header[2] = $FF) and (header[3] = $E0) then begin iType := TImageType.iJPEG; end //Check for Bitmap else if (header[0] = $42) and (header[1] = $4D) and (header[2] = $5E) and (header[3] = $23) then begin iType := TImageType.iBMP; end //Check for Bitmap else if (header[0] = $42) and (header[1] = $4D) and (header[2] = $52) then begin iType := TImageType.iBMP; end //Check for Bitmap else if (header[0] = $42) and (header[1] = $4D) and (header[2] = $EE) and (header[3] = $0F) then begin iType := TImageType.iBMP; end //Check for GIF else if (header[0] = $47) and (header[1] = $49) and (header[2] = $46) and (header[3] = $38) and (header[4] = $39) then begin iType := TImageType.iGIF; end //Check for TIFF else if (header[0] = $49) and (header[1] = $49) and (header[2] = $2A) and (header[3] = $00) then begin iType := TImageType.iTIFF; end //Check for Adobe PSD else if (header[0] = $38) and (header[1] = $42) and (header[2] = $50) and (header[3] = $53) and (header[4] = $00) and (header[5] = $01) then begin iType := TImageType.iPSD; end //Check for PCX else if (header[0] = $0A) and (header[1] = $05) and (header[2] = $01) and (header[3] = $08) and (header[4] = $00) then begin iType := TImageType.iPCX; end else begin //Unknown Image type iType := TImageType.IUnknown; end; Result := iType; //Check header to find out what image type we have. end; begin if ParamCount = 1 then begin if not FileExists(ParamStr(1)) then begin WriteLn('File Not Found: ' + sLineBreak + ParamStr(1)); end else begin Writeln(GetImageType(ParamStr(1))); end; end;end.
Bart:
I have a similar unit, that does some more extensive checking (and also returns width and height) of the image.
It supports less formats though.
Feel free to use (parts of) this code.
Bart
DreamVB:
Thanks Bart I look at your code latter.
wp:
Seems to be a popular topic because I have a similar unit for fpspreadsheet (https://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/components/fpspreadsheet/source/common/fpsimages.pas). Only later I noticed that the format checks are already available in each fpc installation: The folder packages/fcl-image/src contains the units needed by the fcl graphics routines, including the reader and writer units for all graphics format. Each file format has dedicated reader and writer units with corresponding classes. It is an elemental requirement for each reader that it must be able to detect the graphics format from the file (or stream) header, without relying on a file extension. The reader method for this purpose is called "CheckContents", works on the image stream and returns true if the typical signature of the file format is found. When the reader unit of a file format is added to the uses clause of your application the unit is registered in an internal image handler list along with related data, among them the name of the graphic format. TFPCustomImage, the elemental image class of fcl-image, has a method FindHandlerFromStream which scans over all registered image handlers and calls the CheckContents method of each reader class. This way TFPCustomImage can determine the graphics format from the stream header.
Luckily all this is accessible to us, and knowing this (after some study in the fcl-image source) your program shrinks to a few lines. All you have to do is to add the reader units of all formats that you want to check to the uses clause:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---uses ... fpImage, // what follows are the reader units available in fcl-image fpReadBMP, fpReadGIF, fpReadPNG, fpReadPSD, fpReadJPEG, fpReadTIFF, fpReadPCX, fpReadPNM, fpReadTGA, fpReadXPM, fpReadXWD; function GetImageType(AStream: TStream): String;var handlerData: TIHData;begin handlerData := TFPCustomImage.FindHandlerFromStream(AStream); if handlerData = nil then Result := 'Format not detected' else Result := handlerData.TypeName;end; procedure TForm1.Button1Click(Sender: TObject);var stream: TFileStream;begin stream := TFileStream.Create(FILE_NAME, fmOpenRead); try ShowMessage(GetImageType(stream)); finally stream.Free; end;end;
Of course, this cannot replace the detection of audo or video files - for these, your code is still required.
Navigation
[0] Message Index