Java对图像的处理,具有相当强的表现能力,下列程序可以将普通照片生成类似于手绘的素描。

import java.awt.color.ColorSpace;

import java.awt.image.BufferedImage;

import java.awt.image.ColorConvertOp;

import java.io.File;

import javax.imageio.ImageIO;

public class sketch {

public static void main(String[] args) throws Exception{

String file1 = "D:/1.jpg";//原文件

String file2 = "D:/2.jpg";//素描

File inputFile = new File(file1);

BufferedImage old = ImageIO.read(inputFile);

//去色

BufferedImage b1 = discolor(old);

//反相

b1 = invert(b1);

//高斯模糊

float[][] matric = gaussian2DKernel(3, 3f);

b1 = convolution(b1, matric);

//叠加

b1 = deceaseColorCompound(old, b1);

//黑白

ColorSpace cs1 = ColorSpace.getInstance(ColorSpace.CS_GRAY);

ColorConvertOp op1 = new ColorConvertOp(cs1, null);

BufferedImage b2 = new BufferedImage(old.getWidth(), old.getHeight(), BufferedImage.TYPE_INT_RGB);

op1.filter(b1, b2);

ImageIO.write(b2, "jpg", new File(file2));

System.out.println("生成素描");

}

//去色

public static BufferedImage discolor(final BufferedImage sourceImage) {

final int width = sourceImage.getWidth();

final int height = sourceImage.getHeight();

final BufferedImage retImage = new BufferedImage(width, height,

BufferedImage.TYPE_INT_ARGB);

for (int i = 0; i < width; i++) {

for (int j = 0; j < height; j++) {

final int color1 = sourceImage.getRGB(i, j);

final int a1 = (color1 >> 24) & 0xff;

final int r1 = (color1 >> 16) & 0xff;

final int g1 = (color1 >> 8) & 0xff;

final int b1 = color1 & 0xff;

double sumA = a1;

double sumR = 0;

double sumG = 0;

double sumB = 0;

sumR = sumG = sumB = r1 * 0.299 + g1 * 0.587 + b1 * 0.114;

final int result = (((int) sumA)<<24)

| (((int) sumR) << 16) | (((int) sumG) << 8) | ((int) sumB);

retImage.setRGB(i, j, result);

}

}

return retImage;

}

//反相

public static BufferedImage invert(final BufferedImage sourceImage) {

final int width = sourceImage.getWidth();

final int height = sourceImage.getHeight();

final BufferedImage retImage = new BufferedImage(width, height,

BufferedImage.TYPE_INT_ARGB);

for (int i = 0; i < width; i++) {

for (int j = 0; j < height; j++) {

final int color1 = sourceImage.getRGB(i, j);

final int a1 = (color1 >> 24) & 0xff;

final int r1 = (color1 >> 16) & 0xff;

final int g1 = (color1 >> 8) & 0xff;

final int b1 = color1 & 0xff;

int a = a1;

int r = 255 - r1;

int g = 255 - g1;

int b = 255 - b1;

int result = (a << 24) | (r << 16) | (g << 8) | b;

if(result > 255) result = 255;

retImage.setRGB(i, j, result);

}

}

return retImage;

}

//叠加:两张图片颜色减淡混合

// C =MIN( A +(A×B)/(256-B),255)

public static BufferedImage deceaseColorCompound(final BufferedImage sourceImage,

final BufferedImage targetImage) {

final int width = sourceImage.getWidth() > targetImage.getWidth() ? sourceImage

.getWidth() : targetImage.getWidth();

final int height = sourceImage.getHeight() > targetImage.getHeight() ? sourceImage

.getHeight() : targetImage.getHeight();

final BufferedImage retImage = new BufferedImage(width, height,

BufferedImage.TYPE_INT_ARGB);

for (int i = 0; i < width; i++) {

for (int j = 0; j < height; j++) {

if(i>=sourceImage.getWidth() || j>=sourceImage.getHeight()){

if(i>=targetImage.getWidth() || j>=targetImage.getHeight()){

retImage.setRGB(i, j, 0);

continue;

}

retImage.setRGB(i, j, targetImage.getRGB(i, j));

continue;

}

if(i>=targetImage.getWidth() || j>=targetImage.getHeight()){

retImage.setRGB(i, j, sourceImage.getRGB(i, j));

continue;

}

final int color1 = sourceImage.getRGB(i, j);

final int color2 = targetImage.getRGB(i, j);

final int a1 = (color1 >> 24) & 0xff;

final int r1 = (color1 >> 16) & 0xff;

final int g1 = (color1 >> 8) & 0xff;

final int b1 = color1 & 0xff;

final int a2 = (color2 >> 24) & 0xff;

final int r2 = (color2 >> 16) & 0xff;

final int g2 = (color2 >> 8) & 0xff;

final int b2 = color2 & 0xff;

final int a = deceaseColorChannel(a1, a2);

final int r = deceaseColorChannel(r1, r2);

final int g = deceaseColorChannel(g1, g2);

final int b = deceaseColorChannel(b1, b2);

final int result = (a << 24) | (r << 16) | (g << 8) | b;

retImage.setRGB(i, j, result);

}

}

return retImage;

}

// C =MIN( A +(A×B)/(256-B),255)

private static int deceaseColorChannel(final int source, final int target) {

final int result = source + source * target / (256 - target);

return result > 255 ? 255 : result;

}

//高斯模糊

public static BufferedImage convolution(final BufferedImage image,

final float kernel[][]) {

final int width = image.getWidth();

final int height = image.getHeight();

final int radius = kernel.length / 2;

final BufferedImage retImage = new BufferedImage(width, height,

BufferedImage.TYPE_INT_ARGB);

for (int i = 0; i < width; i++) {

for (int j = 0; j < height; j++) {

double sumA = 0;

double sumR = 0;

double sumG = 0;

double sumB = 0;

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

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

final int posX = x < 0 ? 0 : x >= width ? width - 1 : x;

final int posY = y < 0 ? 0 : y >= height ? height - 1

: y;

final int color = image.getRGB(posX, posY);

final int a = (color >> 24) & 0xff;

final int r = (color >> 16) & 0xff;

final int g = (color >> 8) & 0xff;

final int b = color & 0xff;

final int kelX=x - i + radius;

final int kelY=y - j + radius;

sumA += kernel[kelX][kelY] * a;

sumR += kernel[kelX][kelY] * r;

sumG += kernel[kelX][kelY] * g;

sumB += kernel[kelX][kelY] * b;

}

}

final int blurColor = (((int) sumA)<<24)

| (((int) sumR) << 16) | (((int) sumG) << 8) | ((int) sumB);

retImage.setRGB(i, j, blurColor);

}

}

