一个“叠加”错觉......
基本上这将根据当前鼠标位置和视口大小生成未模糊图像的subImage,然后将其与“叠加效果”混合并渲染在模糊图像之上,创建“错觉” ”的抠图效果。
以下示例将跟随鼠标移动,在鼠标光标周围显示图像的 200x200 像素区域。
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RadialGradientPaint;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
public class TestPane extends JPanel {
private BufferedImage blurredImage;
private BufferedImage normalImage;
private BufferedImage spyScopeImage;
private int viewPortSize = 200;
private Point currentLocation;
public TestPane() throws IOException {
blurredImage = ImageIO.read(getClass().getResource("/images/PosterBlurred.png"));
normalImage = ImageIO.read(getClass().getResource("/images/Poster.png"));
spyScopeImage = new BufferedImage(viewPortSize, viewPortSize, BufferedImage.TYPE_INT_ARGB);
Graphics2D masked = spyScopeImage.createGraphics();
Color transparent = new Color(255, 0, 0, 0);
Color fill = Color.RED;
RadialGradientPaint rgp = new RadialGradientPaint(
new Point2D.Double(viewPortSize / 2d, viewPortSize / 2d),
viewPortSize,
new float[]{0f, 0.5f, 1f},
new Color[]{fill, transparent, transparent});
// masked.setComposite(AlphaComposite.DstAtop);
masked.setPaint(rgp);
masked.fill(new Rectangle(0, 0, viewPortSize, viewPortSize));
masked.dispose();
MouseAdapter mouseAdapter = new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
currentLocation = e.getPoint();
repaint();
}
@Override
public void mouseEntered(MouseEvent e) {
currentLocation = e.getPoint();
repaint();
}
@Override
public void mouseExited(MouseEvent e) {
currentLocation = null;
repaint();
}
};
addMouseMotionListener(mouseAdapter);
}
@Override
public Dimension getPreferredSize() {
if (blurredImage != null) {
return new Dimension(blurredImage.getWidth(), blurredImage.getHeight());
}
return new Dimension(800, 600);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (blurredImage != null) {
int x = (getWidth() - blurredImage.getWidth()) / 2;
int y = (getHeight() - blurredImage.getHeight()) / 2;
g2d.drawImage(blurredImage, x, y, this);
if (currentLocation != null && normalImage != null) {
int mouseX = currentLocation.x - x;
int mouseY = currentLocation.y - y;
int viewPortOffset = viewPortSize / 2;
int minX = Math.max(0, mouseX - viewPortOffset);
int minY = Math.max(0, mouseY - viewPortOffset);
int maxX = Math.min(normalImage.getWidth(), mouseX + viewPortSize);
int maxY = Math.min(normalImage.getHeight(), mouseY + viewPortSize);
int viewX = minX - viewPortOffset;
int viewY = minY - viewPortOffset;
BufferedImage subimage = normalImage.getSubimage(minX, minY, maxX - minX, maxY - minY);
// Here we're going to "mask" the sub image and the "spy scope" effect together
BufferedImage masked = new BufferedImage(viewPortSize, viewPortSize, BufferedImage.TYPE_INT_ARGB);
Graphics2D mg = masked.createGraphics();
mg.drawImage(subimage, 0, 0, this);
mg.setComposite(AlphaComposite.DstAtop);
mg.drawImage(spyScopeImage, 0, 0, this);
mg.dispose();
g2d.drawImage(masked, x + minX, y + minY, this);
}
}
g2d.dispose();
}
}
}
或者...
您可以使用“范围效果”创建模糊图像的“蒙版”版本,该版本会暴露在其下方渲染的图像,但是同样,这会很昂贵,因为每次您创建原始模糊大小的新图像时图像。
这个概念在How to create a transparent shape in the image中得到了证明