Java中的 GradientPaint 画刷好像仅仅只能支持2色渐变,下面我用动态生成纹理画刷的方式变相实现了一个简单的多色渐变的效果:package test.draw;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.TexturePaint;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* 彩虹纹理画刷
*
* @author h_Davy [dave3068 AT gmail DOT com]
* @version 2007-11-28 上午02:09:46
*/
public class RainbowText extends JPanel
implements Runnable, MouseListener {
private static final long serialVersionUID = 1L;
RainbowText() {
super(true);
init();
}
private void init() {
setBackground(Color.white);
setTextAttributes();
//new Thread(this).start();
addMouseListener(this);
}
private String text = "Rainbow Text";
private Font f;
private TextLayout tl;
private AttributedCharacterIterator aci;
//private FontMetrics fm;
private void setTextAttributes() {
f = new Font("serif",Font.BOLD,60);
//fm = this.getFontMetrics(f);
AttributedString as = new AttributedString(text);
//as.addAttribute(TextAttribute.FONT, f, 0, text.length());
AffineTransform at = new AffineTransform();
//at.setToRotation(Math.toRadians(45));
as.addAttribute(TextAttribute.FONT, f.deriveFont(at), 0, text.length());
aci = as.getIterator();
Color []c = new Color[]
{Color.blue, Color.cyan, Color.green, Color.yellow,
Color.orange, Color.red, Color.magenta};
float []w = new float[]
{.09f, .15f, .16f, .17f, .15f, .16f};
initTextImg(350, c, w, true);
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(2.f));
// draw background
g2.setColor(getBackground());
g2.fillRect(0, 0, getWidth(), getHeight());
g2.setColor(Color.blue);
g2.drawRoundRect(5, 5, getWidth()-10, getHeight()-10, 10, 10);
//
g2.setStroke(new BasicStroke(1.5f));
FontRenderContext frc = g2.getFontRenderContext();
//tl = new TextLayout(text, f, frc);
tl = new TextLayout(aci, frc);
Rectangle2D rect = tl.getBounds();
int x = getWidth()/2 - (int)rect.getWidth()/2,
y = getHeight()/2 + (int)rect.getHeight()/2;
g2.translate(x, y);
//g2.rotate(Math.toRadians(-45));
//g2.setColor(Color.yellow);
//g2.fill(rect);
g2.setPaint(new TexturePaint(bi, rect));
g2.setComposite(AlphaComposite.SrcOver);
//g2.rotate(Math.toRadians(30));
tl.draw(g2, 0, 0);
//AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f);
//g2.setComposite(ac);
W = (int)rect.getWidth();
rect = new Rectangle2D.Float(X, 0, W, 1);
g2.setPaint(new TexturePaint(bi, rect));
R.setRect(-x+10, y, getWidth()-20, 20);
g2.fillRect(R.x, 10, R.width, 20);
}
private boolean run = false;
private int X = 0;
private int W = 0;
private static Rectangle R = new Rectangle();
public void run() {
try {
while (run) {
Thread.sleep(10);
X+=1;
if (X>=W) X = 0;
//repaint();
repaint(10, R.y+10, R.width, R.height);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void mouseClicked(MouseEvent e) {
run = !run;
new Thread(this).start();
}
// 纹理
private BufferedImage bi;
/**
* 初始化纹理
*
* @param width 纹理总宽度
* @param c 颜色值数组
* @param w 各色带宽度所占百分比(w.length=c.length-1)
* @param cyclic 是否循环
*/
private void initTextImg(int width, Color []c, float w[], boolean cyclic) {
bi = new BufferedImage(width, 1, BufferedImage.TYPE_4BYTE_ABGR);
int n = c.length;
int m = cyclic ? n : n - 1;
// initialize widths
float []ww = new float[m];
float s = 0;
int i;
for (i = 0; i < m-1; i++) {
s += w[i];
if (s>=1) {
break; // 以防输入的百分比过大时产生的异常
} else {
ww[i] = w[i];
}
}
if (i<(m-1)) { // 若输入的百分比过大将剩下的均分
float t = (1-s+w[i])/(m-i);
for (; i<m; i++) {
ww[i] = t;
}
} else { // 将剩下的分配给最后一个色块
ww[m-1] = 1 - s;
}
// initialize colors
int []rgbs = new int[n];
for (i = 0; i < n; i++)
rgbs[i] = c[i].getRGB();
// the color's divides
int a[] = new int[n];
int r[] = new int[n];
int g[] = new int[n];
int b[] = new int[n];
// initialize the color's divides
for (i = 0; i < n; i++) {
a[i] = (rgbs[i] >> 24) & 0xff;
r[i] = (rgbs[i] >> 16) & 0xff;
g[i] = (rgbs[i] >> 8) & 0xff;
b[i] = (rgbs[i] ) & 0xff;
}
// tail of color's divides (if you wana cyclic)
int ta = ((rgbs[n-1] >> 24) & 0xff) - a[0];
int tr = ((rgbs[n-1] >> 16) & 0xff) - r[0];
int tg = ((rgbs[n-1] >> 8) & 0xff) - g[0];
int tb = ((rgbs[n-1] ) & 0xff) - b[0];
// 用于存储平滑过渡的各颜色值
int []interp = new int[cyclic ? n*256+1 : (n-1)*256+1];
// 颜色线性平滑插值
for (i = 0; i <= 256; i++) {
float rel = i / 256.0f;
int rgb;
for (int j=0; j<n-1; j++) {
rgb =
(((int) (a[j] + (a[j+1]-a[j]) * rel)) << 24) |
(((int) (r[j] + (r[j+1]-r[j]) * rel)) << 16) |
(((int) (g[j] + (g[j+1]-g[j]) * rel)) << 8) |
(((int) (b[j] + (b[j+1]-b[j]) * rel)) );
interp[i+256*j] = rgb;
}
if (cyclic) {
rgb =
(((int) (a[0] + ta * rel)) << 24) |
(((int) (r[0] + tr * rel)) << 16) |
(((int) (g[0] + tg * rel)) << 8) |
(((int) (b[0] + tb * rel)) );
interp[n*256-i] = rgb;
}
}
// fill the image
/*float rt = (float)interp.length / width;
for (i=0; i<width; i++) {
bi.setRGB(i, 0, interp[(int)(i*rt)]);
}*/
int cur = 0;
for (i=0; i<m; i++) {
int wi = (int) (width*ww[i]);
if (i==(m-1)) wi = width-cur;
//System.out.print(wi+",");
float rt = (float)256 / wi;
for (int j=0; j<wi; j++) {
bi.setRGB(cur+j, 0, interp[(int)(j*rt)+i*256]);
}
cur += wi;
}
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
/**
* @param args
*/
public static void main(String[] args) {
JFrame f = new JFrame("");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(640, 480);
f.setLocationRelativeTo(null);
f.add(new RainbowText());
f.setVisible(true);
}
}
//EOF
2007-12-03
Java2D 3 or more Colors gradient paint (use TexturePaint)
Posted by Davy Hawk at 12/03/2007 10:59:00 AM
Subscribe to:
Post Comments (Atom)
0 comments:
Post a Comment