Java实现窗体中角色逐渐风化效果

简介:
效果图如下:
 

源码:
AirslakeImage.java
package  org.test;

import  java.awt.Button;
import  java.awt.Color;
import  java.awt.Frame;
import  java.awt.Graphics;
import  java.awt.Image;
import  java.awt.Panel;
import  java.awt.event.ActionEvent;
import  java.awt.event.ActionListener;
import  java.awt.event.WindowAdapter;
import  java.awt.event.WindowEvent;
import  java.awt.image.PixelGrabber;
import  java.util.Random;

import  org.loon.framework.game.image.Bitmap;
import  org.loon.framework.game.image.LColor;
/**
 * <p>Title: LoonFramework</p>
 * <p>Description:java实现图片风化效果</p>
 * <p>Copyright: Copyright (c) 2007</p>
 * <p>Company: LoonFramework</p>
 * 
@author chenpeng  
 * @email:[email]ceponline@yahoo.com.cn[/email] 
 * 
@version 0.1
 
*/

public   class  AirslakeImage  extends  Panel  implements  Runnable, ActionListener  {

    
/**
     * 
     
*/

    
private static final long serialVersionUID = 1L;
    
    
static final public int _WIDTH = 400;
    
    
static final public int _HEIGHT = 400;
    
    
private boolean _isRun=false;

    
private Image _img;
    
    
private Image _screen;
    
    
private Graphics _back;

    
private int _imgWidth;
    
private int _imgHeight;

    
private Fraction[] _fractions;

    
private Thread _timer;

    
private Button _meganteButton;
    
private Button _revivalButton;


    
private Random _rand = new Random();

    
public AirslakeImage() {
        
        _screen
=new Bitmap(_WIDTH,_HEIGHT).getImage();
        
        _back
=_screen.getGraphics();
        
        setSize(_WIDTH, _HEIGHT);

        _meganteButton 
= new Button("破碎图片");
        _meganteButton.addActionListener(
this);
        add(_meganteButton);

        _revivalButton 
= new Button("还原图片");
        _revivalButton.addActionListener(
this);
        add(_revivalButton);
        _revivalButton.setEnabled(
false);

        loadImage(
"role.png");

        init(_img);
    }

    
    
/**
     * 初始化image图像,分解其中像素
     * 
@param _img
     
*/

    
private void init(Image _img) {
        
if (_timer != null{
            _timer
=null;
            _isRun
=false;
        }

        _fractions 
= new Fraction[_imgWidth * _imgHeight];
        PixelGrabber pg 
= new PixelGrabber(_img, 00, _imgWidth, _imgHeight, true);
        
try {
            pg.grabPixels();
        }
 catch (InterruptedException e) {
            e.printStackTrace();
        }

        
int pixel[] = (int[]) pg.getPixels();
     
        
//重新封装像素
        for (int y = 0; y < _imgHeight; y++{
            
for (int x = 0; x < _imgWidth; x++{
                
int n = y * _imgWidth + x;
                _fractions[n] 
= new Fraction();
                
double angle = _rand.nextInt(360);
                
double speed = 10.0 / _rand.nextInt(30);
                _fractions[n].x 
=   x+90;
                _fractions[n].y 
=   y+20;
                _fractions[n].vx 
= Math.cos(angle * Math.PI / 180* speed;
                _fractions[n].vy 
= Math.sin(angle * Math.PI / 180* speed;
                _fractions[n].color 
= pixel[n];
                _fractions[n].countToCrush 
= x / 6 + _rand.nextInt(10);
            }

        }

    }

    
    
public void update(Graphics g){
        paint(g);
    }

    
    
public void paint(Graphics g){
        
//变更背景色
        _back.setColor(Color.WHITE);
        
//清空背景
        _back.fillRect(00, _WIDTH, _HEIGHT);

        
for (int n = 0; n < _imgWidth * _imgHeight; n++{
            
int x = (int) _fractions[n].x;
            
int y = (int) _fractions[n].y;
            LColor color
=LColor.getLColor(_fractions[n].color);
            
//纯黑色区域不读取
            if(!LColor.equals(color, LColor.fromArgb(0,0,0))){
            
//获得rgb三色
            int red = color.R;
            
int green = color.G;
            
int blue = color.B;
            _back.setColor(
new Color(red, green, blue));
            
//绘制
            _back.drawLine(x, y, x, y);
            }

        }

        g.drawImage(_screen, 
00this);
    }


    
public void actionPerformed(ActionEvent e) {
        
if (e.getSource() == _meganteButton) {
            execute();
            _meganteButton.setEnabled(
false);
            _revivalButton.setEnabled(
true);
        }
 else if (e.getSource() == _revivalButton) {
            init(_img);
            repaint();
            _meganteButton.setEnabled(
true);
            _revivalButton.setEnabled(
false);
        }

    }




    
/**
     * 加载图像
     * 
@param filename
     
*/

    
private void loadImage(String filename) {
        Bitmap bitmap 
= new Bitmap(("./image/"+filename).intern());
        
//替换透明区域颜色(象素化后,转为rgb形式的透明区域色值将显示为r=0,g=0,b=0),可以直接用pixel识别透明区域,也可以替换或跳过该区域)
        _img=bitmap.getImage();
        _imgWidth 
= _img.getWidth(this);
        _imgHeight 
= _img.getHeight(this);
    }



  
    
/**
     * 执行操作
     *
     
*/

    
private void execute() {
        _timer 
= new Thread(this);
        _timer.start();
        _isRun
=true;
    }

    
    
class Fraction {
        
//图片在窗体中x
        public double x;
        
//图片在窗体中y
        public double y;
        
//显示图x
        public double vx;
        
//显示图y
        public double vy;
        
//color
        public int color; 
        
//变形颗粒数量
        public int countToCrush; 
    }

    
        
public void run() {
            
while(_isRun){
            
for (int n = 0; n < _imgWidth * _imgHeight; n++{
                
if (_fractions[n].countToCrush <= 0
                    _fractions[n].x 
+= _fractions[n].vx;
                    _fractions[n].y 
+= _fractions[n].vy;
                    _fractions[n].vy 
+= 0.1
                }
 else {
                    _fractions[n].countToCrush
--;
                }

             
            }

            
//间隔
            try {
                Thread.sleep(
60);
            }
 catch (InterruptedException e) {
                e.printStackTrace();
            }

            repaint();
            }

        }

    
    
    
public static void main(String[]args){
        java.awt.EventQueue.invokeLater(
new Runnable() {
            
public void run() {
                Frame frm 
= new Frame("java实现图片风化效果");
                frm.add(
new AirslakeImage());
                frm.setResizable(
false);
                frm.setSize(_WIDTH, _HEIGHT);
                frm.addWindowListener(
new WindowAdapter(){
                    
public void windowClosing(WindowEvent e){
                        System.exit(
0);
                    }

                }
);
                frm.setLocationRelativeTo(
null);
                frm.setVisible(
true);
            }

        }
);
    }

}





本文转自 cping 51CTO博客,原文链接:http://blog.51cto.com/cping1982/130055
相关文章
|
5月前
|
Java Maven
使用java语言制作一个窗体(弹窗),用来收集用户输入的内容
该博客文章介绍了如何使用Java Swing中的JFrame创建一个窗体来收集用户输入的内容,并提供了详细的实现步骤和完整代码示例。
使用java语言制作一个窗体(弹窗),用来收集用户输入的内容
|
2月前
|
Java 开发者
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
54 4
|
3月前
|
Java 开发者
在 Java 多线程编程中,Lock 接口正逐渐取代传统的 `synchronized` 关键字,成为高手们的首选
【10月更文挑战第6天】在 Java 多线程编程中,Lock 接口正逐渐取代传统的 `synchronized` 关键字,成为高手们的首选。相比 `synchronized`,Lock 提供了更灵活强大的线程同步机制,包括可中断等待、超时等待、重入锁及读写锁等高级特性,极大提升了多线程应用的性能和可靠性。通过示例对比,可以看出 Lock 接口通过 `lock()` 和 `unlock()` 明确管理锁的获取和释放,避免死锁风险,并支持公平锁选择和条件变量,使其在高并发场景下更具优势。掌握 Lock 接口将助力开发者构建更高效、可靠的多线程应用。
38 2
|
5月前
|
Java 开发者
在 Java 多线程编程中,Lock 接口正逐渐取代传统的 `synchronized` 关键字,成为高手们的首选
在 Java 多线程编程中,Lock 接口正逐渐取代传统的 `synchronized` 关键字,成为高手们的首选。相比 `synchronized`,Lock 提供了更灵活强大的线程同步机制,包括可中断等待、超时等待、重入锁及读写锁等高级特性,极大提升了多线程应用的性能和可靠性。通过示例对比,可以看出 Lock 接口通过 `lock()` 和 `unlock()` 明确管理锁的获取和释放,避免死锁风险,并支持公平锁选择和条件变量,使其在高并发场景下更具优势。掌握 Lock 接口将助力开发者构建更高效、可靠的多线程应用。
34 2
|
7月前
|
Java 数据库连接 数据库
深入探索:Java连接池在数据库性能优化中的角色
【6月更文挑战第24天】Java应用中,数据库连接池如HikariCP提升性能,减少资源消耗。连接池预创建并管理连接,避免频繁创建/关闭。工作流程:申请连接→池中取或新建→使用后归还给池。示例展示了如何配置及使用HikariCP连接池,强调了其在高并发环境中的重要性。选择合适连接池并优化配置对系统性能至关重要。
65 1
|
6月前
|
存储 安全 Java
Java集合篇之逐渐被遗忘的Stack,手写一个栈你会吗?
总之,虽然在日常开发中,`java.util.Stack`正逐渐被其他类如 `Deque`接口的实现所取代,但手写一个栈(无论是基于数组还是链表)都是一次很好的编程练习,它可以帮助开发者更加深入地理解栈这种数据结构的工作原理和各种操作。
50 0
|
6月前
|
存储 算法 Java
Java面试题:解释JVM的内存结构,并描述堆、栈、方法区在内存结构中的角色和作用,Java中的多线程是如何实现的,Java垃圾回收机制的基本原理,并讨论常见的垃圾回收算法
Java面试题:解释JVM的内存结构,并描述堆、栈、方法区在内存结构中的角色和作用,Java中的多线程是如何实现的,Java垃圾回收机制的基本原理,并讨论常见的垃圾回收算法
92 0
|
8月前
|
Java 开发者
在Java中,接口和超类在多态性中扮演着重要的角色
【5月更文挑战第7天】Java中的接口和超类支持多态性,接口作为规范,允许多继承和回调机制;超类提供基类,实现代码重用和方法重写,两者共同促进代码的灵活性和可维护性。
58 10
|
8月前
|
存储 算法 安全
Java集合篇之逐渐被遗忘的Stack,手写一个栈你会吗?
Java集合篇之逐渐被遗忘的Stack,手写一个栈你会吗?
55 0
|
8月前
|
Cloud Native Java 云计算
Java在云计算时代的新角色及挑战
【2月更文挑战第11天】 随着云计算技术的迅猛发展,Java作为一种历史悠久的编程语言,在新的技术环境下面临着前所未有的机遇与挑战。本文将深入探讨Java在云计算时代的新角色,分析其在云原生应用开发、微服务架构、容器化技术等方面的应用,并针对Java在性能优化、安全性提升、跨平台能力等方面面临的挑战提出切实可行的解决策略。通过对Java未来发展方向的展望,旨在为Java开发者在云计算时代的转型提供指导和启示。
155 6