java水泡_JAVA图像处理系列(八)——艺术效果:水泡

艺术效果水泡

通过对图像进行变形或叠加其他图片,能够实现许多有趣的艺术效果,本文介绍类似水泡效果的实现方式,下面先看一下实现的效果。

第一张为原始图像,第二张为叠加水泡效果的图像。

211c7f7a62b3

cat.jpg

211c7f7a62b3

cat_belb.jpg

算法原理

图像中的水泡效果,是由两个算法叠加而成。第一个为计算水泡上反射光照的效果,第二个为图像通过水泡折射后的形变计算。

(1)光照效果实现

通过设定光源的位置,及水泡上个点与光源的位置关系进行计算,下面是实现代码:

public static void upLightPoint(BufferedImage image, int x, int y, double scale, double hall) {

Pixel pixel = new Pixel();

if (scale > 1)

scale = 1;

else if (scale < 0) {

if (hall == 0) {

scale = 0;

} else {

scale = scale / hall;

}

}

pixel.setRGB(image.getRGB(x, y));

if (scale >= 0) {

pixel.red = pixel.red + (int) ((255 - pixel.red) * scale);

pixel.green = pixel.green + (int) ((255 - pixel.green) * scale);

pixel.blue = pixel.blue + (int) ((255 - pixel.blue) * scale);

} else {

pixel.red = pixel.red + (int) (pixel.red * scale);

pixel.green = pixel.green + (int) (pixel.green * scale);

pixel.blue = pixel.blue + (int) (pixel.blue * scale);

}

image.setRGB(x, y, pixel.getRGB());

}

public static void drawBall(BufferedImage bimg, int x_center, int y_center, int radius, int x_lamp, int y_lamp) {

double z, z_lamp;

double distance;

for (int y = y_center - radius; y < y_center + radius; y++) {

for (int x = x_center - radius; x < x_center + radius; x++) {

distance = (x - x_center) * (x - x_center) + (y - y_center) * (y - y_center);

if (distance > radius * radius)

continue;

z = Math.sqrt(radius * radius - distance);

z_lamp = Math.sqrt(radius * radius - (x_lamp - x_center) * (x_lamp - x_center)

- (y_lamp - y_center) * (y_lamp - y_center));

distance = Math.sqrt(radius * radius * 2 - 2 * (x - x_center) * (x_lamp - x_center)

- 2 * (y - y_center) * (y_lamp - y_center) - 2 * z * z_lamp);

try {

upLightPoint(bimg, x, y, (1 - distance / radius / .5), 0);

} catch (Exception e) {

}

}

}

}

(2)折射效果实现

通过背景图像图水泡中心的位置关系,计算简单的折射效果,代码如下:

public static void belbImage(BufferedImage image, BufferedImage bimg, int x_center, int y_center, int radius) {

double scale = radius * Math.PI / 2;

double x1 = 0;

double y1 = 0;

for (int y = y_center - radius; y < y_center + radius; y++) {

for (int x = x_center - radius; x < x_center + radius; x++) {

double distance = Math.sqrt((x - x_center) * (x - x_center) + (y - y_center) * (y - y_center));

if (distance > radius)

continue;

double hu = Math.asin(distance / radius);

double v = hu * scale * 4.14 / 180.0;

x1 = x_center + (x - x_center) * v;

y1 = y_center + (y - y_center) * v;

try {

if (x1 > image.getWidth())

x1 = image.getWidth() * 2 - x1;

else if (x1 < 0)

x1 = -x1;

if (y1 > image.getHeight())

y1 = image.getHeight() * 2 - y1;

else if (y1 < 0)

y1 = -y1;

bimg.setRGB(x, y, image.getRGB((int) x1, (int) y1));

} catch (Exception e) {

}

}

}

}

(3)两种效果的叠加

将两种效果进行叠加,就产生了水泡的效果,叠加代码如下:

public static BufferedImage drawBallImage(BufferedImage image, int x, int y, int radius) {

BufferedImage bimg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);

Graphics2D g2 = bimg.createGraphics();

g2.drawImage(image, 0, 0, null);

int r = radius, x_lamp, y_lamp;

x_lamp = x - (int) (r / 2.0);

y_lamp = y - (int) (r / 2.0);

belbImage(image, bimg, x, y, r);

drawBall(bimg, x, y, r, x_lamp, y_lamp);

g2 = bimg.createGraphics();

g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.0f));

g2.drawImage(image, 0, 0, null);

g2.dispose();

return bimg;

}

代码中使用到的辅助类Pixel代码如下:

import java.awt.image.*;

