3

BufferedImage背景が透明な「リング」を作りたいです。次のように、背景が透明な円を描くことができます。

BufferedImage bi = new BufferedImage(d, d, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) bi.getGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(c);
g.fillOval(0, 0, d, d);

しかし、ここで、リングを作成するために、その中央に小さな透明な円を描画したいと思います(したがって、この画像を別の画像の上に描画すると、リングの周囲と内側のピクセルは描画されません)。Graphicsアンチエイリアスを使用できるように、オブジェクトを使用してこれを実行したいと思います。

これは可能ですか?そうでない場合、この問題に取り組むための最良の方法は何ですか?

4

2 に答える 2

7

円形を作成し、そこから別の円形を差し引き、それをクリップとして設定すると、必要な線に沿って何かができあがる可能性があります。クリップの粗いエッジを非表示にするには、シェイプの2px幅のストロークを描画します。

一つの指輪

import java.awt.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class OneRing {

    OneRing(BufferedImage imageBG, BufferedImage imageFG) {
        // presumes the images are identical in size BNI
        int w = imageBG.getWidth();
        int h = imageBG.getHeight();
        Ellipse2D.Double ellipse1 = new Ellipse2D.Double(
                w/16,h/16,7*w/8,7*h/8); 
        Ellipse2D.Double ellipse2 = new Ellipse2D.Double(
                w/4,h/4,w/2,h/2);
        Area circle = new Area(ellipse1);
        circle.subtract(new Area(ellipse2));

        Graphics2D g = imageBG.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
        g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g.setClip(circle);
        g.drawImage(imageFG, 0, 0, null);
        g.setClip(null);
        Stroke s = new BasicStroke(2);
        g.setStroke(s);
        g.setColor(Color.BLACK);
        g.draw(circle);
        g.dispose();

        JLabel l = new JLabel(new ImageIcon(imageBG));
        JOptionPane.showMessageDialog(null, l);
    }

    public static void main(String[] args) throws Exception {
        URL urlFG = new URL("http://i.stack.imgur.com/OVOg3.jpg");
        URL urlBG = new URL("http://i.stack.imgur.com/lxthA.jpg");
        final BufferedImage biFG = ImageIO.read(urlFG);
        final BufferedImage biBG = ImageIO.read(urlBG);
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                new OneRing(biBG, biFG);
            }
        });
    }
}
于 2012-06-01T16:59:54.737 に答える
2

透明な形を描くことはできません。Java 2Dを含むほとんどのグラフィックスAPIでは、何かの上に描画すると、グラフィックスコンテキストが既存のピクセルを新しいピクセルと「ブレンド」します。あなたが探しているものを達成するブレンドモードを見つける必要があります。Javaでのブレンドは、Compositeを介して行われます。

次の操作を実行するコンポジットを使用/実装する必要があります。

result color = destination color
result alpha = destination alpha - source alpha

次に、alpha = 1で描画する各ピクセルは、alpha = 0としてブレンドされ、alpha=1のピクセルは同じままになります。

于 2012-06-01T15:48:30.037 に答える