关于如何获取图片的原始尺寸问题(200分)

  • 主题发起人 主题发起人 JamesDF
  • 开始时间 开始时间
J

JamesDF

Unregistered / Unconfirmed
GUEST, unregistred user!
我用扫描仪扫描 图片A( 5" X 5" ,300dpi)到Photo中,又扫描图片B (10" X 10",600dpi)
的图片到PhotoShop中,把图片格式转换成Jpg,察看图片大小,能够显示正确的尺寸。

我把图片A 和图片B 导入到CorelDraw中, 察看图片的大小,结果和PhotoShop的一样。

我把图片放入Delphi的TImage中,察看Image1.Picture.graphic.height,就得不到PhotoShop
和 CorelDraw的结果。
提出一些疑问
1.通过察看以往的问题,大多数认为,图片文件尺寸大小,只有dpi,在不同分辨率的输出设备下
就会有不同的尺寸。但是PhotoShop 和 CorelDraw 为什么能够识别不同分辨率的图片

2. TImage的分辨率是96dpi,但是如果能够在Delphi中获取到PhotoShop和CorelDraw中的关于图片大小的值。

3. 以前的问题中有关于在bmp文件中保存有关于图片的原始分辨率的数据,但是有没有Jpg图的原始分辨率的获取获取方法?
 
在Delphi下也可以啊,
你要控制计算机的显示模式,
具体看看《VC数字图象编程》吧
对你会有所启发的
 
如果有bmp的,将jpg转成bmp不就可以了
 
这个问题我也费解,在PHOTO中设置长宽分辨率,但IMAGE中不能识别。
为了能打印清晰,只能用大图缩小打印,请参看我的程序:
http://www.playicq.com/dispdocnew.php?t=27&id=3701
 

