java怎么将一个图像画到一个指定的圆形区域呢?

ccnyou 2013-02-02 10:52:03
图一



图二



上图中图一为原图,现给定素材,需要将图像画城图二然后输出。现在问题是,
给定的图像都是矩形,怎么将矩形的图片画到中间的那两个圆里面呢?
...全文
1065 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
raistlic 2013-02-06
  • 打赏
  • 举报
回复
raistlic 2013-02-06
  • 打赏
  • 举报
回复
根据同事所说的思路,在网上找了一下解决方案,更好效果的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;
}
}
raistlic 2013-02-06
  • 打赏
  • 举报
回复
引用 13 楼 ccnyou 的回复:
引用 12 楼 raistlic 的回复:代码很简陋,还是贴出来吧,模糊用了第三方库 jhlabs 的高斯模糊 demo已下载,谢谢!
今天请教了同事,这样模糊边缘是错的…… 同事说要达到边缘“软化”的效果,不要用clip,根据你要填充的Shape,用合适的 AlphaComposite 来 mask image 。
ccnyou 2013-02-05
  • 打赏
  • 举报
回复
引用 8 楼 ace62 的回复:
说下思路:先画某个图片(矩形);再画圆;然后将圆外的部分画成别的(覆盖已有的部分图片)
所谓的别的是指?模糊处理?这个肿么处理好点呢?
ace62 2013-02-05
  • 打赏
  • 举报
回复
说下思路:先画某个图片(矩形);再画圆;然后将圆外的部分画成别的(覆盖已有的部分图片)
ccnyou 2013-02-05
  • 打赏
  • 举报
回复
引用 12 楼 raistlic 的回复:
代码很简陋,还是贴出来吧,模糊用了第三方库 jhlabs 的高斯模糊
demo已下载,谢谢!
raistlic 2013-02-05
  • 打赏
  • 举报
回复
代码很简陋,还是贴出来吧,模糊用了第三方库 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;
  }
}
raistlic 2013-02-05
  • 打赏
  • 举报
回复
试了一下,做了个小DEMO



链接: http://download.csdn.net/detail/raistlic/5054386
raistlic 2013-02-05
  • 打赏
  • 举报
回复
引用 6 楼 itfirefly 的回复:
锯齿应该都会存在的,毕竟不死矢量图,比较折中的办法死把圈圈旁边的内容虚化
+1
zqfddqr 2013-02-04
  • 打赏
  • 举报
回复
提高分辨率可以抗锯齿的
望舒 2013-02-02
  • 打赏
  • 举报
回复
锯齿应该都会存在的,毕竟不死矢量图,比较折中的办法死把圈圈旁边的内容虚化
失落夏天 2013-02-02
  • 打赏
  • 举报
回复
重写 paintComponent(Graphics g) g.setColor(Color.BLACK); g.fillOval(x + 10, y - 10, 10, 10); 这花出来的应该是一个黑色球,至于具体的,当然,这感觉比较复杂。。 或者你可以定义为矩形的JPanel,但是里面放的图片是带有透明色的圆形,这样是不会遮盖其它的组件的。
ccnyou 2013-02-02
  • 打赏
  • 举报
回复

画个圆而已,肿么就那么坑捏?有木有好的图形库推荐捏?
yongger520 2013-02-02
  • 打赏
  • 举报
回复
还没整过这么复杂的
ccnyou 2013-02-02
  • 打赏
  • 举报
回复
不好意思,楼上贴错图,这个才对
ccnyou 2013-02-02
  • 打赏
  • 举报
回复
现在我这样做,画出来的效果如图

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出来的,也会有锯齿,而且这个锯齿还算挺明显的。有没有办法画得更精细些啊?

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