通过Delphi TCanvas打印JPEG图像时遇到一些麻烦。 在JPEG将打印为黑色的30-50%的任何时间 广场而不是它应该。已尝试更改许多设置以查看 如果有一个特定的条件,它将无法打印,但 截至撰写本文时,没有任何工作,条件仍然存在 - 我无法分辨打印输出何时可能有黑色JPEG或何时打印正确。
以下是我用于将JPEG打印到Canvas的代码。
Screen.Cursor := crHourGlass;
try
// initialize image
//>>imgImage := TImage.Create(Self);
imgImage := TImage.Create(Application);
// load image from file
imgImage.Picture.LoadFromFile(sFileNameAndPath);
// set width and height to that of loaded image
////imgImage.Autosize := true;
////Printer.Orientation := poPortrait;
// Header
Printer.Canvas.Font.Height := MulDiv(GetDeviceCaps(Printer.Canvas.Handle, LOGPIXELSY), 12, 72);
Printer.Canvas.Font.Name := 'Courier New';
// Determine height and width of 1 printer-character
iDeltaW := Printer.Canvas.TextWidth('X');
iDeltaH := Printer.Canvas.TextHeight('X');
// ------------------------------
// Method #1 - columns and lines
// ------------------------------
// what column to printing from
iFromLeftMargin := iLeft * iDeltaW;
// what line to print from
iFromTopOfPage := iTop * iDeltaH;
// ------------------------------
// Method #2 - pixels
// ------------------------------
iPPW := Printer.PageWidth;
iPPH := Printer.PageHeight;
iIPW := imgImage.Picture.Width;
ePXW := iPPW / iInvImageWidth;
ePXH := iPPH / iInvImageHeight;
//~//iFromLeftMargin := Ceil(iLeft * pxW);
//~//iFromTopOfPage := Ceil(iTop * pxH);
iFromLeftMargin := Ceil(iLeft * ePXW);
iFromTopOfPage := Ceil(iTop * ePXH);
// Set printed bitmap width
iPrintedImageWidth := MulDiv(iPPW, iIPW, iInvImageWidth);
// Set printed bitmap height to maintain aspect ratio
iPrintedImageHeight := imgImage.Picture.Height * iPrintedImageWidth DIV
imgImage.Picture.Width; // maintain aspect ratio of bitmap
Bitmap := TBitmap.Create;
try
Bitmap.Width := imgImage.Picture.Width;
Bitmap.Height := imgImage.Picture.Height;
Bitmap.PixelFormat := pf24bit;
Bitmap.IgnorePalette := False;
// Convert JPEG (GIF, or whatever) to BMP
Bitmap.Canvas.Draw(0, 0, imgImage.Picture.Graphic);
// Print Image
PrintBitmap(Printer.Canvas,
Rect(iFromLeftMargin, iFromTopOfPage,
iFromLeftMargin + iPrintedImageWidth,
iFromTopOfPage + iPrintedImageHeight),
Bitmap);
finally
// free bitmap memory
Bitmap.Free;
end;
// free image memory
imgImage.Free;
finally
Screen.Cursor := crDefault;
end;
如果有人有任何想法,我将不胜感激!
此致 詹姆斯
编辑:下面的PrintBitmap方法的代码。我已经采取了将位图保存到磁盘的建议,以便在生成时查看它,即使打印输出为黑色方块,也不会将其保存为黑色方块。我希望这表明问题出现在下面的PrintBitmap代码中。
procedure PrintBitmap(Canvas: TCanvas; DestRect: TRect; Bitmap: TBitmap);
var
BitmapHeader: pBitmapInfo;
BitmapImage: POINTER;
HeaderSize: DWORD;
ImageSize: DWORD;
begin
GetDIBSizes(Bitmap.Handle, HeaderSize, ImageSize);
GetMem(BitmapHeader, HeaderSize);
GetMem(BitmapImage, ImageSize);
try
GetDIB(Bitmap.Handle, Bitmap.Palette, BitmapHeader^, BitmapImage^);
StretchDIBits(Canvas.Handle,
DestRect.Left, DestRect.Top, // Destination Origin
DestRect.Right - DestRect.Left, // Destination Width
DestRect.Bottom - DestRect.Top, // Destination Height
0, 0, // Source Origin
Bitmap.Width, Bitmap.Height, // Source Width & Height
BitmapImage,
TBitmapInfo(BitmapHeader^),
DIB_RGB_COLORS,
SRCCOPY);
finally
FreeMem(BitmapHeader);
FreeMem(BitmapImage);
end;
end; {PrintBitmap}
不幸的是,此代码是由不再在我公司工作的人编写的,我只是想解决现有问题。
答案 0 :(得分:3)
很难说你发布的代码片段。你应该发布一些自给自足的工作代码(可编辑和可运行) 例如,没有本地var声明,没有Begindoc / EndDoc。
现在,在添加本地声明之后,有一堆编译器警告未初始化变量,如iTop
或iLeft
。如果那些留下随机垃圾,可能是你没有画你认为你做的地方。
您还假设您始终拥有pf24bit
格式,但根本无法保证。由于您没有指定相同的JPG是否可以打印正常或随机失败,或者如果它有不同的JPG而您遇到问题,则无法排除格式转换问题。
我还建议您安装一个免费的可用图像调试展示台,在PrintBitmap
之前设置一个断点,然后在打印前查看本地Bitmap
是否正确。
然后让我们看看PrintBitmap
程序中的内容......您是否尝试直接在Printer Canvas上绘图?
更新:
PrintBitmap
代码似乎是合法的,除了它不检查任何返回代码:
if not GetDIB(...) then
raise [...];
if GDI_ERROR = StretchDIBits(...) then
RaiseLastOSError;
问题可能来自打印机/驱动程序 您是否尝试过其他打印机或其他驱动程序? 另外,请确保您的打印机准备就绪......