昨天晚上研究了一下,得到快门数据:
文件第0x23E,0x23F,0x240,0x241为快门速度分子
文件第0x242,0x243,0x244,0x245为快门速度分母
例如:
文件第0x23E,0x23F,0x240,0x241为0A 00 00 00,那么就是0000000A,即分母为10
文件第0x242,0x243,0x244,0x245为2C 01 00 00,那么就是0000012C,即分子为300
因此快门速度为:10/300,即1/30秒
若
文件第0x23E,0x23F,0x240,0x241为2C 01 00 00,那么就是0000012C,即分母为300
文件第0x242,0x243,0x244,0x245为0A 00 00 00,那么就是00000000A,即分子为10
因此快门速度为:300/10,即30秒
unit SonyInterface;
interface
uses
Windows, Jpeg, Classes, SysUtils;
{ PreView Size : 120 * 160 }
type
TSonyDSCHeader = packed record
Format_Desc: array[0..5] of char; { Image Format : Exif , for F717 }
Format_Version: array[0..3] of char; { Image Format Version : 2.2, for F717 }
Unknown1: array[0..$A1] of char;
Sony_Flag1: array[0..5] of char; { Flag : Sony }
Device_Flag: array[0..9] of char; { Device : CyberShot }
Unknown2: array[0..29] of char;
DateTime1: array[0..19] of char; { DateTime }
Unknown3: array[0..329] of char;
SpeedUp: integer; { 快门速度分子 }
SpeedDown: integer; { 快门速度分母 }
Unknown4: array[0..7] of char;
DateTime2: array[0..19] of char; { DateTime }
DateTime3: array[0..19] of char; { DateTime }
Unknown5: array[0..187] of char;
Sony_Flag2: array[0..5] of char; { Flag : Sony }
Device_Flag2: array[0..9] of char; { Device : CyberShot }
Unknown6: array[0..29] of char;
DateTime4: array[0..19] of char; { DateTime }
Space: Char;
end;
function GetDSCInfo(const FileName: string; out Info: TSonyDSCHeader; Preview: TJPEGImage): Boolean;
implementation
{ TSonyCyberShot }
function GetDSCInfo;
const
SOI_SONY = $E1FFD8FF;
SOI = $D8FF; { JPEG File Flag of Start }
EOI = $D9FF; { JPEG File Flag of End }
SONY = $E1FF; { Sony define Flag }
HEADER_LEN = 881;
var
Flag: DWord;
L, H: Byte;
Len: Word;
Ms: TMemoryStream;
Fs: TFileStream;
begin
Result := False;
FS := TFileStream.Create(FileName, fmOpenRead);
with FS do
try
Read(Flag, SizeOf(Flag));
if Flag <> SOI_SONY then Exit;
Read(H, SizeOf(H));
Read(L, SizeOf(L));
Len := MakeWord(L, H);
Read(Info, Sizeof(Info));
Ms := TMemoryStream.Create;
Ms.CopyFrom(Fs, Len - HEADER_LEN);
Ms.Position := 0;
Preview.LoadFromStream(MS);
Ms.Free;
Result := True;
finally
Free;
end;
end;
end.
function Gcf(N1, N2: integer): integer;
begin
Result := N1;
while (N1 > 1) and not ((N1 mod Result = 0) or (N2 mod Result = 0)) do
Dec(Result);
end;
function CommonFraction(Numerator, Denominator: integer): string;
begin
if Numerator mod Denominator = 0 then
Result := Format('%d', [Numerator div Denominator])
else
Result := Format('%d/%d', [Numerator div Gcf(Numerator, Denominator), Denominator div Gcf(Numerator, Denominator)]);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Info: TSonyDSCHeader;
Img: TJPEGImage;
begin
Img := TJPEGImage.Create;
with OpenDialog1 do
if Execute then
if GetDSCInfo(FileName, Info, Img) then
begin
Memo1.Lines.Add('快门速度:' + CommonFraction(Info.SpeedUp, Info.SpeedDown));
Image1.Picture.Assign(Img);
end;
Img.Free;
end;
读取缩略图的代码:
unit SonyInterface;
interface
uses
Windows, Jpeg, Classes, SysUtils;
type
TSonyDSCHeader = packed record
Format_Desc: array[0..5] of char; { Image Format : Exif , for F717 }
Format_Version: array[0..3] of char; { Image Format Version : 2.2, for F717 }
Unknown1: array[0..$A1] of char;
Sony_Flag: array[0..5] of char; { Flag : Sony }
Device_Flag: array[0..9] of char; { Device : CyberShot }
Unknown2: array[0..29] of char;
DateTime: array[0..19] of char; { DateTime }
Unknown3: array[0..640] of char;
end;
function GetDSCInfo(const FileName: string; out Info: TSonyDSCHeader; Preview: TJPEGImage): Boolean;
implementation
{ TSonyCyberShot }
function GetDSCInfo;
const
SOI_SONY = $E1FFD8FF;
SOI = $D8FF; { JPEG File Flag of Start }
EOI = $D9FF; { JPEG File Flag of End }
SONY = $E1FF; { Sony define Flag }
HEADER_LEN = 881;
var
Flag: DWord;
L, H: Byte;
Len: Word;
Ms: TMemoryStream;
Fs: TFileStream;
begin
Result := False;
FS := TFileStream.Create(FileName, fmOpenRead);
with FS do
try
Read(Flag, SizeOf(Flag));
if Flag <> SOI_SONY then Exit;
Read(H, SizeOf(H));
Read(L, SizeOf(L));
Len := MakeWord(L, H);
Read(Info,Sizeof(Info));
Ms := TMemoryStream.Create;
Ms.CopyFrom(Fs, Len - HEADER_LEN);
Ms.Position := 0;
Preview.LoadFromStream(MS);
Ms.Free;
Result := True;
finally
Free;
end;
end;
end.
procedure TForm1.Button2Click(Sender: TObject);
var
Info: TSonyDSCHeader;
Img : TJPEGImage;
begin
Img := TJPEGImage.Create;
with OpenDialog1 do
if Execute then
if GetDSCInfo(FileName,Info,Img) then
Image1.Picture.Assign(Img);
Img.Free;
end;