public class Pixel {

public int red;

public int green;

public int blue;

public int alpha=0xFF;

public double hue;

public double saturation;

public double luminosity;

private int rgb;

public Pixel() {

}

public void setRGB(int rgb) {

red = (rgb & 0x00FF0000) / 0x00010000;

green = (rgb & 0x0000FF00) / 0x00000100;

blue = rgb & 0x000000FF;

alpha = (rgb >> 24)&0x0ff;

this.rgb = rgb;

}

public int getRGB() {

rgb = alpha<<24 | 0x00010000 * red | 0x00000100 * green | blue;

return this.rgb;

}

public static void setRgb(BufferedImage image, int x, int y, int red, int green, int blue) {

int rgb = 0xFF000000 | red * 0x00010000 | green * 0x00000100 | blue;

image.setRGB(x, y, rgb);

}

public static int pixelIntensity(int rgb) {

int red = (rgb&0x00FF0000)/0x00010000;

int green = (rgb&0x0000FF00)/0x00000100;

int blue = rgb&0x000000FF;

return (int) (0.299 * red + 0.587 * green + 0.114 * blue + 0.5);

}

}

测试代码

本文上的效果图片使用了下面的测试代码:

public static void main(String[] argv) throws IOException {

BufferedImage img = read(new File("cat.jpg"));

BufferedImage img2 =drawBallImage(img, 100, 300, 80);

ImageIO.write(img2, "jpeg", new File("cat_belb.jpg"));

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/555006.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java读word_java读word文件(示例代码)

Apache POI是Apache软件基金会的开放源码函式库&#xff0c;POI提供API给Java程序对Microsoft Office格式档案读和写的功能。1.读取word 2003及word 2007需要的jar包读取 2003 版本(.doc)的word文件相对来说比较简单&#xff0c;只需要 poi-3.5-beta6-20090622.jar 和 poi-scra…

Dubbo调用远程服务详解_导入jar方式

Dubbo调用远程服务 1.创建公共接口模块api 公共接口主要用于存放接口对象,这里我们只创建一个服务层的接口IndexService用于远程调用服务的测试 package com.example.dubboapi.service;public interface IndexService {String echo(); }

Dubbo SpringBoot+Dubbo泛化的使用,以及开发时直连本地的Dubbo服务(Dubbo指定点对点调用服务)

​ 一般情况我们使用dubbo)通过rpc调用dubbo提供方的服务&#xff0c;首先要在消费者的项目中引入接口提供者的jar包&#xff08;provider端暴露的接口和方法&#xff09;&#xff0c;然后使用jar包里面的类和方法&#xff0c;两端才能正常通信调用。但是如果要调N个不同服务提…

java string... 参数_Java String.Format() 方法及参数说明

JDK1.5中&#xff0c;String类新增了一个很有用的静态方法String.format():format(Locale l, String format, Object... args) 使用指定的语言环境、格式字符串和参数返回一个格式化字符串。format(String format, Object... args) 使用指定的格式字符串和参数返回一个格式化字…

Unity3D VS UE4

Unity3D&#xff08;U3D&#xff09; 1.视觉效果&#xff1a;Unity3D相对UE4略逊、手机3D应用、3D游戏轻量级首选&#xff0c;支持跨平台、设备兼容性更好 2.产品力&#xff1a;Unity3D更加多元化&#xff0c;各平台都有代表作&#xff0c;比如《王者荣耀》《炉石传说》《纪念…

SpringBoot读取resource或template中的文件

Spring-Boot读取resource或template中的文件 1.项目场景&#xff1a; 以jar包方式部署系统&#xff0c;想读取resource或是template下面的文件时&#xff0c;报 File Not Found 我遇到的情况是&#xff0c;整个项目达成了一个包&#xff0c;在开发环境&#xff08;windows i…

关于使用this.getClass().getResource(“/“)获取文件时遇到的坑_ClassPathResource加载资源文件用法

最近在工作中遇到需要读取配置文件&#xff0c;然后第一想法就是将文件放到项目的resources目录下, 然后使用&#xff1a; String fileName "config/zh.md" String path this.getClass().getResource("/").getPath() fileName; System.out.println(p…

Objects.requireNonNull( )方法说明

Objects.requireNonNull( )方法在java.util.Objects中 作用就是判断一个对象是否为空 底层源码&#xff1a; /* param obj 需要检测是否为空的对象* param <T> 对象类型* return 对象不为空则返回该对象* throws 对象为空则报NullPointerException异常*/public static …

数据模型 同比 环比_同比和环比计算公式?

