java composite_如何有效地实现java.awt.Composite?

背景:我需要能够以“禁用”外观创建图像.通常建议的方法是将图像转换为灰度并显示灰度图像.缺点是它只适用于图像,因此显示图形很麻烦,因为您无法立即访问处于禁用状态的图像.

现在我认为这可以使用java.awt.Composite动态完成(然后我不需要知道如何实现一个Icon来禁用它).似乎没有实现转换为灰度,所以我必须创建自己的……

也就是说,我一起攻击了一个实现(它呈现了我所期望的).但我不确定它是否真的适用于所有情况(复合/ CompositeContext的Javadocs对于这种复杂的操作看起来非常薄).正如你可以从我的实现中看到的那样,我采用了一种迂回的方式来逐像素处理,因为似乎没有简单的方法来批量读取/写入像素,而这种格式并不是由所涉及的栅格决定的.

欢迎任何指向更广泛的文档/示例/提示的指针.

这是SSCCE – 它通过DisabledComposite渲染(彩色)GradientPaint,将渐变转换为灰度.请注意,在现实世界中,您将无法知道通过哪些调用呈现的内容. Gradient实际上只是一个例子(抱歉,但是人们常常没有这样做,所以这次我会明确说明).

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Composite;

import java.awt.CompositeContext;

import java.awt.Dimension;

import java.awt.GradientPaint;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.image.ColorModel;

import java.awt.image.Raster;

import java.awt.image.WritableRaster;

import javax.swing.JComponent;

import javax.swing.JFrame;

import javax.swing.SwingUtilities;

public class CompositeSSCE implements Runnable {

static class DisabledComposite implements Composite {

@Override

public CompositeContext createContext(

final ColorModel srcColorModel,

final ColorModel dstColorModel,

final RenderingHints hints) {

return new DisabledCompositeContext(srcColorModel, dstColorModel);

}

}

static class DisabledCompositeContext implements CompositeContext {

private final ColorModel srcCM;

private final ColorModel dstCM;

final static int PRECBITS = 22;

final static int WEIGHT_R = (int) ((1 << PRECBITS) * 0.299);

final static int WEIGHT_G = (int) ((1 << PRECBITS) * 0.578);

final static int WEIGHT_B = (int) ((1 << PRECBITS) * 0.114);

final static int SRCALPHA = (int) ((1 << PRECBITS) * 0.667);

DisabledCompositeContext(final ColorModel srcCM, final ColorModel dstCM) {

this.srcCM = srcCM;

this.dstCM = dstCM;

}

public void compose(final Raster src, final Raster dstIn, final WritableRaster dstOut) {

final int w = Math.min(src.getWidth(), dstIn.getWidth());

final int h = Math.min(src.getHeight(), dstIn.getHeight());

for (int y = 0; y < h; ++y) {

for (int x = 0; x < w; ++x) {

int rgb1 = srcCM.getRGB(src.getDataElements(x, y, null));

int a1 = ((rgb1 >>> 24) * SRCALPHA) >> PRECBITS;

int gray = (

((rgb1 >> 16) & 0xFF) * WEIGHT_R +

((rgb1 >> 8) & 0xFF) * WEIGHT_G +

((rgb1 ) & 0xFF) * WEIGHT_B

) >> PRECBITS;

int rgb2 = dstCM.getRGB(dstIn.getDataElements(x, y, null));

int a2 = rgb2 >>> 24;

int r2 = (rgb2 >> 16) & 0xFF;

int g2 = (rgb2 >> 8) & 0xFF;

int b2 = (rgb2 ) & 0xFF;

// mix the two pixels

gray = gray * a1 / 255;

final int ta = a2 * (255 - a1);

r2 = gray + (r2 * ta / (255*255));

g2 = gray + (g2 * ta / (255*255));

b2 = gray + (b2 * ta / (255*255));

a2 = a1 + (ta / 255);

rgb2 = (a2 << 24) | (r2 << 16) | (g2 << 8) | b2;

Object data = dstCM.getDataElements(rgb2, null);

dstOut.setDataElements(x, y, data);

}

}

}

@Override

public void dispose() {

// nothing for this implementation

}

}

// from here on out its only the fluff to make this a runnable example

public static void main(String[] argv) {

Runnable r = new CompositeSSCE();

SwingUtilities.invokeLater(r);

}

// simple component to use composite to render

static class DemoComponent extends JComponent {

// demonstrate rendering an icon in grayscale with the composite

protected void paintComponent(Graphics g) {

Graphics2D g2d = (Graphics2D) g;

GradientPaint p = new GradientPaint(0, 0, Color.GREEN, 127, 127, Color.BLUE, true);

g2d.setComposite(new DisabledComposite());

g2d.setPaint(p);

g2d.fillRect(0, 0, getWidth(), getHeight());

}

}

// Fluff to use the Composite in Swing

public void run() {

try {

JFrame f = new JFrame("Test grayscale composite");

DemoComponent c = new DemoComponent();

c.setPreferredSize(new Dimension(500, 300));

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.setLayout(new BorderLayout());

f.add(c, BorderLayout.CENTER);

f.pack();

f.setVisible(true);

} catch (Exception e) {

throw new RuntimeException(e);

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值