怎样让Printer.Canvas.Pixels[15, 15] := clBlack的一个象素点打印出来清楚啊?(200分)

  • 主题发起人 WangZhaoHui
  • 开始时间
以下是 VC 下的处理!!!你看看吧。

使用各种映射方式

所谓的映射方式简单点讲就是坐标的安排方式,系统默认的映射方式为MM_TEXT即X坐标向右增加,Y坐标向下增加,(0,0)在屏幕左上方,DC中的每一点就是屏幕上的一个象素。也许你会认为这种方式下是最好理解的,但是一个点和象素对应的关系在屏幕上看来是正常的,但到了打印机上就会很不正常。因为我们作图是以点为单位并且打印机的分辨率远远比显示器高(800DPI 800点每英寸)所以在打印机上图形看起来就会很小。这样就需要为打印另做一套代码而加大了工作量。如果每个点对应0.1毫米那么在屏幕上的图形就会和打印出来的图形一样大小。
通过int CDC::SetMapMode( int nMapMode )可以指定映射方式,可用的有以下几种:
MM_HIENGLISH 每点对应0.001英寸 Each logical unit is converted to 0.001 inch. Positive x is to the right;
positive y is up.

MM_HIMETRIC 每点对应0.001毫米 Each logical unit is converted to 0.01 millimeter. Positive x is to the right;
positive y is up.

MM_LOENGLISH 每点对应0.01英寸 Each logical unit is converted to 0.01 inch. Positive x is to the right;
positive y is up.

MM_LOMETRIC 每点对应0.001毫米 Each logical unit is converted to 0.1 millimeter. Positive x is to the right;
positive y is up.

MM_TEXT 象素对应 Each logical unit is converted to 1 device pixel. Positive x is to the right;
positive y isdo
wn.

以上几种映射默认的原点在屏幕左上方。除MM_TEXT外都为X坐标向右增加,Y坐标向上增加,和自然坐标是一致的。所以在作图是要注意什么时候应该使用负坐标。而且以上的映射都是X-Y等比例的,即相同的长度在X,Y轴上显示的长度都是相同的。

DownLoad Sample

另外的一种映射方式为MM_ANISOTROPIC,这种方式可以规定不同的长宽比例。在设置这中映射方式后必须调用CSize CDC::SetWindowExt( SIZE size )和CSize CDC::SetViewportExt( SIZE size )来设定长宽比例。系统会根据两次设定的长宽的比值来确定长宽比例。下面给出一段代码比较映射前后的长宽比例:
OnDraw(CDC* pDC)
{
CRect rcC1(200,0,400,200);
pDC->FillSolidRect(rcC1,RGB(0,0,255));
pDC->SetMapMode(MM_ANISOTROPIC );
CSize sizeO;
sizeO=pDC->SetWindowExt(5,5);
TRACE("winExt %d %d/n",sizeO.cx,sizeO.cy);
sizeO=pDC->SetViewportExt(5,10);
TRACE("ViewExt %d %d/n",sizeO.cx,sizeO.cy);
CRect rcC(0,0,200,200);
pDC->FillSolidRect(rcC,RGB(0,128,0));
}
上面代码在映射后画出的图形将是一个长方形。

DownLoad Sample

最后讲讲视原点(viewport origin),你可以通过调用CPoint CDC::SetViewportOrg( POINT point )重新设置原点的位置,这就相对于对坐标进行了位移。例如你将原点设置在(20,20)那么原来的(0,0)就变成了(-20,-20)。
 
调用 api SetMode 应该可以的!

The SetMapMode function sets the mapping mode of the specified device context. The mapping mode defines the unit of measure used to transform page-space units into device-space units, and also defines the orientation of the device's x and y axes.
int SetMapMode(
HDC hdc, // handle of device context
int fnMapMode // new mapping mode
);

Parameters
hdc
Identifies the device context.
fnMapMode
Specifies the new mapping mode. It can be any one of the following values:
Value Description
MM_ANISOTROPIC Logical units are mapped to arbitrary units with arbitrarily scaled axes. Use the SetWindowExtEx and SetViewportExtEx functions to specify the units, orientation, and scaling that you want.
MM_HIENGLISH Each logical unit is mapped to 0.001 inch. Positive x is to the right;
positive y is up.
MM_HIMETRIC Each logical unit is mapped to 0.01 millimeter. Positive x is to the right;
positive y is up.
MM_ISOTROPIC Logical units are mapped to arbitrary units with equally scaled axes;
that is, one unit along the x-axis is equal to one unit along the y-axis. Use the SetWindowExtEx and SetViewportExtEx functions to specify the units and the orientation of the axes that you want. Graphics device interface (GDI) makes adjustments as necessary to ensure the x and y units remain the same size (for example, if you set the window extent, the viewport will be adjusted to keep the units isotropic).
MM_LOENGLISH Each logical unit is mapped to 0.01 inch. Positive x is to the right;
positive y is up.
MM_LOMETRIC Each logical unit is mapped to 0.1 millimeter. Positive x is to the right;
positive y is up.
MM_TEXT Each logical unit is mapped to one device pixel. Positive x is to the right;
positive y isdo
wn.
MM_TWIPS Each logical unit is mapped to one twentieth of a printer's point (1/1440 inch, also called a "twip"). Positive x is to the right;
positive y is up.

