在Java中绘制屏幕外图像时的悲惨文本

时间:2017-07-18 20:14:01

标签: java graphics2d antialiasing double-buffering

我试图通过屏幕外图像双缓冲来修复文本质量,因此被困(超出了乐趣的极限)。 Screen capture worth a thousand words.

  • 丑陋的String被绘制到屏幕外图像,然后被复制到paintComponent的{​​{1}}参数。
  • 好看的Graphics会直接写入String的{​​{1}}参数,绕过屏幕外图像。

两个paintComponent实例(屏幕上和屏幕外)在渲染质量,抗锯齿等方面都是相同的设置......

非常感谢您的智慧。

非常简单的代码如下:

Graphics

2 个答案:

答案 0 :(得分:0)

您没有使用相同的颜色绘制两个字符串。屏幕外图形的默认颜色是rgb(0,0,0)(即纯黑色),而Swing会将Graphics对象的颜色设置为外观的默认颜色 - 对于我而言,在Windows上7,使用默认主题,是rgb(51,51,51),或深灰色。

尝试在您的setupGraphics方法中放置g.setColor(Color.BLACK);,以确保使用相同的颜色绘制两个字符串。

答案 1 :(得分:0)

感谢您的回复。

提到DPI后,MadProgrammer引导我找到了一个可行的解决方案,我在这里提供的解决方法更多的是干净的'清洁'解决方案值得骄傲。无论如何,它解决了这个问题。

我注意到,当我的屏幕分辨率为2880x1800(Retina显示屏)时,MouseEvent的{​​{1}}方法在屏幕的右下角显示x = 1440,y = 900。然后,getPoint()大小是屏幕分辨率的一半,尽管它覆盖了整个屏幕。

这看到,解决方案如下:

  • 首先,创建一个与屏幕分辨率匹配的屏幕外图像,而不是几十个双缓冲文章中建议的JPanel

  • 然后,使用放大变换绘制屏幕外图像,大于需要,特别是通过r =屏幕尺寸/面板尺寸比例进行缩放。

  • 最后,将缩小版的幕外图像复制回屏幕,应用收缩因子r(或比例因子1 / r)。

解决方案实现分为两种方法:

  • 之前发布的初始JPanel.getSize()的修订版
  • 后来解释了一个辅助方法paintComponent

修改后的getDPIFactor()方法如下:

paintComponent

要完成任务,必须获取屏幕分辨率。

拨打public final void paintComponent(Graphics g) { super.paintComponent(g); double dpiFactor = getDPIFactor(); // -------------------------------------- //OffScreen painting Graphics2D osg2D = getOffscreenGraphics(); setupGraphics(osg2D); //Paint stuff bigger than needed osg2D.setTransform(AffineTransform.getScaleInstance(dpiFactor, dpiFactor)); //Custom painting performPainting(osg2D); //Shrink offscreen buffer to screen. ((Graphics2D)g).drawImage( osi, AffineTransform.getScaleInstance(1.0/dpiFactor, 1.0/dpiFactor), this); // -------------------------------------- // OnScreen painting Graphics2D gg = (Graphics2D)g; setupGraphics(gg); gg.drawString("Direct painting", 10, 35); } 并不能解决问题,因为它会返回覆盖整个屏幕的Toolkit.getDefaultToolkit().getScreenResolution()的大小。如上所示,这个数字与物理点中的实际屏幕尺寸不匹配。

Sarge Bosch在this stackoverflow post中清除了获取此数据的方法。 我已经调整了他的代码来实现拼图的最后一部分JPanel

getDPIFactor()

此代码解决了Mac Retina显示的问题,但我对其他任何地方都感到害怕,因为/* * Adapted from Sarge Bosch post in StackOverflow. * https://stackoverflow.com/questions/40399643/how-to-find-real-display-density-dpi-from-java-code */ private Double getDPIFactor() { GraphicsDevice defaultScreenDevice = GraphicsEnvironment.getLocalGraphicsEnvironment() .getDefaultScreenDevice(); // on OS X, it would be CGraphicsDevice if (defaultScreenDevice instanceof CGraphicsDevice) { CGraphicsDevice device = (CGraphicsDevice) defaultScreenDevice; // this is the missing correction factor. // It's equal to 2 on HiDPI a.k.a. Retina displays int scaleFactor = device.getScaleFactor(); // now we can compute the real DPI of the screen return scaleFactor * (device.getXResolution() + device.getYResolution()) / 2 / Toolkit.getDefaultToolkit().getScreenResolution(); } else return 1.0; } 明确提到CGraphicsDevice的专有实现。

我没有其他HDPI硬件可供使用,有机会提供更广泛的解决方案。