一、同比增长计算公式&#xff1a; 1、同比增长率(本期数&#xff0d;同期数)同期数100% 例子&#xff1a;比如说去年3月的产32313133353236313431303231363533e4b893e5b19e31333365666237值100万&#xff0c;本年3月的产值300万&#xff0c;同比增长率是多少&#xff1f; 本…

SimpleDateFormat的线程不安全问题

一、前言 日期的转换与格式化在项目中应该是比较常用的了 一个问题&#xff1a;项目中的日期转换怎么用的&#xff1f;SimpleDateFormat 用过吗&#xff1f;能说一下 SimpleDateFormat 线程安全问题吗&#xff0c;以及如何解决&#xff1f; 回答&#xff1a;平时就是在全局定…

JVM——System.gc、内存溢出、内存泄漏、STW、安全点、安全区域、强软弱虚引用

文章目录①. System.gc()的理解②. 内存溢出(out of Memory)③. 内存泄漏(Memory Leak)④. Stop The World⑤. 多线程中的并行与并发⑥. 垃圾回收的并行、串行、并发⑦. 安全点(Safepoint)⑧. 安全区域(Safe Region)⑨. 引用①. 强引用:不回收②. 软引用: 内存不足即回收③. 弱…

Java——ThreadLocal概述、解决SimpleDateFormat出现的异常、内存泄漏、弱引用、remove方法

文章目录①. ThreadLocal简介①. ThreadLocal是什么②. api介绍③. 永远的helloword④. 通过上面代码总结②. 从阿里ThreadLocal规范开始①. 非线程安全的SimpleDateFormat②. 将SimpleDateFormat定义成局部变量(方案一)③. ThreadLocal 解决日期格式乱码问题④. 阿里规范怎么说…

JPA入门

文章目录JPA概述JPASpring Data JPAJPA注解基础注解EntityTableIdEnumeratedTransientColumnTemporal联合主键注解IdClassEmbeddable和EmbeddedId注解实体之间关联关系注解OneToOneManyToOne和OneToManyRepositoryJPA查询方式DQM&#xff08;定义查询方法&#xff09;使用实例D…

Java8——Stream流操作List排序_List集合中每个对象元素按时间顺序排序

一个学生类的实体类 Data public class Student {private Long id;private String name;private int age;private Double height;public Student(Long id, String name, int age, Double height) {this.id id;this.name name;this.age age;this.height height;}然后我们测…

java线程初始方法三种_Java 多线程 三种实现方式

Java多线程实现方式主要有三种&#xff1a;继承Thread类、实现Runnable接 口、使用ExecutorService、Callable 实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值&#xff0c;只有最后一种Callable是带返回值的&#xff0c;返回结果可以从Future中取出来关于Exe…

java控制层创建websocket_用Java构建一个简单的WebSocket聊天室

前言首先对于一个简单的聊天室&#xff0c;大家应该都有一定的概念了&#xff0c;这里我们省略用户模块的讲解&#xff0c;而是单纯的先说说聊天室的几个功能&#xff1a;自我对话、好友交流、群聊、离线消息等。今天我们要做的demo就能帮我们做到这一点啦&#xff01;&#xf…

Java中Date与 LocalDateTime ,LocalDate之间的转换

Date与LocalDateTime和LocalDate互相转换思路 Date转LocalDateTime和LocalDate都可以通过Date先转换成Instant然后再转换成LocalDateTime和LocalDate&#xff0c;可以按照下图的方式进行转换。LocalDateTime和LocalDate转换成Date也是以Instant为中介来进行转换的。 1&#xff…

Spring-data-jpa入门(一)

啥是JPA 我这个小白没有听说过&#xff0c;全英文名叫Java Persistence API&#xff0c;就是java持久化api&#xff0c;是SUN公司推出的一套基于ORM的规范。 持久化想必如雷贯耳&#xff0c;都2022年了&#xff0c;谁还不用个持久化框架啊&#xff0c;举起mybatis。 ORM呢&a…

struts单例模式 java_Java单例设计模式详细介绍

Java单例设计模式教程中包含了单例模式的定义、特点以及线路安全等问题。单例模式定义&#xff1a;单例模式确保某个类只有一个实例&#xff0c;而且自行实例化并向整个系统提供这个实例。在计算机系统中&#xff0c;线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对…

NetBeans、Eclipse 和 IDEA,哪个才是最优秀的Java IDE?

NetBeans、Eclipse 和 IDEA&#xff0c;哪个才是最优秀的Java IDE? 本文将向您介绍三种流行的Java IDE的基本特点&#xff0c;并比较它们的优缺点。 众所周知&#xff0c;集成开发环境(IDE)能够让程序员的日常编程过程&#xff0c;比起直接在文本编辑器上编写代码要容易得多。…