ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
Forum membership is Free!  Click Join to sign-up
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 EXIF for MOV files
 New Topic  Reply to Topic
Author Previous Topic Topic Next Topic  

Murat

Russia
48 Posts

Posted - Jan 15 2013 :  10:49:12  Show Profile  Reply
As you know, many digital cameras record videos in MOV format.

And this format allows storing camera info in the EXIF format. I guess it will be perfect to add support for reading EXIF from MOV files into the future ImageEN versions...

fab

1310 Posts

Posted - Jan 18 2013 :  02:42:25  Show Profile  Reply
It could be supported in a future release.
I don't have a MOV with EXIF, anyway if you only need to extract EXIF you could try this way (NOT TESTED!):
- locate EXIF position using IESearchEXIFInfo
- load EXIF using IELoadEXIFFromTIFF

Example:

var
  stream: TFileStream;
  p: int64;
  params: TIOParams;
begin
  params := TIOParams.Create(nil);
  stream := TFileStream.Create('test.mov', fmOpenRead);
  try
    p := IESearchEXIFInfo(stream);
    stream.Position := p;
    if (p >= 0) and IELoadEXIFFromTIFF(stream, params) then
    begin
      ShowMessage(params.EXIF_ImageDescription);
    end;
  finally
    params.Free();
    stream.Free();
  end;
end;
Go to Top of Page

Murat

Russia
48 Posts

Posted - Jan 22 2013 :  05:57:40  Show Profile  Reply
OK. Thanks! I'll test it.

I've sent an email with sample MOV file to Nigel's email. Don't know whether your old email from hicomponents is workable?
Go to Top of Page

fab

1310 Posts

Posted - Jan 22 2013 :  10:51:13  Show Profile  Reply
The old email still works.
Go to Top of Page

fab

1310 Posts

Posted - Jan 31 2013 :  15:44:11  Show Profile  Reply
Next version will contain a new function (not method) named IEReadEXIFFromMOV.
It can extract EXIF from MOV created with FujiFilm cameras (the unique I found acceptable documentation) like the one you have sent me.

Here is source code of IEReadEXIFFromMOV:

function IEReadEXIFFromMOV(Stream: TStream; OutParams: TObject): boolean;
var
  ms: TMemoryStream;
  tp: dword;
  sz: int64;
  nm: integer;
  nullpr: TProgressRec;
  abort: boolean;
  tempAlphaChannel: TIEMask;
  TIFFHeader: TTIFFHeader;
  ioparams: TIOParams;
  function GetDWord():dword;
  begin
    Stream.Read(result, sizeof(dword));
    result := IESwapDWord(result);
  end;
  function DWordToStr(dw:dword):string;
  var
    i: integer;
  begin
    result := '';
    for i := 3 downto 0 do
      result := result + chr(dw shr (i * 8) and $FF);
  end;
  function FindTag(tag:string):boolean;
  begin
    result := false;
    while Stream.Position < Stream.Size do
    begin
      sz := GetDWord(); // get atom size
      tp := GetDWord(); // get atom type
      if sz = 0 then
        sz := Stream.Size - Stream.Position
      else if sz = 1 then
      begin
        // 64 bit size
        sz := GetDWord();
        sz := sz or (GetDWord() shl 32);
      end;
      if DWordToStr(tp) = tag then
      begin
        result := true;
        break;
      end;
      Stream.Seek(sz - 8, soCurrent);
    end;
  end;
begin
  result := false;
  if FindTag('moov') and FindTag('udta') and FindTag('MVTG') then
  begin
    ms := TMemoryStream.Create();
    try
      Stream.Seek(16, soCurrent);
      ms.CopyFrom(Stream, sz - 8);
      abort := false;
      with nullpr do
      begin
        Aborting := @abort;
        fOnProgress := nil;
        Sender := nil;
      end;
      tempAlphaChannel := nil;
      TIFFHeader.Id := $4949;
      TIFFHeader.Ver := 42;
      TIFFHeader.PosIFD := 0;
      ms.Position := 0;
      ioparams := OutParams as TIOParams;
      TIFFReadStream(nil, ms, nm, ioparams, nullpr, true, tempAlphaChannel, true, true, false, true, @TIFFHeader);
      result := true;
    finally
      ms.Free();
    end;
  end;
end;


However you have to modify also TIFFReadStream (in tiffilt.pas) to accept an extra optional parameter.
TIFFReadStream must be defined as:
procedure TIFFReadStream(Bitmap:TIEBitmap; Stream:TStream; var numi:integer; IOParams:TIOParams; var Progress:TProgressRec; Preview:boolean; var AlphaChannel:TIEMask; TranslateBase:boolean; IgnoreAlpha:boolean; IsExifThumb:boolean; IsEXIFData:boolean; ProvidedHeader: PTIFFHeader = nil);


Modify...

    Stream.read(TIFFHeader, sizeof(TTIFFHeader));

...to...

    if ProvidedHeader <> nil then
      TIFFHeader := ProvidedHeader^
    else
      Stream.read(TIFFHeader, sizeof(TTIFFHeader));


And finally...

    if PosIFD = 0 then
      exit;
...to...

    if (PosIFD = 0) and (ProvidedHeader = nil) then
      exit;



Usage example:

var
  fs: TFileStream;
begin
  fs := TFileStream.Create('c:\tempworks\DSCF1261.MOV', fmOpenRead);
  try
    IEReadEXIFFromMOV(fs, ImageEnView1.IO.Params);
    memo1.lines.add('EXIF_Make = '+ImageEnView1.io.params.EXIF_Make);
    memo1.lines.add('EXIF_Model = '+ImageEnView1.IO.Params.EXIF_Model);
    memo1.lines.add('EXIF_DateTime = '+ImageEnView1.IO.Params.EXIF_DateTime);
  finally
    fs.Free();
  end;
end;
Go to Top of Page

Murat

Russia
48 Posts

Posted - Oct 10 2013 :  10:06:49  Show Profile  Reply
Hi Fabrizio,

I've emailed you another MOV file taken by NIKON COOLPIX AW100 with existed
EXIF block.

Unfortunately IEReadEXIFFromMOV is unable to locate the exif block for
this file. Could you please check it.
Go to Top of Page

fab

1310 Posts

Posted - Oct 17 2013 :  01:50:10  Show Profile  Reply
It seems that Nikon MOV doesn't contain EXIF, but custom Nikon tags. Please look at:

http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/QuickTime.html

The NCDT tag doesn't actually contain an EXIF block.
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
Jump To: