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

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 EXIF for MOV files

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

View 
UserName:
Password:
Format  Bold Italicized Underline  Align Left Centered Align Right  Horizontal Rule  Insert Hyperlink   Browse for an image to attach to your post Browse for a zip to attach to your post Insert Code  Insert Quote Insert List
   
Message 

 

Emoji
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Black Eye [B)]
Frown [:(] Shocked [:0] Angry [:(!] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
Murat Posted - Jan 15 2013 : 10:49:12
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...
6   L A T E S T    R E P L I E S    (Newest First)
fab Posted - Oct 17 2013 : 01:50:10
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.
Murat Posted - Oct 10 2013 : 10:06:49
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.
fab Posted - Jan 31 2013 : 15:44:11
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;
fab Posted - Jan 22 2013 : 10:51:13
The old email still works.
Murat Posted - Jan 22 2013 : 05:57:40
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?
fab Posted - Jan 18 2013 : 02:42:25
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;