Java打印中如何获取BufferedImage的点单位边界以避免文字重叠?
获取PrinterJob中绘制图像的点单位边界
要算出这张图像在打印页面上的点单位边界(避免在图像区域内写文字),你可以按以下步骤操作:
确定图像的起始绘制坐标
你代码里用的imageableX和imageableY来自PageFormat,这两个值本身就是点单位(1点 = 1/72英寸),也就是图像左上角在打印页面上的位置。把图像像素尺寸转换成点单位
BufferedImage的getWidth()/getHeight()返回的是像素数,得结合图像的DPI转换成打印用的点:- 先获取图像的DPI信息(没有的话默认用打印系统标准的72DPI):
BufferedImage image = crossword.getImage(); float dpiX = image.getProperty("dpiX", 72f); float dpiY = image.getProperty("dpiY", 72f); - 转换像素为点:
float imageWidthInPoints = (image.getWidth() * 72f) / dpiX; float imageHeightInPoints = (image.getHeight() * 72f) / dpiY;
- 先获取图像的DPI信息(没有的话默认用打印系统标准的72DPI):
计算完整的边界范围
结合起始坐标和转换后的尺寸,图像的点单位边界矩形是:- 左上角:
(imageableX, imageableY) - 右下角:
(imageableX + imageWidthInPoints, imageableY + imageHeightInPoints)
- 左上角:
如果用了缩放变换,要额外处理
要是你给Graphics2D加了缩放、旋转之类的变换,得把变换应用到边界矩形上才能得到实际打印位置:AffineTransform transform = g2d.getTransform(); Rectangle2D imageRect = new Rectangle2D.Float(imageableX, imageableY, imageWidthInPoints, imageHeightInPoints); // 应用变换后的矩形就是实际打印的边界 transform.transform(imageRect, imageRect);
整合到你的代码里
你可以把计算逻辑加到print方法里,用来判断文字位置是否在图像外:
@Override public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { // ... 其他初始化代码 Graphics2D g2d = (Graphics2D) graphics; BufferedImage image = crossword.getImage(); float imageableX = (float) pageFormat.getImageableX(); float imageableY = (float) pageFormat.getImageableY(); // 计算图像的点单位尺寸 float dpiX = image.getProperty("dpiX", 72f); float dpiY = image.getProperty("dpiY", 72f); float imgWidthPoints = (image.getWidth() * 72f) / dpiX; float imgHeightPoints = (image.getHeight() * 72f) / dpiY; // 绘制图像 g2d.drawImage(image, null, (int) imageableX, (int) imageableY); // 构建图像的边界矩形 Rectangle2D imageBounds = new Rectangle2D.Float(imageableX, imageableY, imgWidthPoints, imgHeightPoints); // 示例:安全绘制文字(确保不在图像范围内) String text = "需要打印的文字"; FontMetrics metrics = g2d.getFontMetrics(); // 假设要绘制在(100, 100)位置 float textX = 100f; float textY = 100f; Rectangle2D textBounds = metrics.getStringBounds(text, g2d); textBounds.setRect(textX, textY - metrics.getAscent(), textBounds.getWidth(), textBounds.getHeight()); if (!imageBounds.intersects(textBounds)) { g2d.drawString(text, textX, textY); } // ... 其他代码 return PAGE_EXISTS; }
内容的提问来源于stack exchange,提问作者Elly
相关产品推荐
相关产品推荐

