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();
}
}
}
其他代碼請見源碼
效果圖