Java Swing BufferedImage质量差 [英] Java Swing BufferedImage poor quality

查看:304
本文介绍了Java Swing BufferedImage质量差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在BufferedImage上创建图形,然后复制到JPanel中。
当我直接在JPanel上绘制时,图片的质量是v.good,但是在使用中间BufferedImage时,质量/分辨率会明显降低。
我已经通过OSX的辅助功能面板中的缩放选项进行了检查。
我正在MacBook Pro Retina上开发。

I'm trying to create a drawing on BufferedImage and then copy in onto JPanel. When I draw directly on JPanel quality of the picture is v.good but when using intermediate BufferedImage quality / resolution is visibly reduced. I've checked that with zoom option from OSX's Accessibility panel. I'm developing on MacBook Pro Retina.

是否正在发生某种自动缩放?
BufferedImage我在做什么?

Is there some sort of automated scaling happening? What am I doing wrong with BufferedImage?

以下是演示问题的代码

package com.sample.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class QualityProblem {

private static final double DOT_SIZE = 4;

public static void main(String[] args) {
    JFrame frame = new JFrame("ChartPanel demo");
    frame.setBackground(Color.WHITE);

    // JPanel draw = new DrawingOK();
    JPanel draw = new DrawingUgly();
    draw.setBackground(Color.BLACK);

    frame.getContentPane().add(draw, BorderLayout.CENTER);
    frame.setSize(new Dimension(1200, 900));
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    frame.setVisible(true);
}

private static class DrawingOK extends JPanel {

    private static final long serialVersionUID = 1L;

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2draw = (Graphics2D) g.create();
        try {
            g2draw.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2draw.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2draw.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

            Ellipse2D.Double e = new Ellipse2D.Double(50, 50, DOT_SIZE, DOT_SIZE);
            g2draw.setColor(Color.YELLOW);
            g2draw.fill(e);
        } finally {
            g2draw.dispose();
        }
    }
}

private static class DrawingUgly extends JPanel {

    private static final long serialVersionUID = 1L;

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Dimension size = getParent().getSize();
        BufferedImage image = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);

        Graphics2D ig = image.createGraphics();
        ig.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        ig.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        ig.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

        Graphics2D g2draw = (Graphics2D) g.create();
        try {
            Ellipse2D.Double e = new Ellipse2D.Double(50, 50, DOT_SIZE, DOT_SIZE);
            ig.setColor(Color.YELLOW);
            ig.fill(e);
            g2draw.drawImage(image, 0, 0, null);
        } finally {
            ig.dispose();
            g2draw.dispose();
        }
    }
}
}


添加了具有4像素点和50D的图像,并且都放大了。
丑陋的一个图像是从BufferedImage复制到屏幕的图形

Edited: Added images with 4 pixel dot and 50D both zoomed in. Ugly one comes from BufferedImage copied onto screen's Graphics

推荐答案

HaraldK在问题下方的一条评论中给出了非常好的建议。 BufferedImage的大小需要乘以2,该图像的Graphics2D必须设置为缩放比例2,而目标Graphics2D(屏幕设备)的缩放比例必须设置为0.5。
使用这些设置,放大时两个圆圈看起来完全一样。
波纹管完整,修改了DrawingUgly类。

HaraldK in one comments below question gave really good advice. BufferedImage size needs to be multiplied by 2, Graphics2D for that image must be set with scale 2 and target Graphics2D (of the screen device) needs to be scaled with 0.5. With those settings both circles look exactly the same when zoomed in. Bellow complete, modified DrawingUgly class.

    private static class DrawingUgly extends JPanel {

    private static final long serialVersionUID = 1L;

    public DrawingUgly() {
        this.setPreferredSize(new Dimension(600, 25));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2draw = (Graphics2D) g.create();

        double scale = 2;
        BufferedImage image = new BufferedImage((int) (getWidth() * scale), (int) (getHeight() * scale), BufferedImage.TYPE_INT_RGB);

        Graphics2D ig = image.createGraphics();
        ig.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        ig.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        ig.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

        ig.scale(scale, scale);

        ig.setColor(Color.BLACK);
        ig.fillRect(0, 0, getWidth(), getHeight());

        Ellipse2D.Double e = new Ellipse2D.Double(10, 10, DOT_SIZE, DOT_SIZE);
        ig.setColor(Color.YELLOW);
        ig.fill(e);
        ig.dispose();

        g2draw.scale(1.0d / scale, 1.0d / scale);

        g2draw.drawImage(image, 0, 0, this);
    }
}

这篇关于Java Swing BufferedImage质量差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