procedure SetJpgdpi(filename: string; dpix, dpiy: Integer);
const
BufferSize = 50;
DPI = 1; {inch}
DPC = 2; {cm}
var
Buffer: string;
index: Integer;
FileStream: TFileStream;
xResolution: WORD;
yResolution: WORD;
typeA: Byte;
begin
FileStream := TFileStream.Create(filename, fmOpenReadWrite);
try
SetLength(Buffer, BufferSize);
FileStream.Read(buffer[1], BufferSize);
index := Pos('JFIF' + #$00, buffer);
if index > 0 then
begin
FileStream.Seek(index + 6, soFromBeginning);
typeA := DPI;
FileStream.write(typeA, 1);
xresolution := swap(dpix);
FileStream.write(xresolution, 2);
yresolution := swap(dpiy);
FileStream.write(yresolution, 2);
end
finally
FileStream.Free;
end;
end;
 
唉,又是要自己解决,不过把方面也告诉大家
{ 获取JPEG的宽度、高度等信息 }
{ Copyright Kingron 2002 }
function GetJPEGSize(FileName: string; var Width, Height: WORD): Boolean;
const
JPEG_FLAG_BEGIN = $D8FF;
JPEG_FLAG_END = $D9FF;
JPEG_FRAME = $C0FF;
var
FS: TFileStream;
Flag1, Flag2: WORD;
B: Byte;

procedure SeekForFrame;
type
TSegHeader = packed record
Flag: WORD;
LenHi, LenLo: Byte;
end;
var
Seg: TSegHeader;
begin
with Seg, FS do
repeat
Read(Seg, SizeOf(Seg));
if Flag <> JPEG_FRAME then
Position := Position + MakeWord(LenLo, LenHi) - 2;
until (Position >= Fs.Size) or (Seg.Flag = JPEG_FRAME);
end;

begin
FS := TFileStream.Create(FileName, fmOpenRead);
try
{ JPEG 文件开头必须为 FF D8,文件尾必须为 FF D9 }
FS.Read(Flag1, SizeOf(Flag1));
FS.Position := FS.Size - 2;
FS.Read(Flag2, SizeOf(Flag2));
Result := (Flag1 = JPEG_FLAG_BEGIN) and (Flag2 = JPEG_FLAG_END);
if not Result then exit; { 不是合法的JPEG文件则退出 }

FS.Position := 2;
SeekForFrame; { 寻找JPEG的Frame段,即图像数据区 }
FS.Read(B, SizeOf(B)); { Frame段段头后第一个Byte为数据精度 }

FS.Read(B, SizeOf(B)); { 高度高字节 }
WordRec(Height).Hi := B;
FS.Read(B, SizeOf(B)); { 高度低字节 }
WordRec(Height).Lo := B;

FS.Read(B, SizeOf(B)); { 宽度高字节 }
WordRec(Width).Hi := B;
FS.Read(B, SizeOf(B)); { 宽度低字节 }
WordRec(Width).Lo := B;
finally
FS.Free;
end;
end;
 
procedure GetJPGSize(const sFile: string; var wWidth, wHeight: Word);
const
ValidSig: array[0..1] of Byte = ($FF, $D8);
Parameterless = [$01, $D0, $D1, $D2, $D3, $D4, $D5, $D6, $D7];
var
Sig: array[0..1] of byte;
f: TFileStream;
x: integer;
Seg: byte;
Dummy: array[0..15] of byte;
Len: word;
ReadLen: LongInt;
begin
FillChar(Sig, SizeOf(Sig), #0);
f := TFileStream.Create(sFile, fmOpenRead);
try
ReadLen := f.read(Sig[0], SizeOf(Sig));

for x := Low(Sig) to High(Sig) do
if Sig[x] <> ValidSig[x] then
ReadLen := 0;

if ReadLen > 0 then
begin
ReadLen := f.read(Seg, 1);
while (Seg = $FF) and (ReadLen > 0) do
begin
ReadLen := f.read(Seg, 1);
if Seg <> $FF then
begin
if (Seg = $C0) or (Seg = $C1) then
begin
ReadLen := f.read(Dummy[0], 3); { don't need these bytes }
wHeight := ReadMWord(f);
wWidth := ReadMWord(f);
end
else
begin
if not (Seg in Parameterless) then
begin
Len := ReadMWord(f);
f.Seek(Len - 2, 1);
f.read(Seg, 1);
end
else
Seg := $FF; { Fake it to keep looping. }
end;
end;
end;
end;
finally
f.Free;
end;
end;
 
function ReadMWord(f: TFileStream): Word;
type
TMotorolaWord = record
case Byte of
0: (Value: Word);
1: (Byte1, Byte2: Byte);
end;
var
MW: TMotorolaWord;
begin
{ It would probably be better to just read these two bytes in normally }
{ and then do a small ASM routine to swap them. But we aren't talking }
{ about reading entire files, so I doubt the performance gain would be }
{ worth the trouble. }
f.read(MW.Byte2, SizeOf(Byte));
f.read(MW.Byte1, SizeOf(Byte));
Result := MW.Value;
end;
 
procedure GetPNGSize(const sFile: string; var wWidth, wHeight: Word);
type
TPNGSig = array[0..7] of Byte;
const
ValidSig: TPNGSig = (137, 80, 78, 71, 13, 10, 26, 10);
var
Sig: TPNGSig;
f: tFileStream;
x: integer;
begin
FillChar(Sig, SizeOf(Sig), #0);
f := TFileStream.Create(sFile, fmOpenRead);
try
f.read(Sig[0], SizeOf(Sig));
for x := Low(Sig) to High(Sig) do
if Sig[x] <> ValidSig[x] then
Exit;
f.Seek(18, 0);
wWidth := ReadMWord(f);
f.Seek(22, 0);
wHeight := ReadMWord(f);
finally
f.Free;
end;
end;
 
图像大小是一个像素点的大小,设置分辨率DPI后,就可以计算出显示/打印的图像尺寸大小了。
 
还有个方法
Imaging Toolkit for Delphi, Version 1.3.1

-------------------------------------------------------------------------

MCM DESIGN
Sandholmgardsvej 38
3460 Birkerod
Denmark

E-mail: CustomerCare@mcm-design.dk
Homepage: www.mcm-design.com
www.mcm-design.com/imagingtoolkitfordelphi/
www.twaintoolkitfordelphi.com
www.twaintoolkitforcbuilder.com
很不错的一个东西
 
下载后无法安装,不知道who有破解版?
 
多人接受答案了。
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
897
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部