java怎么将一个图像画到一个指定的圆形区域呢? 图一图二上图中图一为原图,现给定素材,需要将图像画城图二然后输出。现在问题是,给定的图像都是矩形,怎么将矩形的图片画到中间的那两个圆里面呢? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 重写 paintComponent(Graphics g)g.setColor(Color.BLACK);g.fillOval(x + 10, y - 10, 10, 10);这花出来的应该是一个黑色球,至于具体的,当然,这感觉比较复杂。。或者你可以定义为矩形的JPanel,但是里面放的图片是带有透明色的圆形,这样是不会遮盖其它的组件的。 现在我这样做,画出来的效果如图 for(int i = 0; i < 100; i++){ //double PI = 3.14159; int dx1,dx2,dy1,dy2; int sx1,sx2,sy1,sy2; double r = 50, x = 0, y = Math.abs(50 - i); x = r * r - y * y; x = Math.sqrt(x); dx1 = (int)(300 - x); sx1 = (int)(50 - x); dx2 = (int)(300 + x); sx2 = (int)(50 + x); dy1 = 100 + i; sy1 = i; dy2 = 100 + i + 1; sy2 = i + 1; targetGraphics.drawImage(srcImage1, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null); } targetGraphics.fillOval(300, 200, 100, 100);就是还是有锯齿。第二个圆形是直接调用fillOval出来的,也会有锯齿,而且这个锯齿还算挺明显的。有没有办法画得更精细些啊? 试了一下,做了个小DEMO链接: http://download.csdn.net/detail/raistlic/5054386 代码很简陋,还是贴出来吧,模糊用了第三方库 jhlabs 的高斯模糊import com.jhlabs.image.GaussianFilter;import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Image;import java.awt.Point;import java.awt.event.MouseEvent;import java.awt.event.MouseMotionAdapter;import java.awt.geom.RoundRectangle2D;import java.awt.image.BufferedImage;import javax.imageio.ImageIO;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.SwingUtilities;/** * * @date 05/02/2013 */public class Demo extends JPanel { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { JFrame f = new JFrame("Test"); f.setContentPane(new Demo()); f.pack(); f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); f.setLocationRelativeTo(null); f.setVisible(true); } }); } private BufferedImage image; private Image small; private Point loc; private int halfScaledSize; Demo() { try { image = ImageIO.read(getClass().getResourceAsStream("koala.jpg")); small = image.getScaledInstance( image.getWidth()/2, image.getHeight()/2, Image.SCALE_SMOOTH); halfScaledSize = small.getWidth(this) / 8; loc = new Point(0, 0); } catch(Exception e) { throw new RuntimeException(e); } setPreferredSize(new Dimension(small.getWidth(this), small.getHeight(this))); addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseMoved(MouseEvent e) { loc.x = e.getX(); loc.y = e.getY(); repaint(); } }); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(small, 0, 0, this); int x = loc.x - halfScaledSize; int y = loc.y - halfScaledSize; int size = halfScaledSize * 2; BufferedImage shadow = getRoundPanel(Color.BLACK, size+10, 10); g.drawImage(shadow, x + 5, y + 5, this); g.drawImage(getRoundPanel(Color.WHITE, size+10, 4), x, y, this); g.drawImage(getRenderedImage(image, loc.x * 2, loc.y * 2, size, 2), x + 5, y + 5, this); } private BufferedImage getRoundPanel(Color c, int size, int blur) { int fix = blur / 2; BufferedImage result = new BufferedImage( size, size, BufferedImage.TYPE_INT_ARGB); Graphics2D g = result.createGraphics(); g.setClip(new RoundRectangle2D.Double( fix, fix, size - blur, size - blur, size - blur, size - blur)); g.setColor(c); g.fillRect(0, 0, result.getWidth(), result.getHeight()); g.dispose(); GaussianFilter filter = new GaussianFilter(blur); result = filter.filter(result, result); return result; } private BufferedImage getRenderedImage( BufferedImage img, int x, int y, int size, int blur) { int fix = blur / 2; BufferedImage result = new BufferedImage( size, size, BufferedImage.TYPE_INT_ARGB); Graphics2D g = result.createGraphics(); g.setClip(new RoundRectangle2D.Double( fix, fix, size-blur, size-blur, size-blur, size-blur)); g.translate(-x, -y); g.drawImage(img, fix, fix, null); size -= blur * 2; GaussianFilter filter = new GaussianFilter( blur * 2 ); result = filter.filter(result, result); g.setClip(new RoundRectangle2D.Double( blur, blur, size - blur * 2, size - blur * 2, size - blur * 2, size - blur * 2)); g.drawImage(img, fix, fix, null); g.dispose(); return result; }} 今天请教了同事,这样模糊边缘是错的……同事说要达到边缘“软化”的效果,不要用clip,根据你要填充的Shape,用合适的 AlphaComposite 来 mask image 。 根据同事所说的思路,在网上找了一下解决方案,更好效果的DEMO在这里:import com.jhlabs.image.GaussianFilter;import java.awt.AlphaComposite;import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Image;import java.awt.Point;import java.awt.Rectangle;import java.awt.RenderingHints;import java.awt.event.MouseEvent;import java.awt.event.MouseMotionAdapter;import java.awt.geom.Area;import java.awt.geom.RoundRectangle2D;import java.awt.image.BufferedImage;import javax.imageio.ImageIO;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.SwingUtilities;/** * * @date 05/02/2013 */public class Demo extends JPanel { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { JFrame f = new JFrame("Test"); f.setContentPane(new Demo()); f.pack(); f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); f.setLocationRelativeTo(null); f.setVisible(true); } }); } private BufferedImage image; private Image small; private Point loc; private int halfScaledSize; Demo() { try { image = ImageIO.read(getClass().getResourceAsStream("koala.jpg")); small = image.getScaledInstance( image.getWidth()/2, image.getHeight()/2, Image.SCALE_SMOOTH); halfScaledSize = small.getWidth(this) / 8; loc = new Point(0, 0); } catch(Exception e) { throw new RuntimeException(e); } setPreferredSize(new Dimension(small.getWidth(this), small.getHeight(this))); addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseMoved(MouseEvent e) { loc.x = e.getX(); loc.y = e.getY(); repaint(); } }); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(small, 0, 0, this); int x = loc.x - halfScaledSize; int y = loc.y - halfScaledSize; int size = halfScaledSize * 2; BufferedImage shadow = getShadow(Color.BLACK, size+6, 6); g.drawImage(shadow, x + 3, y + 3, this); ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setColor(Color.white); g.fillRoundRect(x, y, size + 6, size + 6, size + 6, size + 6); g.drawImage(getRenderedImage(image, loc.x * 2, loc.y * 2, size), x + 3, y + 3, this); } private BufferedImage getShadow(Color c, int size, int blur) { int fix = blur / 2; BufferedImage result = new BufferedImage( size, size, BufferedImage.TYPE_INT_ARGB); Graphics2D g = result.createGraphics(); g.setClip(new RoundRectangle2D.Double( fix, fix, size - blur, size - blur, size - blur, size - blur)); g.setColor(c); g.fillRect(0, 0, result.getWidth(), result.getHeight()); g.dispose(); GaussianFilter filter = new GaussianFilter(blur); result = filter.filter(result, result); return result; } private BufferedImage getRenderedImage( BufferedImage img, int x, int y, int size) { BufferedImage result = new BufferedImage( size, size, BufferedImage.TYPE_INT_ARGB); Graphics2D g = result.createGraphics(); g.translate(-x, -y); g.drawImage(img, 0, 0, null); g.translate(x, y); RoundRectangle2D round = new RoundRectangle2D.Double(0, 0, size, size, size, size); Area clear = new Area(new Rectangle(0, 0, size, size)); clear.subtract(new Area(round)); g.setComposite(AlphaComposite.Clear); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.fill(clear); g.dispose(); return result; }} < Java 2D Trickery: Soft Clipping >http://weblogs.java.net/blog/campbell/archive/2006/07/java_2d_tricker.html" Re: Anti-aliasing in image clipping to non-rectangular sub-images "http://www.velocityreviews.com/forums/t630704-re-anti-aliasing-in-image-clipping-to-non-rectangular-sub-images.html (求助)一个关于JAVA读取数据库的问题 集合问题。。 截串 静态变量和实例变量的区别是什么? 求救! Java中没有类似引用调用的方法吗? 请大家帮忙看看这段copy程序 调用存储过程返回多结果集的问题 java的内存问题 java 如何写日志文件? 关于导入包的问题。 一直困惑着我。 java(simple think in java)
paintComponent(Graphics g)
g.setColor(Color.BLACK);
g.fillOval(x + 10, y - 10, 10, 10);
这花出来的应该是一个黑色球,至于具体的,当然,这感觉比较复杂。。
或者你可以定义为矩形的JPanel,但是里面放的图片是带有透明色的圆形,这样是不会遮盖其它的组件的。
//double PI = 3.14159;
int dx1,dx2,dy1,dy2;
int sx1,sx2,sy1,sy2;
double r = 50, x = 0, y = Math.abs(50 - i);
x = r * r - y * y;
x = Math.sqrt(x);
dx1 = (int)(300 - x);
sx1 = (int)(50 - x);
dx2 = (int)(300 + x);
sx2 = (int)(50 + x);
dy1 = 100 + i;
sy1 = i;
dy2 = 100 + i + 1;
sy2 = i + 1;
targetGraphics.drawImage(srcImage1, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
}
targetGraphics.fillOval(300, 200, 100, 100);
就是还是有锯齿。第二个圆形是直接调用fillOval出来的,也会有锯齿,而且这个锯齿还算挺明显的。有没有办法画得更精细些啊?
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
*
* @date 05/02/2013
*/
public class Demo extends JPanel {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() { @Override
public void run() {
JFrame f = new JFrame("Test");
f.setContentPane(new Demo());
f.pack();
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
private BufferedImage image;
private Image small;
private Point loc;
private int halfScaledSize;
Demo() {
try {
image = ImageIO.read(getClass().getResourceAsStream("koala.jpg"));
small = image.getScaledInstance(
image.getWidth()/2, image.getHeight()/2,
Image.SCALE_SMOOTH);
halfScaledSize = small.getWidth(this) / 8;
loc = new Point(0, 0);
}
catch(Exception e) {
throw new RuntimeException(e);
}
setPreferredSize(new Dimension(small.getWidth(this), small.getHeight(this)));
addMouseMotionListener(new MouseMotionAdapter() { @Override
public void mouseMoved(MouseEvent e) {
loc.x = e.getX();
loc.y = e.getY();
repaint();
}
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(small, 0, 0, this);
int x = loc.x - halfScaledSize;
int y = loc.y - halfScaledSize;
int size = halfScaledSize * 2; BufferedImage shadow = getRoundPanel(Color.BLACK, size+10, 10);
g.drawImage(shadow, x + 5, y + 5, this); g.drawImage(getRoundPanel(Color.WHITE, size+10, 4), x, y, this);
g.drawImage(getRenderedImage(image, loc.x * 2, loc.y * 2, size, 2),
x + 5, y + 5, this);
}
private BufferedImage getRoundPanel(Color c, int size, int blur) {
int fix = blur / 2; BufferedImage result = new BufferedImage(
size, size, BufferedImage.TYPE_INT_ARGB); Graphics2D g = result.createGraphics();
g.setClip(new RoundRectangle2D.Double(
fix, fix, size - blur, size - blur, size - blur, size - blur));
g.setColor(c);
g.fillRect(0, 0, result.getWidth(), result.getHeight());
g.dispose(); GaussianFilter filter = new GaussianFilter(blur);
result = filter.filter(result, result);
return result;
}
private BufferedImage getRenderedImage(
BufferedImage img, int x, int y, int size, int blur) {
int fix = blur / 2;
BufferedImage result = new BufferedImage(
size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
g.setClip(new RoundRectangle2D.Double(
fix, fix, size-blur, size-blur, size-blur, size-blur));
g.translate(-x, -y);
g.drawImage(img, fix, fix, null);
size -= blur * 2;
GaussianFilter filter = new GaussianFilter( blur * 2 );
result = filter.filter(result, result);
g.setClip(new RoundRectangle2D.Double(
blur, blur, size - blur * 2, size - blur * 2, size - blur * 2, size - blur * 2));
g.drawImage(img, fix, fix, null);
g.dispose();
return result;
}
}
今天请教了同事,这样模糊边缘是错的……同事说要达到边缘“软化”的效果,不要用clip,根据你要填充的Shape,用合适的 AlphaComposite 来 mask image 。
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
*
* @date 05/02/2013
*/
public class Demo extends JPanel {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() { @Override
public void run() {
JFrame f = new JFrame("Test");
f.setContentPane(new Demo());
f.pack();
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
private BufferedImage image;
private Image small;
private Point loc;
private int halfScaledSize;
Demo() {
try {
image = ImageIO.read(getClass().getResourceAsStream("koala.jpg"));
small = image.getScaledInstance(
image.getWidth()/2, image.getHeight()/2,
Image.SCALE_SMOOTH);
halfScaledSize = small.getWidth(this) / 8;
loc = new Point(0, 0);
}
catch(Exception e) {
throw new RuntimeException(e);
}
setPreferredSize(new Dimension(small.getWidth(this), small.getHeight(this)));
addMouseMotionListener(new MouseMotionAdapter() { @Override
public void mouseMoved(MouseEvent e) {
loc.x = e.getX();
loc.y = e.getY();
repaint();
}
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(small, 0, 0, this);
int x = loc.x - halfScaledSize;
int y = loc.y - halfScaledSize;
int size = halfScaledSize * 2; BufferedImage shadow = getShadow(Color.BLACK, size+6, 6);
g.drawImage(shadow, x + 3, y + 3, this);
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.white);
g.fillRoundRect(x, y, size + 6, size + 6, size + 6, size + 6);
g.drawImage(getRenderedImage(image, loc.x * 2, loc.y * 2, size),
x + 3, y + 3, this);
}
private BufferedImage getShadow(Color c, int size, int blur) {
int fix = blur / 2; BufferedImage result = new BufferedImage(
size, size, BufferedImage.TYPE_INT_ARGB); Graphics2D g = result.createGraphics();
g.setClip(new RoundRectangle2D.Double(
fix, fix, size - blur, size - blur, size - blur, size - blur));
g.setColor(c);
g.fillRect(0, 0, result.getWidth(), result.getHeight());
g.dispose(); GaussianFilter filter = new GaussianFilter(blur);
result = filter.filter(result, result);
return result;
}
private BufferedImage getRenderedImage(
BufferedImage img, int x, int y, int size) {
BufferedImage result = new BufferedImage(
size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
g.translate(-x, -y);
g.drawImage(img, 0, 0, null);
g.translate(x, y);
RoundRectangle2D round = new RoundRectangle2D.Double(0, 0, size, size, size, size);
Area clear = new Area(new Rectangle(0, 0, size, size));
clear.subtract(new Area(round));
g.setComposite(AlphaComposite.Clear);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.fill(clear);
g.dispose();
return result;
}
}
http://weblogs.java.net/blog/campbell/archive/2006/07/java_2d_tricker.html" Re: Anti-aliasing in image clipping to non-rectangular sub-images "
http://www.velocityreviews.com/forums/t630704-re-anti-aliasing-in-image-clipping-to-non-rectangular-sub-images.html