【问题标题】:Cursor with Semi-Transparency / Anti-Aliasing半透明/抗锯齿光标
【发布时间】:2011-11-29 12:00:42
【问题描述】:

我正在尝试使用以下代码创建自定义光标:

BufferedImage cursor = new BufferedImage(30, 30, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) cursor.getGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.BLACK);
g.drawOval(0, 0, 26, 26);
jframe.getContentPane().setCursor(Toolkit.getDefaultToolkit().createCustomCursor(
    cursor, new Point(13, 13), "cursor"));

如果没有抗锯齿,这看起来真的很糟糕,但是一旦我尝试激活抗锯齿,应该是半透明的像素似乎变得完全实心 - 好像 JFrame 光标无法处理半透明。

我尝试从.png 文件加载BufferedImage,但结果相同。

我不想在画布上手动绘制光标,因为与此方法相比,它有轻微的输入延迟

我想要做的就是拥有一个可以支持半透明的光标。 关于如何实现这一目标的任何想法?

提前致谢。

【问题讨论】:

    标签: java eclipse


    【解决方案1】:

    这个很微妙(我已经被困了几年:)但我今天已经破解了。

    光标似乎只支持打开/关闭透明度,因此首先绘制到 TYPE_INT_RGB 图像,然后将其复制到 TYPE_INT_ARGB(然后修复透明度)即可。

    不确定它是否是最佳的,但对于像这样的小图像来说,这并不重要。

            int size = 32;
    
            /*
             * we need two buffered images as the cursor only supports on/off for alpha
             * 
             * so we need to draw to an image without alpha support
             * then draw that to one with alpha support
             * then make "white" transparent
             */
            BufferedImage image = new BufferedImage(size, size,
                    BufferedImage.TYPE_INT_RGB);
            BufferedImage image2 = new BufferedImage(size, size,
                    BufferedImage.TYPE_INT_ARGB);
    
            Graphics2D g = image.createGraphics();
            Graphics2D g2 = image2.createGraphics();
    
            g.setColor(Color.white);
            g.fillRect(0, 0, size, size);
    
    
            // turn on anti-aliasing.
            g.setStroke(new BasicStroke(4.0f)); // 4-pixel lines
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
                RenderingHints.VALUE_ANTIALIAS_ON);
    
            g.setColor(new Color(0.5f, 0f, 0f));
            g.drawOval(3, 3, size-7, size-7);
    
            g2.drawImage(image,  0, 0, null, null);
    
    
            for (int y = 0 ; y < size ; y++) {
                for (int x = 0 ; x < size ; x++) {
    
                    int rgb = image.getRGB(x, y);
    
                    int blue = rgb & 0xff;
                    int green = (rgb & 0xff00) >> 8;
                    int red = (rgb & 0xff0000) >> 16;
                    //int alpha = (rgb & 0xff000000) >> 24;
    
                    if (red == 255 && green == 255 && blue == 255) {
                        // make white transparent
                        image2.setRGB(x, y, 0);
                    }
    
                }
            }
    
            eraserCursor = Toolkit.getDefaultToolkit().createCustomCursor(
                    image2, new Point(size / 2, size / 2), "eraserCursor");
    

    【讨论】:

      【解决方案2】:

      在我的代码中,为了实现半透明图像,我使用了这个sn-p:

      g.setComposite(AlphaComposite.SrcOver.derive(0.8f));
      g.drawImage(image, 0, 0, null);
      g.setComposite(AlphaComposite.SrcOver);
      

      看看它是否适合你...

      【讨论】:

        猜你喜欢
        • 2010-11-20
        • 1970-01-01
        • 1970-01-01
        • 2014-02-18
        • 2015-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-22
        相关资源
        最近更新 更多