return retImage;

}

//2D高斯卷积矩阵

// G(x,y)=[1/(2*PI*sigma^2)]*e^[-((x^2+y^2)/(2*sigma^2))]

// x,y->[-radius,radius)

public static float[][] gaussian2DKernel(final int radius, final float sigma) {

final int length = 2 * radius;

final float[][] matric = new float[length + 1][length + 1];

final float sigmaSquare2 = 2 * sigma * sigma;

float sum = 0;

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

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

matric[radius + x][radius + y] = (float) (Math.pow(Math.E, -(x

* x + y * y)

/ sigmaSquare2) / (Math.PI * sigmaSquare2));

sum += matric[radius + x][radius + y];

}

}

for (int x = 0; x < length; x++) {

for (int y = 0; y < length; y++) {

matric[x][y] /= sum;

}

}

return matric;

}

}

生成效果比较

生成前照片:

生成后素描:

java 手绘_用普通照片生成手绘素描相关推荐

  1. python将图片转动漫_如何把照片变成手绘动漫化?

    看了各位答主的回答,大都是利用 ps 或者是相应的 app 来实现动漫效果的. 其中的原理大同小异,大家看我这篇文章就足够了! 1.普通照片和动漫图片的区别 要想搞清楚怎么变成动漫化风格,首先就要明白 ...

  2. python怎么把照片转成卡通_如何把照片变成手绘动漫化?

    12/10更新送福利 知乎专供,虎课网7天全站通VIP,全站5w+视频教程随意看!(当然也包括回答中的所有视频链接) ============================== 一.用电脑PS做 点 ...

  3. python将图片转换成动漫_如何把照片变成手绘动漫化?

    12/10更新送福利 知乎专供,虎课网7天全站通VIP,全站5w+视频教程随意看!(当然也包括回答中的所有视频链接) ============================== 一.用电脑PS做 点 ...

  4. 用pfx证书java双向认证_把CA证书生成的crt的证书和pem的私钥转换成java能够使用的keystore和pcks12的证书,实现https双向认证...

    最近在做一个https双向认证的工作,领导先让我实现,我之前写了一篇文章,把tomcat的生成证书和配置的实现写了出来. 现在领导给了我服务器的CA证书的客户端证书和私钥,服务端信任证书,分别是crt ...

  5. python乘法符号手写_利用Python自动生成小学生加减乘除口算考试题卷,不再为手写算术题烦恼!...

    还在为给孩子抄各种各样的口算题而烦恼?孩子上小学一年级之后,加减乘除的口算就要开始练习了,老师肯定会让家长出题.所以我们当家长的,要提前准备一下,就利用Python开发了一套自动生成小学生口算题的小应 ...

  6. java语言生成语法分析_语法分析器自动生成工具一览

    最近打算重做以前的一个留下遗憾的工作,当中的一项小任务就是要求编写一个简易SQL语言的语法分析器. 本科的<编译原理>课程依稀在我脑中留下些许映象.当初的课程大作业是写一个叫Dicuf(貌 ...

  7. ios怎么玩java模拟器游戏_新方式玩iOS手游 水果模拟器让电脑运行苹果iOS

    新方式玩iOS手游 水果模拟器让电脑运行苹果iOS 作者:阿姆斯特朗雷时间:2020-02-28 分享到: 手机的出现到现在人手一台,从简单的通话短信,到现在方寸间体验到各种新热手游,掌上的这个屏幕给 ...

  8. uniapp手写_【uniapp 开发】手绘签名组件

    代码如下: 点击签名1 点击签名2 import catSignature from "@/components/cat-signature/cat-signature.vue" ...

  9. java唯一码_唯一邀请码生成(Java版本)

    前言 之前收到一个需求,甲方说,他们想给用户生成一个唯一的邀请码,然后用户量在xxx之类的,例如我这里就随便说个5kw个吧.这个嘛,听起来都觉得挺简单的,毕竟每个用户基本上都有自己的唯一用户id,用那 ...

最新文章

  1. jquery中ajax的dataType属性包括哪几项
  2. hp laser103 属性没有配置项_冰雪传奇:起源之上还有装备吗?详解鸿蒙装备合成与属性...
  3. Spinner的使用方法
  4. c语言自动ejter,Skinnskalle eller ej, ingen ska behöva dö för sina åsikter
  5. 计算机学院志愿服务活动 2013/12/23 爱心6+1,计算机学院赴淮南南站开展志愿服务活动...
  6. 大数据可视化系统开发的作用
  7. a4如何打印双面小册子_怎样将十几几十页的长文件文档打印成A4纸对折的小册子?...
  8. PMP中英文术语对照
  9. 测试脚本常用知识点python
  10. CorelDRAW常用工具之橡皮擦工具
  11. 一起来学linux:磁盘与文件系统:
  12. 描述 C 库函数 int fseek(FILE *stream, long int offset, int whence) 设置流 stream 的文件位置为给定的偏移 offset,参数 offs
  13. 中国人民大学计算机专硕好考吗,干货:中国人民大学考研复试成功经验分享,值得收藏!...
  14. 塑胶卡扣弹性计算公式_弹性的计算方法
  15. pep8 python 编码规范下载_PEP8 Python 编码规范整理
  16. 有趣的跳跃(循环判断)
  17. 时间序列分析之预处理(一)
  18. AAA云免费云主机推荐码
  19. 计算机科学引论试题,内工大计算机科学引论在线测试题.pdf
  20. CPU架构及移动处理器芯片厂商盘点

热门文章

  1. 鹏业软件导入布局图纸
  2. 洛谷P1508Likecloud-吃、吃、吃 ----- Only my water can help me
  3. 《期市截拳道》 笔记
  4. 西方哲学史中49位哲学家的核心思想
  5. 【java】对URL中的中文和符号进行UrlEncode转码
  6. Android手机通讯录备份和恢复项目
  7. c语言 dtr rts 编程,C# 怎样设置RTS和DTR
  8. Ardunio下的STM32串口通信
  9. 书读百遍,其意自现 --- 意境与语境的融合
  10. wamp 不起启动一直是黄的