急了,如何获得TBitmap中图片的分辨率(1200分) (100分)

  • 主题发起人 主题发起人 whf
  • 开始时间 开始时间

Var
tmpStream:TFileStream;
FileHeader:TBitMapFileHeader;
FbmHeadInfo: PBITMAPINFOHEADER;
begin
TmpStream:=TFileStream.Create('FileName',fmOpenRead);
try
TmpStream.ReadBuffer(FileHeader,Sizeof(TBITMAPFILEHEADER));
if FileHeader.bfType<>$4D42 then raise Exception.Create('无效的位图文件');
GetMem(FbmHeadInfo,Sizeof(TBITMAPINFOHEADER));
TmpStream.ReadBuffer(FbmHeadInfo^,Sizeof(TBITMAPINFOHEADER)) ;
FreeMem(FbmHeadInfo,Sizeof(TBITMAPINFOHEADER));
ShowMessage('X PixelPerMeter:'+IntToStr(FbmHeadInfo.biXPelsPerMeter)
+'X PixelPerMeter:'+IntToStr(FbmHeadInfo.biYPelsPerMeter));
except
TmpStream.Free ;
raise ;
end ;
TmpStream.Free ;
end;
 
有希望,biXPelsPerMeter怎样转换成每英寸的像素数,比如:我用"映像"得到的是90,
用这段程序得到的是3510。
 
奇怪的现象,当把一张位图文件在 映像 中改变分辨率, 比如从90--〉70
这时你发现显示的尺寸变大了,(但是,在选项里的实际尺寸没变)然后保存文件,
用画图打开,现在你看到的是图像变小了,看来两个软件的工作原理很不一样啊
是否画图总是以96 来打开图片呢?
 
我觉得画笔和delphi中的TBitmap都没有用到图片中的分辨率(都按照96处理),所以才有
这种现象。
 
刚才得到的数字如果除以39就

你最后要的结果
 
为什么?
还有JPG,GIF如何得到?
再加200分(以后每天加200分,直到有结果,或者我破产)
 
先声明,我是外行,说错了请指正:
我猜测象BITMAP这种格式可能并没有分辨率这个指标,只有象素数,楼上说的好象都是这个.而分辨率应该
是原图上单位距离里的象素数.
例如一张照片,我用100的分辨率扫描和300的分辨率扫描结果图象大小差9倍,但我用ACDSee
这样的看图软件看的时候,并没有办法看出来这张图原来有多大(以JPEG/BMP等格式保存).
要知道分辨率除了要知道图象的象素多少以外还要知道这张图的尺寸.BMP图象的文件里有没有保存
这个信息,请知道的高手指点,可以明确的是,象PHOTOSHOP,CoreldRAW制出的并以它们自己格式保存的图里应
该是有包括的,
(个人猜测,尽供参考 [:D])
 
重复一遍: 位图本身没有分辨率这个概念,分辨率要取决于你要在多大的区域来显示或打印!
同一个位图,显示的区域越大,分辨率就越小,反之就大;

每种软件对位图处理时会用不同的缩放比例来显示,你也可以修改,
PhotoShop,CorelDraw 里改变分辨率最终会改变位图本身的大小,即点数和字节数;

至于 映像 里的处理,其实是先确定"大小"再计算相应的点数,注意,这里的"大小"是以毫米或英寸为单位的,
在 映像 里改小分辨率,而没改变"大小",当然会导致实际点数减少,因此再用画笔打开,看起来会小;还可以看看改变后文件的 字节数,
在 映像 里看起来变大,,那跟你"缩放"菜单下的显示模式有关,
点数 = 毫米为单位的大小 / 25.4 * dpi
 
至于 映像 里的处理,其实是先确定"大小"再计算相应的点数,注意,这里的"大小"是以毫米或英寸为单位的,
--我就是想知道“大小”(以毫米为单位,以像素为单位的会随着“分辨率”(暂时叫吧)会变的)
 
应该反过来,

只能以点数的大小和显示/打印的大小(以长度为单位,这个大小要由你来设定)来决定分辨率
或者,对显示/打印设备来说,你可以改变设备的显示/打印分辨率(而不是位图的分辨率),就会改变显示/打印时的大小了,


GetDeviceCaps(printer.Handle, LOGPIXELSX);
可以得到打印水平方面的分辨率,以英寸为单位;
 
不对,我在“映像”里发现,以毫米为单位的大小是固定的,不随分辨率的改变而改变,
而以像素为单位的大小是变化的,用Height,Width取得的大小是以像素为单位的,如何得到
以毫米为单位的大小?
 
根据测试,我觉得 映像 里是利用 bitmapinfoheader 里面的:biXPelsPerMeter,biYPelsPerMeter 来计算这个尺寸的
但这个分辨率你基本上用不着,因为要如何显示这幅位图,是要根据你的实际情况来决定的,
 
我是想原始尺寸显示和打印图片,得不到分辨率,显示和打印的图片不是原始尺寸的。
 
所谓原始尺寸,应该是一个像素点对一个显示/打印设备的点,

Delphi 中用 Printer.Canvas.Draw(0, 0, bmp); 即是原样输出,
 
不是,我已经是过了.
 
我实验发现,如果你扫描后保存的为.bmp格式,用JobsLee的方法再除39可得你扫描时设置
的分辨率dpi(每英寸点数),因此图片的实际大小为bitmap.width/dpi,bitmap.height/dpi,
单位为英寸.再乘2.54,得到的单位为厘米.
但用其它格式转换过来的.bmp文件则得到的PixelPerMeter为0.

继续关注
 
谢谢,跟我做的实验一样,但我不清楚这个39是怎么得来的。
 
39我也不知道其原理,但它确实有用.
我想其它格式图象文件(jpg,tiff,gif...),自己可以写个图象转换程序,先转换
成bmp文件,再得到它的实际大小.
我先实验一下.
 
>> 但用其它格式转换过来的.bmp文件则得到的PixelPerMeter为0.

所以你不能用它作为显示尺寸的依据

>> 但我不清楚这个39是怎么得来的。

39 = 1000 / 25.4; ---> PixelPerMeter 是每米(1000毫米)的点数,

>> 我是想原始尺寸显示和打印图片,得不到分辨率,显示和打印的图片不是原始尺寸的。

我想问,什么是"原始"?我认为你不可能得到"原始"大小
 
haha,问题解决(晕了,你这句提醒了我)可以得到的,Width / 分辨率 = 实际宽(以英寸表示)
我再开一贴,大家到那里拿分,这贴我想保留几天,看还有没有别的方法
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部