java 图像特效之图像混合(溶图)
来源:互联网 发布:sql服务器名称 编辑:程序博客网 时间:2024/05/05 22:36
阅读本系列,请先看前言!谢谢
photoshop中的图层混合功能大家一定很熟悉。此功能可以根据指定模式,将2个图层进行混合,实现不同色彩风格的图像效果,也就是我们通常所说的溶图。 实现图像混合的原理其实很简单,就是将两张图像的重叠,分别取相同位置的两个像素点上的RGB值,通过特定的公式计算出新的RGB值,这样,不公的公式,将产生不同的色彩效果。
假设a[i]代表第一个像素点的RGB值中的一个值,相对应于b[i](代表另一个像素点的RGB值中的一个值),变暗效果的公式是a[i] < b[i] ? a[i] : b[i],这个公式很简单,就是比较2个值得大小。
除此之外,还有其他效果的算法可以供我们使用:
排除
a[i] + b[i] - 2 * a[i] * b[i] / 255
差值
Math.abs(a[i] - b[i])
实色混合
(b[i] < 128 ? (b[i] == 0 ? 2 * b[i] : Math.max(0, (255 - ((255 - a[i]) << 8 ) / (2 * b[i])))) : ((2 * (b[i] - 128)) == 255 ? (2 * (b[i] - 128)) : Math.min(255, ((a[i] << 8 ) / (255 - (2 * (b[i] - 128)) ))))) < 128 ? 0 : 255;
点光
Math.max(0, Math.max(2 * b[i] - 255, Math.min(b[i], 2 * a[i])))
线性光
Math.min(255, Math.max(0, (b[i] + 2 * a[i]) - 1))
亮光
b[i] < 128 ? (b[i] == 0 ? 2 * b[i] : Math.max(0, (255 - ((255 - a[i]) << 8 ) / (2 * b[i])))) : ((2 * (b[i] - 128)) == 255 ? (2 * (b[i] - 128)) : Math.min(255, ((a[i] << 8 ) / (255 - (2 * (b[i] - 128)) ))))
强光
(a[i] < 128) ? (2 * a[i] * b[i] / 255) : (255 - 2 * (255 - a[i]) * (255 - b[i]) / 255)
柔光
b[i] < 128 ? (2 * (( a[i] >> 1) + 64)) * (b[i] / 255) : (255 - ( 2 * (255 - ( (a[i] >> 1) + 64 ) ) * ( 255 - b[i] ) / 255 ))
叠加
(b[i] < 128) ? (2 * a[i] * b[i] / 255) : (255 - 2 * (255 - a[i]) * (255 - b[i]) / 255)
线性减淡
Math.min(255, (a[i] + b[i]))
颜色减淡
(b[i] == 255) ? b[i] : Math.min(255, ((a[i] << 8 ) / (255 - b[i])))
滤色
255 - (((255 - a[i]) * (255 - b[i])) >> 8)
变亮
(b[i] > a[i]) ? b[i] : a[i]
线性加深
(a[i] + b[i] < 255) ? 0 : (a[i] + b[i] - 255)
颜色加深
b[i] == 0 ? b[i] : Math.max(0, Math.max(0, (255 - ((255 - a[i]) << 8 ) / b[i])))
正片叠底
a[i] * b[i] / 255
参考:图像混合(溶图)算法的javascript实现 对于图片
给出上述一些效果的实现:
/* * a[i] * b[i] / 255 * 正片叠底 */public Image filter() {if(this.img.gray)return this.img; // Grayscale images can not be processedfor (int y = 0; y < this.img.h; y++) { for (int x = 0; x < this.img.w; x++) { int fr = this.img.red[x + y * this.img.w]*jb.red[x + y * this.img.w]/255; int fg = this.img.green[x + y * this.img.w]*jb.green[x + y * this.img.w]/255; int fb = this.img.blue[x + y * this.img.w]*jb.blue[x + y * this.img.w]/255; this.img.data[x + y * this.img.w] = (255 << 24) | (math.st(fr) << 16) | (math.st(fg) << 8) | math.st(fb); } }return this.img;}
/* * (a[i] + b[i] < 255) ? 0 : (a[i] + b[i] - 255) * 线性加深 */public Image linearDeep() {if(this.img.gray)return this.img; // Grayscale images can not be processedfor (int y = 0; y < this.img.h; y++) { for (int x = 0; x < this.img.w; x++) { int fr = (this.img.red[x + y * this.img.w]+jb.red[x + y * this.img.w])<255?0:(this.img.red[x + y * this.img.w]+jb.red[x + y * this.img.w]-255); int fg = (this.img.green[x + y * this.img.w]+jb.green[x + y * this.img.w])<255?0:(this.img.green[x + y * this.img.w]+jb.green[x + y * this.img.w]-255); int fb = (this.img.blue[x + y * this.img.w]+jb.blue[x + y * this.img.w])<255?0:(this.img.blue[x + y * this.img.w]+jb.blue[x + y * this.img.w]-255); this.img.data[x + y * this.img.w] = (255 << 24) | (math.st(fr) << 16) | (math.st(fg) << 8) | math.st(fb); } }return this.img;}
/* * (b[i] > a[i]) ? b[i] : a[i] * 变亮 */public Image max() {if(this.img.gray)return this.img; // Grayscale images can not be processedfor (int y = 0; y < this.img.h; y++) { for (int x = 0; x < this.img.w; x++) { int fr = this.img.red[x + y * this.img.w] > jb.red[x + y * this.img.w]?this.img.red[x + y * this.img.w]:jb.red[x + y * this.img.w]; int fg = this.img.green[x + y * this.img.w] > jb.green[x + y * this.img.w]?this.img.green[x + y * this.img.w]:jb.green[x + y * this.img.w]; int fb = this.img.blue[x + y * this.img.w] > jb.blue[x + y * this.img.w]?this.img.blue[x + y * this.img.w]:jb.blue[x + y * this.img.w]; this.img.data[x + y * this.img.w] = (255 << 24) | (math.st(fr) << 16) | (math.st(fg) << 8) | math.st(fb); } }return this.img;}
/* * 255 - (((255 - a[i]) * (255 - b[i])) >> 8) * 滤色 */public Image ColorFilter() {if(this.img.gray)return this.img; // Grayscale images can not be processedfor (int y = 0; y < this.img.h; y++) { for (int x = 0; x < this.img.w; x++) { int fr = 255-((255-this.img.red[x + y * this.img.w])*(255-jb.red[x + y * this.img.w])>>8); int fg = 255-((255-this.img.green[x + y * this.img.w])*(255-jb.green[x + y * this.img.w])>>8); int fb = 255-((255-this.img.blue[x + y * this.img.w])*(255-jb.blue[x + y * this.img.w])>>8); this.img.data[x + y * this.img.w] = (255 << 24) | (math.st(fr) << 16) | (math.st(fg) << 8) | math.st(fb); } }return this.img;}
/* * Math.min(255, (a[i] + b[i])) * 线性减淡 */public Image LinearSub() {if(this.img.gray)return this.img; // Grayscale images can not be processedfor (int y = 0; y < this.img.h; y++) { for (int x = 0; x < this.img.w; x++) { int fr = 255>(this.img.red[x + y * this.img.w]+jb.red[x + y * this.img.w])?(this.img.red[x + y * this.img.w]+jb.red[x + y * this.img.w]):255; int fg = 255>(this.img.green[x + y * this.img.w]+jb.green[x + y * this.img.w])?(this.img.green[x + y * this.img.w]+jb.green[x + y * this.img.w]):255; int fb = 255>(this.img.blue[x + y * this.img.w]+jb.blue[x + y * this.img.w])?(this.img.blue[x + y * this.img.w]+jb.blue[x + y * this.img.w]):255; this.img.data[x + y * this.img.w] = (255 << 24) | (math.st(fr) << 16) | (math.st(fg) << 8) | math.st(fb); } }return this.img;}
/* * a[i] + b[i] - 2 * a[i] * b[i] / 255 * 排除 */public Image Exclude() {if(this.img.gray)return this.img; // Grayscale images can not be processedfor (int y = 0; y < this.img.h; y++) { for (int x = 0; x < this.img.w; x++) { int fr = this.img.red[x + y * this.img.w]+jb.red[x + y * this.img.w]-2*this.img.red[x + y * this.img.w]*jb.red[x + y * this.img.w]/255; int fg = this.img.green[x + y * this.img.w]+jb.green[x + y * this.img.w]-2*this.img.green[x + y * this.img.w]*jb.green[x + y * this.img.w]/255; int fb = this.img.blue[x + y * this.img.w]+jb.blue[x + y * this.img.w]-2*this.img.blue[x + y * this.img.w]*jb.blue[x + y * this.img.w]/255; this.img.data[x + y * this.img.w] = (255 << 24) | (math.st(fr) << 16) | (math.st(fg) << 8) | math.st(fb); } }return this.img;}
/* * Math.abs(a[i] - b[i]) * 差值 */public Image sub() {if(this.img.gray)return this.img; // Grayscale images can not be processedfor (int y = 0; y < this.img.h; y++) { for (int x = 0; x < this.img.w; x++) { int fr = Math.abs(this.img.red[x + y * this.img.w]-jb.red[x + y * this.img.w]); int fg = Math.abs(this.img.green[x + y * this.img.w]-jb.green[x + y * this.img.w]); int fb = Math.abs(this.img.blue[x + y * this.img.w]-jb.blue[x + y * this.img.w]); this.img.data[x + y * this.img.w] = (255 << 24) | (math.st(fr) << 16) | (math.st(fg) << 8) | math.st(fb); } }return this.img;}
以上
0 0
- java 图像特效之图像混合(溶图)
- java 图像特效之素描
- java 图像特效之油画
- java 图像特效之霓虹
- 图像特效---PS图层混合模式之明度模式
- 图像特效---PS图层混合模式之明度模式
- 图像特效之水彩特效
- 图像特效之灯光特效
- 图像特效之挤压特效
- 图像特效之波浪特效
- java 图像特效之老照片
- java 图像特效之随机光晕
- java 图像特效之放大镜与哈哈镜
- java 图像特效之彩色边缘
- 图像特效之电影海报
- 图像特效之连环画
- 图像特效之马赛克
- 图像特效之漩涡
- 是东方闪电
- sencha touch 2 tabpanel中List的不显示问题,解决方案
- VMware虚拟机三种联网方式(图文详细解说)
- UVA 10055 Hashmat the Brave Warrior
- swftools参数详细中文解译
- java 图像特效之图像混合(溶图)
- 最新版本express 4.2.0的快速建站--简单举例
- AsyncTask
- Python之美[从菜鸟到高手]--生成器之全景分析
- 五大常用算法之三:贪心算法
- 同洲盒子更改默认启动Portal
- Akka学习笔记(三):什么是Actor
- 编辑文章 - 博客频道 - CSDN.NET
- afxbeginthread Error 11error C2665: 'AfxBeginThread' : none of the 2 overloads could convert all th