Return Values
If the function succeeds, the return value identifies the previous mapping mode.
If the function fails, the return value is zero.
Remarks
The MM_TEXT mode allows applications to work in device pixels, whose size varies from device to device.
The MM_HIENGLISH, MM_HIMETRIC, MM_LOENGLISH, MM_LOMETRIC, and MM_TWIPS modes are useful for applications drawing in physically meaningful units (such as inches or millimeters).
The MM_ISOTROPIC mode ensures a 1:1 aspect ratio.
The MM_ANISOTROPIC mode allows the x-coordinates and y-coordinates to be adjusted independently.
See Also
GetMapMode, SetViewportExtEx, SetViewportOrgEx, SetWindowExtEx, SetWindowOrgEx
 
我知道,但这个是对pen起作用的,我每一项都试过了,对Printer.Canvas.Pixels[15, 15] := clBlack的一个象素点变大不起作用啊。
有谁知道如何将设置存回去。用setprinter.
var
sDrv: Pchar;
sPrt: Pchar;
DevAdr: THandle;
p: PDeviceModeA;
begin
sdrv := allocmem(256);
sprt := allocmem(64);
devadr := 0;
try
printer.GetPrinter(sdrv, sdrv, sprt, devadr);
p := ptr(devadr);
p^.dmFields := DM_PAPERSIZE;
p^.dmLogPixels:=300;
do
cumentProperties(0, printer.handle, sdrv, p^, p^,
DM_IN_BUFFER);
finally
freemem(sdrv, 256);
freemem(sprt, 64);
end;
 
如果你都试过,只能说明对打印机操作,以下方法不可取:
Printer.Canvas.Pixels[15, 15] := clBlack
 
但在300dpi下是可以看清楚的,600dpi以上时,一个象素点就看不清啦。所以我才问如何用程序将打印机分辨率高成300dpi
 
我看实在不行的话,就告诉操作人员,先将打印机设置为300dpi再使用吧,这是最简单的办法
也是没有办法的办法了
 
呵呵,老大,人家买的是hp 1200,我怎么好意思让人家按300dpi的用啊,只能在程序中偷偷的实现。
 
画两个点不行吗?
 
两个点看不清,三个以上又比MoveTo,LineTo慢。所以我也没办法。我的程序在HP 6L下不慢的,到了HP1200不知为什么就慢。所以只能在程序中实现,不能改驱动程序为6L的。谁还有办法啊?
 
在1200*1200分辨率下画一个点当然是看不见的,可以这样:
1: 首先进行分辨率的转换。
2: 创建一个bitmap(当然是全黑),根据比例进行Strech
 
to Headchen:对不起,方法是有很多,但我要的是速度啊。我其实只想问如何在程序中改打印机的分辩率。
 
既然你用Printer,那肯定不能实现实时打印,只能是一次或分次输出,
你应该先画到一个BITMAP中,然后按实际要求的比例尺缩放到打印机上,那个点自然会被系统缩放。
 
这个速度并不慢啊,你需要什么速度啊!
 
to wk_knife:我大概要执行10000多次的循环来画点,用别的方法真的不行,改变打印机分辨率为300dpi时,用的内存都在600k以上(5页/分钟。再慢谁也受不了啦),实在是没有什么别的办法啦,谁能告诉我如何在程序中改变打印机分辨率啊。就是printers.getprinter,printers.setprinter.我试了半天也没用明白,谁会啊?
 
通过Printer是没有办法的,只有调用windows API与打印机驱动有关的,不过改变打印机的分辨率
的API还不清除,再说不一定所有的打印机均支持,可能要调用打印机驱动提供的API了,仅仅提供
思路,具体我也没有干过
 
是啊,谁会啊?
 
虚拟300dpi!先画在临时的BMP上,再往打印机上送!(一个思路而以)
不过又要快,又要精细,好象不太遵守质量守恒,呵呵!
 
to 卡色:谢谢,但我之所以要在程序设打印机为300dpi是为了能让打印机的一个象素点打印清楚:)
 
多人接受答案了。
 

Similar threads

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