java图片转字符画

  • Post author:
  • Post category:java

java图片转字符画

先来效果图,如下

将图片转换为字符画

思路:读取图片,图片灰化,根据色彩程度选择对应的字符,按照坐标创建图片并将字符画上去

成品图

代码结构图

MainGUI是程序入口,beautyeye_Inf.jar是界面主题jar包,可不需要,gifdecoder.jar是处理gif动态图的jar包,网上不好找,但是可以找到对应的代码,自行打包成jar,请见:

https://blog.csdn.net/rico_zhou/article/details/81301566

代码

MainGUI

package mainGUI;

import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileSystemView;
import javax.swing.plaf.FontUIResource;

import org.jb2011.lnf.beautyeye.BeautyEyeLNFHelper;

import controller.CharImgController;
import utils.ImageUtils;

public class MainGUI extends JFrame implements ActionListener {
	public JPanel jp1;
	public JLabel jlb1, jlb2, jlb3, jlb4, jlb5, jlb6, jlb7, jlb8, jlb9, jlb10;
	public JButton button1, button2, button3, button4;
	public SwingWorker<ReturnMsg, String> sw1;
	private JComboBox jcb1, jcb2, jcb3, jcb4, jcb5;
	public JRadioButton jrb1, jrb2;
	public ButtonGroup bg1;
	public JTextField tt1, tt2, tt3, tt4, tt5, tt6, tt7;
	public JFileChooser jfc1, jfc2;
	public File file;
	public BufferedImage bi1, bi2;
	public static int numImage = 0;
	public ImageUtils iu = new ImageUtils();
	private static boolean isRunning;
	public CharImgController cic = new CharImgController();
	public ReturnMsg f;
	// 是否是gif
	public boolean isGif;
	// gif图片集合
	public List<BufferedImage> list = new ArrayList<BufferedImage>();
	// 缩放后集合
	public List<BufferedImage> list2 = new ArrayList<BufferedImage>();
	public List<Integer> list3 = new ArrayList<Integer>();
	public GifMsg gm = new GifMsg();

	public MainGUI() {
		// 初始化主题
		initTheme();
		// 初始化界面
		init();
	}

	private void initTheme() {
		// 国人牛逼主题,值得学习
		// 初始化字体
		InitGlobalFont(new Font("微软雅黑", Font.PLAIN, 13));
		// 设置本属性将改变窗口边框样式定义
		// 系统默认样式 osLookAndFeelDecorated
		// 强立体半透明 translucencyAppleLike
		// 弱立体感半透明 translucencySmallShadow
		// 普通不透明 generalNoTranslucencyShadow
		BeautyEyeLNFHelper.frameBorderStyle = BeautyEyeLNFHelper.FrameBorderStyle.generalNoTranslucencyShadow;
		// 设置主题为BeautyEye
		try {
			org.jb2011.lnf.beautyeye.BeautyEyeLNFHelper.launchBeautyEyeLNF();
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 隐藏“设置”按钮
		UIManager.put("RootPane.setupButtonVisible", false);
		// 开启/关闭窗口在不活动时的半透明效果
		// 设置此开关量为false即表示关闭之,BeautyEye LNF中默认是true
		BeautyEyeLNFHelper.translucencyAtFrameInactive = false;
		// 设置BeantuEye外观下JTabbedPane的左缩进
		// 改变InsetsUIResource参数的值即可实现
		UIManager.put("TabbedPane.tabAreaInsets", new javax.swing.plaf.InsetsUIResource(3, 20, 2, 20));
		//

		// 切换主题,此主题在圆形窗口有标题栏

		try {
			// UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// font
	private static void InitGlobalFont(Font font) {
		FontUIResource fontRes = new FontUIResource(font);
		for (Enumeration<Object> keys = UIManager.getDefaults().keys(); keys.hasMoreElements();) {
			Object key = keys.nextElement();
			Object value = UIManager.get(key);
			if (value instanceof FontUIResource) {
				UIManager.put(key, fontRes);
			}
		}
	}

	// 主方法
	public static void main(String[] args) {
		// 线程启动截图主程序
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				new MainGUI();
			}
		});
	}

