Java Graphics2D drawImage() 和 clip() : how to apply antialiasing?

标签 java

Java Graphics2D的drawImageclip方法绘制的BufferedImage边缘有锯齿,如何应用抗锯齿?

enter image description here

代码:

BufferedImage img = ImageIO.read(new File("D:\\Pictures\\U\\U\\3306231465660486.jpg"));

JFrame frame = new JFrame();
frame.add(new JPanel() {
    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        g2d.setColor(Color.RED);
        g2d.drawLine(10, 10, 300, 100);


        g2d.translate(50, 200);
        g2d.rotate(Math.toRadians(30), getWidth() / 2.0, getHeight() / 2.0);
        g2d.drawImage(img, 0, 0, this);
        g2d.clip(new Rectangle(-110, 110, 80, 110));
        g2d.fill(new Rectangle(-100, 100, 100, 100));
    }
});

frame.setSize(600, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);

最佳答案

一种解决方案是在加载图像后模糊图像的边界。您还应该将 RenderingHints.KEY_RENDERINGRenderingHints.VALUE_RENDER_QUALITY 一起使用。

这是最终结果:

enter image description here

完整代码如下。请注意,它使用了 Marco13 描述的模糊方法。在这个答案中:https://stackoverflow.com/a/22744303/4289700 .

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MultipleGradientPaint;
import java.awt.RadialGradientPaint;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class Main {

    private static BufferedImage blurImageBorder(BufferedImage input, double border) {
        int w = input.getWidth();
        int h = input.getHeight();
        BufferedImage output = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

        Graphics2D g = output.createGraphics();
        g.drawImage(input, 0, 0, null);

        g.setComposite(AlphaComposite.DstOut);
        Color c0 = new Color(0x000000FF);

        // Left
        g.setPaint(new GradientPaint(new Point2D.Double(0, border), c0, new Point2D.Double(border, border), c0));
        g.fill(new Rectangle2D.Double(0, border, border, h- border - border));

        // Right
        g.setPaint(new GradientPaint(new Point2D.Double(w - border, border), c0, new Point2D.Double(w, border), c0));
        g.fill(new Rectangle2D.Double(w- border, border, border, h- border - border));

        // Top
        g.setPaint(new GradientPaint(new Point2D.Double(border, 0), c0, new Point2D.Double(border, border), c0));
        g.fill(new Rectangle2D.Double(border, 0, w - border - border, border));

        // Bottom
        g.setPaint(new GradientPaint(new Point2D.Double(border, h - border), c0, new Point2D.Double(border, h), c0));
        g.fill(new Rectangle2D.Double(border, h - border, w - border - border, border));

        final float[] floatArray = new float[]{ 0, 1 };
        final Color[] colorArray = new Color[]{ c0, c0 };

        // Top Left
        g.setPaint(new RadialGradientPaint(new Rectangle2D.Double(0, 0, border + border, border + border),
                floatArray, colorArray, MultipleGradientPaint.CycleMethod.NO_CYCLE));
        g.fill(new Rectangle2D.Double(0, 0, border, border));

        // Top Right
        g.setPaint(new RadialGradientPaint(
                new Rectangle2D.Double(w - border - border, 0, border + border, border + border),
                floatArray, colorArray, MultipleGradientPaint.CycleMethod.NO_CYCLE));
        g.fill(new Rectangle2D.Double(w - border, 0, border, border));

        // Bottom Left
        g.setPaint(new RadialGradientPaint(
                new Rectangle2D.Double(0, h - border - border, border + border, border + border),
                floatArray, colorArray, MultipleGradientPaint.CycleMethod.NO_CYCLE));
        g.fill(new Rectangle2D.Double(0, h - border, border, border));

        // Bottom Right
        g.setPaint(new RadialGradientPaint(
                new Rectangle2D.Double(w - border - border, h - border - border, border + border, border + border),
                floatArray, colorArray, MultipleGradientPaint.CycleMethod.NO_CYCLE));
        g.fill(new Rectangle2D.Double(w - border, h - border, border, border));

        g.dispose();

        return output;
    }

    public static void main(String[] args) throws IOException {
        BufferedImage raw = ImageIO.read(new File("/path/to/picture.jpg"));
        BufferedImage img = blurImageBorder(raw, 1);

        JFrame frame = new JFrame();
        frame.add(new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                Graphics2D g2d = (Graphics2D) g;

                g2d.setColor(Color.RED);
                g2d.drawLine(10, 10, 300, 100);

                g2d.translate(50, 200);
                g2d.rotate(Math.toRadians(30), getWidth() / 2.0, getHeight() / 2.0);

                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

                g2d.drawImage(img, 0, 0, this);
                g2d.fill(new Rectangle(-100, 100, 100, 100));
            }
        });

        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setSize(600, 600);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }    
}

关于Java Graphics2D drawImage() 和 clip() : how to apply antialiasing?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52818654/

相关文章:

java - Mule ESB - 在同一流程中配置多个组件

Java Pong 球和 Racket 不可见

java - 处理 Spring Boot 资源服务器中的安全异常

java - RecyclerView 的动态部分标题使用当前日期时间

java - 如何在 JAX-RS 中获取当前调度的 Web 资源的 URI?

java - 用扫描仪扫描文本文件会吃掉数字的数字吗?

java - Spring 3的最小Hibernate 4 XML配置,用于基于注释的事务管理和对象映射?

java - 在线程中启动的方法是否绑定(bind)到该线程?

java - 自动用随机数据填充原始属性?

java - Java 游戏中不显示背景图像