	private void init() {
		// 初始化面板
		jp1 = new JPanel();
		jp1.setLayout(null);

		// 基本设置
		jlb1 = new JLabel("基本设置:");
		jlb1.setBounds(20, 10, 80, 25);
		jp1.add(jlb1);

		jlb2 = new JLabel("缩放图片大小:");
		jlb2.setBounds(47, 40, 100, 25);
		jp1.add(jlb2);

		String[] sfImage = { "原图尺寸", "100x100", "200x200", "300x300", "400x400", "500x500", "自定义" };
		jcb1 = new JComboBox(sfImage);
		// 设置默认显示值
		jcb1.setSelectedIndex(0);
		jp1.add(jcb1);
		jcb1.setBounds(140, 40, 100, 25);

		tt1 = new JTextField();
		tt1.setBounds(250, 40, 60, 25);
		jp1.add(tt1);
		tt1.setVisible(false);

		jlb3 = new JLabel("x");
		jlb3.setBounds(317, 40, 10, 25);
		jp1.add(jlb3);
		jlb3.setVisible(false);

		tt2 = new JTextField();
		tt2.setBounds(330, 40, 60, 25);
		jp1.add(tt2);
		tt2.setVisible(false);

		jcb1.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// 自定义
				if (jcb1.getSelectedIndex() == sfImage.length - 1) {
					tt1.setVisible(true);
					jlb3.setVisible(true);
					tt2.setVisible(true);
				} else {
					tt1.setVisible(false);
					jlb3.setVisible(false);
					tt2.setVisible(false);
				}
			}
		});

		jlb4 = new JLabel("生成图片大小:");
		jlb4.setBounds(47, 70, 100, 25);
		jp1.add(jlb4);

		String[] createImage = { "原图尺寸", "100x100", "200x200", "300x300", "400x400", "500x500", "自定义" };
		jcb2 = new JComboBox(createImage);
		// 设置默认显示值
		jcb2.setSelectedIndex(0);
		jp1.add(jcb2);
		jcb2.setBounds(140, 70, 100, 25);

		tt3 = new JTextField();
		tt3.setBounds(250, 70, 60, 25);
		jp1.add(tt3);
		tt3.setVisible(false);

		jlb5 = new JLabel("x");
		jlb5.setBounds(317, 70, 10, 25);
		jp1.add(jlb5);
		jlb5.setVisible(false);

		tt4 = new JTextField();
		tt4.setBounds(330, 70, 60, 25);
		jp1.add(tt4);
		tt4.setVisible(false);

		jcb2.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// 自定义
				if (jcb2.getSelectedIndex() == createImage.length - 1) {
					tt3.setVisible(true);
					jlb5.setVisible(true);
					tt4.setVisible(true);
				} else {
					tt3.setVisible(false);
					jlb5.setVisible(false);
					tt4.setVisible(false);
				}
			}
		});

		jlb6 = new JLabel("字符画字符集:");
		jlb6.setBounds(47, 100, 100, 25);
		jp1.add(jlb6);

		String[] customChar = { "默认字符", "8@#&$%*o!;.", "自定义" };
		jcb3 = new JComboBox(customChar);
		// 设置默认显示值
		jcb3.setSelectedIndex(0);
		jp1.add(jcb3);
		jcb3.setBounds(140, 100, 100, 25);

		tt5 = new JTextField();
		tt5.setBounds(250, 100, 60, 25);
		jp1.add(tt5);
		tt5.setVisible(false);

		jlb7 = new JLabel("(左->右 = 复杂->简单)");
		jlb7.setBounds(315, 100, 170, 25);
		jp1.add(jlb7);
		jlb7.setVisible(false);

		jcb3.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// 自定义
				if (jcb3.getSelectedIndex() == customChar.length - 1) {
					tt5.setVisible(true);
					jlb7.setVisible(true);
				} else {
					tt5.setVisible(false);
					jlb7.setVisible(false);
				}
			}
		});

		jlb8 = new JLabel("选择字符大小:");
		jlb8.setBounds(47, 130, 100, 25);
		jp1.add(jlb8);

		String[] charSize = { "自适应", "10", "12", "14", "16", "18", "20", "自定义" };
		jcb4 = new JComboBox(charSize);
		// 设置默认显示值
		jcb4.setSelectedIndex(0);
		jp1.add(jcb4);
		jcb4.setBounds(140, 130, 100, 25);

		tt6 = new JTextField();
		tt6.setBounds(250, 130, 60, 25);
		jp1.add(tt6);
		tt6.setVisible(false);

		jcb4.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// 自定义
				if (jcb4.getSelectedIndex() == charSize.length - 1) {
					tt6.setVisible(true);
				} else {
					tt6.setVisible(false);
				}
			}
		});

		// 密集度
		jlb10 = new JLabel("字符密集度:");
		jlb10.setBounds(318, 130, 100, 25);
		jp1.add(jlb10);

		String[] imgIntensity = { "1", "2", "3", "4", "5" };
		jcb5 = new JComboBox(imgIntensity);
		// 设置默认显示值
		jcb5.setSelectedIndex(0);
		jp1.add(jcb5);
		jcb5.setBounds(395, 130, 70, 25);

		button1 = new JButton("选择图片");
		button1.setBounds(30, 170, 80, 30);
		button1.addActionListener(this);
		jp1.add(button1);

		button2 = new JButton("生成图片");
		button2.setBounds(150, 170, 80, 30);
		button2.addActionListener(this);
		button2.setEnabled(false);
		jp1.add(button2);

		button3 = new JButton("另存图片");
		button3.setBounds(270, 170, 80, 30);
		button3.addActionListener(this);
		button3.setEnabled(false);
		jp1.add(button3);

		button4 = new JButton("下载文本");
		button4.setBounds(390, 170, 80, 30);
		button4.setEnabled(false);
		button4.addActionListener(this);
		jp1.add(button4);

		jlb9 = new JLabel("", SwingConstants.CENTER);
		jlb9.setBounds(30, 210, 440, 450);
		jp1.add(jlb9);

		jfc1 = new JFileChooser();
		jp1.add(jfc1);

		this.add(jp1);
		this.setTitle("字符画生成器");
		this.setSize(500, 715);
		this.setLocationRelativeTo(null);
		this.setVisible(true);
		this.setResizable(false);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		ImageIcon imageIcon = new ImageIcon(getClass().getResource("img2.png"));
		this.setIconImage(imageIcon.getImage());
		// 监听界面关闭事件
		this.addWindowListener(new WindowAdapter() {
			// 当关闭时
			public void windowClosing(WindowEvent e) {

			}
		});
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// 监听选择文件夹按钮
		if (e.getSource().equals(button1)) {// 判断触发方法的按钮是哪个
			jfc1.setFileSelectionMode(0);// 设定选择到文件
			jfc1.setFileFilter(new FileCanChoose());
			int state = jfc1.showOpenDialog(this);// 此句是打开文件选择器界面的触发语句
			if (state == 1) {
				return;
			} else {
				file = jfc1.getSelectedFile();// f为选择到的文件
				// 判断是否是动态图
				Timer timer = new Timer();
				if (file.getName().endsWith(".gif") || file.getName().endsWith(".GIF")) {
					isGif = true;
					list.clear();
					list2.clear();
					// 读取并拆分gif
					gm = iu.splitGif(file.getAbsolutePath());
					list = gm.getList();
					// 延迟时间
					list3 = gm.getList2();
					int time = (list3.size() > 0 && list3 != null) ? list3.get(0) : 300;
					// 缩放图片组
					for (BufferedImage bi : list) {
						list2.add(iu.zoomImage(bi, 440, 450));
					}
					// thread = new CountThread();
					// thread.start();

					timer.scheduleAtFixedRate(new TimerTask() {
						int i = 0;

						public void run() {
							if (list2.size() > 0 && list2.get(i) != null) {
								if (numImage != 0) {
									// 移除之前的图片
									jlb9.setText("");
								}
								numImage++;
								jlb9.setIcon(new ImageIcon(list2.get(i)));
								i++;
								if (i > list2.size() - 1) {
									i = 0;
								}
							}
						}
					}, time, time);
					// 轮播图片组模拟gif

					// 每100ms执行一次,1000ms重新执行
					button2.setEnabled(true);
				} else {
					isGif = false;
					if (timer != null) {
						System.out.println(2);
						timer.cancel();
						jlb9.setText("");
					}
					list.clear();
					list2.clear();
					// 缩放图片
					bi1 = iu.zoomImage(file.getAbsolutePath(), 440, 450, null);
					if (bi1 != null) {
						if (numImage != 0) {
							// 移除之前的图片
							jlb9.setText("");
						}
						numImage++;
						jlb9.setIcon(new ImageIcon(bi1));
						button2.setEnabled(true);
					} else {
						JOptionPane.showMessageDialog(null, "加载图片失败!请重试!", "提示消息", JOptionPane.WARNING_MESSAGE);
					}
				}
			}
		}

		// 监听生成图片
		if (e.getSource().equals(button2)) {
			// get params
			CharImgParams cip = getCharImgPra();
			// check
			int flag = checkParams(cip);
			if (flag == 0) {
				// 转换参数
				CharImgParams2 cip2 = iu.turnPro(cip);
				button1.setEnabled(false);
				button2.setEnabled(false);
				button3.setEnabled(false);
				button4.setEnabled(false);

				// start times
				MainGUI.isRunning = true;

				sw1 = new SwingWorker<ReturnMsg, String>() {
					// 此方法是耗时任务
					@Override
					protected ReturnMsg doInBackground() throws Exception {
						f = cic.charImgController(cip2);
						return f;
					}

					// done
					protected void done() {
						ReturnMsg f = null;
						try {
							f = get();
						} catch (Exception e) {
							e.printStackTrace();
						}
						if (f != null && f.isSucc) {
							// 显示在一个窗口
							if (!isGif) {
								ShowImgJF sij = new ShowImgJF(f.getBi());
							} else {
								ShowImgJF sij = new ShowImgJF(f.getList(), f.getList4());
							}
						} else {
							JOptionPane.showMessageDialog(null, "创建字符画失败!", "提示消息", JOptionPane.WARNING_MESSAGE);
						}
						button1.setEnabled(true);
						button2.setEnabled(true);
						button3.setEnabled(true);
						button4.setEnabled(true);
					}
				};
				sw1.execute();
			} else if (flag == 1) {
				JOptionPane.showMessageDialog(null, "不能为空!请重新填写!", "提示消息", JOptionPane.WARNING_MESSAGE);
			} else if (flag == 2) {
				JOptionPane.showMessageDialog(null, "数字格式不正确!请重新填写!", "提示消息", JOptionPane.WARNING_MESSAGE);
			} else if (flag == 3) {
				JOptionPane.showMessageDialog(null, "字符集超长!请重新填写!", "提示消息", JOptionPane.WARNING_MESSAGE);
			}
		}

		// 监听另存图片
		if (e.getSource().equals(button3) || e.getSource().equals(button4)) {
			if (f != null && f.isSucc()) {
				// 打开文件夹
				// 接收文件
				JFileChooser chooser = new JFileChooser();
				// 设定只能选择到文件夹
//				chooser.setFileSelectionMode(1);
				chooser.setDialogTitle("保存文件框");
				// 默认文件名称还有放在当前目录下
				
				// 保存路径
				SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
				String fileName = sdf.format(new Date());
				if (e.getSource().equals(button3)) {
					if (isGif) {
						fileName = sdf.format(new Date()) + ".gif";
					} else {
						fileName = sdf.format(new Date()) + ".jpg";
					}
				} else if (e.getSource().equals(button4)) {
					fileName = sdf.format(new Date()) + ".txt";
				}
				File filePath = FileSystemView.getFileSystemView().getHomeDirectory();
				File defaultFile = new File(filePath + File.separator + fileName);
				chooser.setSelectedFile(defaultFile);
				int s = chooser.showSaveDialog(this);
				String saveFilePath = chooser.getSelectedFile().getPath();
				if (s == 1) {
					return;
				} else {
					try {
						if (e.getSource().equals(button3)) {
							if (isGif) {
								// 生成动态图
								iu.jpgToGif(f.getList(), f.getList4(), saveFilePath);
							} else {
								ImageIO.write(f.getBi(),
										fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()),
										new File(saveFilePath));
							}
						} else if (e.getSource().equals(button4)) {
							if (isGif) {
								// 动态图全部输出(时间戳+"_"+延迟时间+后缀123+文件格式)
								String pathName = null;
								Writer out = null;
								for (int i = 0; i < f.getList3().size(); i++) {
									pathName = saveFilePath.substring(0, saveFilePath.length() - 4) + "_"
											+ f.getList4().get(i) + "_" + i + ".txt";
									out = new FileWriter(new File(pathName));
									out.write(f.getList3().get(i).getTextImg());
									out.close();
								}

							} else {
								Writer out = new FileWriter(new File(saveFilePath));
								out.write(f.getTextImg());
								out.close();
							}
						}
						JOptionPane.showMessageDialog(null, "保存成功!", "提示消息", JOptionPane.WARNING_MESSAGE);
					} catch (Exception e1) {
						JOptionPane.showMessageDialog(null, "保存失败!请重试!", "提示消息", JOptionPane.WARNING_MESSAGE);
						e1.printStackTrace();
					}
				}
			} else {
				JOptionPane.showMessageDialog(null, "保存失败!请重试!", "提示消息", JOptionPane.WARNING_MESSAGE);
			}

		}

	}

	// 校验参数
	private int checkParams(CharImgParams cip) {
		// 不能为空
		if ("".equals(cip.getSfImgSizeW()) || "".equals(cip.getSfImgSizeH()) || "".equals(cip.getCreateImgSizeW())
				|| "".equals(cip.getCreateImgSizeH()) || "".equals(cip.getCharArray())
				|| "".equals(cip.getCharSize())) {
			return 1;
		}
		// 数字校验
		if (!cip.getSfImgSizeW().matches("^[0-9]*$") || cip.getSfImgSizeW().length() > 8
				|| !cip.getSfImgSizeH().matches("^[0-9]*$") || cip.getSfImgSizeH().length() > 8
				|| !cip.getCreateImgSizeW().matches("^[0-9]*$") || cip.getCreateImgSizeW().length() > 8
				|| !cip.getCreateImgSizeH().matches("^[0-9]*$") || cip.getCreateImgSizeH().length() > 8
				|| !cip.getCharSize().matches("^[0-9]*$") || cip.getCharSize().length() > 8) {

			return 2;
		}
		// 字符校验
		if (cip.getCharArray().length() > 15) {
			return 3;
		}
		return 0;
	}

	// 获取参数
	private CharImgParams getCharImgPra() {
		CharImgParams cip = new CharImgParams();
		// 缩放图片大小
		if (jcb1.getSelectedIndex() == 0) {
			// 原尺寸
			cip.setSfImgSizeW("0");
			cip.setSfImgSizeH("0");
		} else if (jcb1.getSelectedIndex() == jcb1.getItemCount() - 1) {
			// 最后是自定义
			cip.setSfImgSizeW(tt1.getText().trim());
			cip.setSfImgSizeH(tt2.getText().trim());
		} else {
			String[] s = jcb1.getSelectedItem().toString().replaceAll(" ", "").split("x");
			cip.setSfImgSizeW(s[0]);
			cip.setSfImgSizeH(s[1]);
		}

		// 生成图片的大小
		if (jcb2.getSelectedIndex() == 0) {
			// 原尺寸
			cip.setCreateImgSizeW("0");
			cip.setCreateImgSizeH("0");
		} else if (jcb2.getSelectedIndex() == jcb2.getItemCount() - 1) {
			// 最后是自定义
			cip.setCreateImgSizeW(tt3.getText().trim());
			cip.setCreateImgSizeH(tt4.getText().trim());
		} else {
			String[] s = jcb2.getSelectedItem().toString().replaceAll(" ", "").split("x");
			cip.setCreateImgSizeW(s[0]);
			cip.setCreateImgSizeH(s[1]);
		}
		// 获取字符集
		if (jcb3.getSelectedIndex() == 0) {
			// 默认
			cip.setCharArray("8@#&$%*o!;.");
		} else if (jcb3.getSelectedIndex() == jcb3.getItemCount() - 1) {
			// 最后是自定义
			cip.setCharArray(tt5.getText().trim());
		} else {
			cip.setCharArray(jcb3.getSelectedItem().toString().trim());
		}

		// 获取字符大小
		if (jcb4.getSelectedIndex() == 0) {
			// 默认
			cip.setCharSize("10");
		} else if (jcb4.getSelectedIndex() == jcb4.getItemCount() - 1) {
			// 最后是自定义
			cip.setCharSize(tt6.getText().trim());
		} else {
			cip.setCharSize(jcb4.getSelectedIndex() * 2 + 8 + "");
		}
		// 获取文件地址
		cip.setGif(isGif);
		if (isGif) {
			cip.setList(list2);
			cip.setList3(list3);
		} else {
			cip.setFilePath(file.getAbsolutePath());
		}
		// 字符密集度
		cip.setImgIntensity(jcb5.getSelectedIndex() + 1);
		return cip;
	}

	// 文件过滤器
	class FileCanChoose extends FileFilter {
		public boolean accept(File file) {
			String name = file.getName();
			return (name.toLowerCase().endsWith(".jpg") || name.toLowerCase().endsWith(".bmp")
					|| name.toLowerCase().endsWith(".png") || name.toLowerCase().endsWith(".jpeg")
					|| name.toLowerCase().endsWith(".gif") || file.isDirectory());
		}

		@Override
		public String getDescription() {
			return "图片文件:*.jpg、 *.bmp、 *.png、 *.jpeg、 *.gif";
		}
	}

}

CharImgController

package controller;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

import mainGUI.CImgPro;
import mainGUI.CharImgParams;
import mainGUI.CharImgParams2;
import mainGUI.ReturnMsg;
import utils.ImageUtils;

public class CharImgController {
	public ImageUtils iu = new ImageUtils();

	// 控制类
	public ReturnMsg charImgController(CharImgParams2 cip2) {
		if (cip2.isGif()) {
			return charImgController2(cip2);
		} else {
			ReturnMsg f = new ReturnMsg();
			// 获取图片
			BufferedImage image = iu.getImage(cip2.getFilePath());
			if (image == null) {
				f.setSucc(false);
				return f;
			}
			// 对获取的图片进行缩放
			if (cip2.getSfImgSizeW() != 0) {
				try {
					image = iu.zoom2(image, cip2.getSfImgSizeW(), cip2.getSfImgSizeH());
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			// 创建一个缓存图片用于写入字符
			int w = image.getWidth();
			int h = image.getHeight();
			if (cip2.getCreateImgSizeW() != 0) {
				w = cip2.getCreateImgSizeW();
				h = cip2.getCreateImgSizeH();
			}
			BufferedImage createImg = iu.createBufferedImage(w, h);
			// 处理下字体
			int fontSize = 10;
			if (cip2.getCharSize() == 0) {
				// 如果自适应的话
				// 先不处理
				fontSize = 10;
			} else {
				fontSize = cip2.getCharSize();
			}

			// 生成
			CImgPro cp = iu.createAsciiPic(image, createImg, cip2.getCharArray(), fontSize, cip2.getImgIntensity());
			f.setBi(cp.getBi());
			f.setTextImg(cp.getTextImg());
			f.setSucc(true);
			return f;
		}
	}

	// 单独处理gif
	private ReturnMsg charImgController2(CharImgParams2 cip2) {
		ReturnMsg f = new ReturnMsg();
		List<BufferedImage> list = new ArrayList<BufferedImage>();
		List<BufferedImage> list2 = new ArrayList<BufferedImage>();
		// 对获取的图片进行缩放
		if (cip2.getSfImgSizeW() != 0) {
			try {
				for (BufferedImage bi : cip2.getList()) {
					list.add(iu.zoom2(bi, cip2.getSfImgSizeW(), cip2.getSfImgSizeH()));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		// 创建一个缓存图片用于写入字符
		int w = list.get(0).getWidth();
		int h = list.get(0).getHeight();
		if (cip2.getCreateImgSizeW() != 0) {
			w = cip2.getCreateImgSizeW();
			h = cip2.getCreateImgSizeH();
		}
		for (int i = 0; i < list.size(); i++) {
			list2.add(iu.createBufferedImage(w, h));
		}
		// 处理下字体
		int fontSize = 10;
		if (cip2.getCharSize() == 0) {
			// 如果自适应的话
			// 先不处理
			fontSize = 10;
		} else {
			fontSize = cip2.getCharSize();
		}

		// 生成
		List<CImgPro> list3 = new ArrayList<CImgPro>();
		for (int i = 0; i < list2.size(); i++) {
			list3.add(iu.createAsciiPic(list.get(i), list2.get(i), cip2.getCharArray(), fontSize,
					cip2.getImgIntensity()));
		}
		// 直接返回动态图组
		f.setList(list2);
		f.setList3(list3);
		f.setList4(cip2.getList3());
		f.setSucc(true);
		return f;
	}
}

ImageUtils

package utils;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.imageio.ImageIO;

import gifdecoder.AnimatedGifEncoder;
import gifdecoder.GifDecoder;
import mainGUI.CImgPro;
import mainGUI.CharImgParams;
import mainGUI.CharImgParams2;
import mainGUI.GifMsg;

public class ImageUtils {

	// 缩放gif
	public BufferedImage zoomImage(BufferedImage bufImg, int jpwidth, int jpheight) {
		return zoomImage(null, jpwidth, jpheight, bufImg);
	}

	// 缩放图片
	public BufferedImage zoomImage(String absolutePath, int jpwidth, int jpheight, BufferedImage bufImg) {
		double wr = 0, hr = 0;
		if (absolutePath != null) {
			File srcFile = new File(absolutePath);
			bufImg = null;
			try {
				bufImg = ImageIO.read(srcFile);
			} catch (IOException e) {
				e.printStackTrace();
				return null;
			}
		}

		int w = bufImg.getWidth();
		int h = bufImg.getHeight();
		int[] wh = proImage(w, h, jpwidth, jpheight);

		Image Itemp = bufImg.getScaledInstance(wh[0], wh[1], bufImg.SCALE_SMOOTH);
		wr = wh[0] * 1.0 / bufImg.getWidth();
		hr = wh[1] * 1.0 / bufImg.getHeight();
		AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(wr, hr), null);
		Itemp = ato.filter(bufImg, null);
		return (BufferedImage) Itemp;
	}

	private int[] proImage(int w, int h, int jpwidth, int jpheight) {
		// 判断大小
		// 先以宽为缩放准则
		if (jpwidth * h / w <= jpheight) {
			// 如果高不超过
			return new int[] { jpwidth, jpwidth * h / w };
		} else {
			// 如果高超过了
			// 则以高为准则
			if (w * jpheight / h <= jpwidth) {
				return new int[] { w * jpheight / h, jpheight };
			} else {
				return null;
			}
		}
	}

	// 转换参数
	public CharImgParams2 turnPro(CharImgParams cip) {
		CharImgParams2 cip2 = new CharImgParams2();
		if (cip != null) {
			cip2.setSfImgSizeW(Integer.valueOf(cip.getSfImgSizeW()));
			cip2.setSfImgSizeH(Integer.valueOf(cip.getSfImgSizeH()));
			cip2.setCreateImgSizeW(Integer.valueOf(cip.getCreateImgSizeW()));
			cip2.setCreateImgSizeH(Integer.valueOf(cip.getCreateImgSizeH()));
			cip2.setCharSize(Integer.valueOf(cip.getCharSize()));
			cip2.setCharArray(cip.getCharArray());
			cip2.setGif(cip.isGif());
			if (cip.isGif()) {
				cip2.setList(cip.getList());
				cip2.setList3(cip.getList3());
			} else {
				cip2.setFilePath(cip.getFilePath());
			}
			cip2.setImgIntensity(cip.getImgIntensity());
		}

		return cip2;
	}

	// 获取图片
	public BufferedImage getImage(String filePath) {
		File f = new File(filePath);
		BufferedImage image;
		if (f.exists()) {
			try {
				image = ImageIO.read(f);
			} catch (IOException e) {
				e.printStackTrace();
				return null;
			}
		} else {
			return null;
		}
		return image;
	}

	// 另外一种压缩
	public BufferedImage zoom(BufferedImage bimg, int w, int h) throws IOException {
		int height = bimg.getHeight();
		int width = bimg.getWidth();
		BufferedImage bi = new BufferedImage(w, height * h / width, BufferedImage.TYPE_BYTE_GRAY);

		Graphics g = bi.getGraphics();
		g.drawImage(bimg, 0, 0, w, height * h / width, null);
		g.dispose();

		return bi;
	}

	// 缩放图片
	public BufferedImage zoom2(BufferedImage bufImg, int jpwidth, int jpheight) {
		double wr = 0, hr = 0;

		Image Itemp = bufImg.getScaledInstance(jpwidth, jpheight, bufImg.SCALE_SMOOTH);
		wr = jpwidth * 1.0 / bufImg.getWidth();
		hr = jpheight * 1.0 / bufImg.getHeight();
		AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(wr, hr), null);
		Itemp = ato.filter(bufImg, null);
		return (BufferedImage) Itemp;
	}

	// 创建一个缓冲图片
	public BufferedImage createBufferedImage(int w, int h) {
		BufferedImage image2 = new BufferedImage(w, h, BufferedImage.TYPE_INT_BGR);
		Graphics g = image2.createGraphics();
		// 背景色
		g.setColor(Color.WHITE);
		// 背景
		g.fillRect(0, 0, w, h);
		// 前景色
		g.setColor(Color.BLACK);
		return image2;
	}

	// 创建字符画
	public CImgPro createAsciiPic(BufferedImage image, BufferedImage createImg, String charText, int fontSize,
			int imgIntensity) {
		CImgPro cp = new CImgPro();
		StringBuilder sb = new StringBuilder();
		// 字符串由复杂到简单
		String base = "8@#&$%*o!;.";
		if (charText != null && !"".equals(charText)) {
			base = charText;
		}
		try {
			int w = image.getWidth();
			int h = image.getHeight();
			int ww = createImg.getWidth();
			int hh = createImg.getHeight();
			double xc = (double) (ww / w);
			double yc = (double) (hh / h);
			Graphics g2 = createGraphics(createImg);
			// 设置字体
			g2.setFont(new Font("微软雅黑", Font.PLAIN, fontSize));
			for (int y = 0; y < image.getHeight(); y += imgIntensity) {
				for (int x = 0; x < image.getWidth(); x += imgIntensity) {
					int pixel = image.getRGB(x, y);
					int r = (pixel & 0xff0000) >> 16, g = (pixel & 0xff00) >> 8, b = pixel & 0xff;
					float gray = 0.299f * r + 0.578f * g + 0.114f * b;
					int index = Math.round(gray * (base.length() + 1) / 255);
					sb.append(index >= base.length() ? " " : String.valueOf(base.charAt(index)));
					g2.drawString(index >= base.length() ? " " : String.valueOf(base.charAt(index)),
							(int) ((x + 1) * xc), (int) ((y + 1) * yc));
				}
				sb.append("\r\n");
			}
			cp.setBi(createImg);
			cp.setTextImg(sb.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return cp;
	}

	private Graphics createGraphics(BufferedImage createImg) {
		Graphics g = createImg.createGraphics();
		g.setColor(Color.WHITE); // 设置背景色
		g.fillRect(0, 0, createImg.getWidth(), createImg.getHeight());// 绘制背景
		g.setColor(Color.BLACK); // 设置前景色
		return g;
	}

	// 拆分gif
	public GifMsg splitGif(String gifName) {
		GifMsg gm = new GifMsg();
		List<BufferedImage> list = new ArrayList<BufferedImage>();
		List<Integer> list2 = new ArrayList<Integer>();
		try {
			GifDecoder decoder = new GifDecoder();
			decoder.read(gifName);
			// 个数
			int n = decoder.getFrameCount();

			for (int i = 0; i < n; i++) {
				BufferedImage frame = decoder.getFrame(i);
				list2.add(decoder.getDelay(i));
				list.add(frame);
				// ImageIO.write(frame, "jpg", new File(i + ".jpg"));
			}
			gm.setList(list);
			gm.setList2(list2);
			return gm;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return gm;
	}

	// 合成gif
	public void jpgToGif(List<BufferedImage> list, List<Integer> list2, String newPicPath) {
		try {
			// 实例化处理对象
			AnimatedGifEncoder e = new AnimatedGifEncoder();
			e.setRepeat(0);
			e.start(newPicPath);
			for (int i = 0; i < list.size(); i++) {
				// 设置播放的延迟时间
				e.setDelay(list2.get(i));
				// 添加到帧中
				e.addFrame(list.get(i));
			}
			e.finish();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

其他代码请见源码

效果图

源码GitHub:https://github.com/ricozhou/imgtochar1.0


版权声明:本文为rico_zhou原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。