抖音神器---Java實現圖片(Image)轉字元(ASCII)圖片
阿新 • • 發佈:2019-01-04
最近抖音上挺火的一個小把戲,在記事本開啟,一整篇的亂碼字元,然後進過調整之後,出現一張由各種字元組成的黑白照片。先看一個效果圖
微信小程式體驗
直接體驗請微信掃碼
接下來我們就用Java來實現吧。
需要用到的工具類程式碼
非閃圖圖片轉字元畫到記事本
package com.xs.util.image; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import javax.imageio.ImageIO; import com.xs.util.image.other.ImageHelper; /** * Image2ASCII * @author 小帥丶 * 2018年8月14日 */ public class Image2ASCII{ static String ascii = "
[email protected]%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\\\"^`'."; static String base = "@#&$%*o!;.";//小帥丶使用這個字元 //main方法呼叫 public static void main(String[] args) throws Exception { load("G:/phone.jpg", "F:/gif/woman.txt");//靜態圖片轉字元儲存為txt檔案 } /** * 圖片轉字元 * @param imagePath 圖片路徑 * @param txtPath 文字存放路徑 * @throws IOException */ public static void load(String imagePath, String txtPath) throws IOException { BufferedImage image = ImageHelper.resize(ImageIO.read(new File(imagePath)),150,150); load(image, txtPath); } /** * 圖片轉字元 * @param bi BufferedImage圖片 * @param txtPath 文字存放路徑 * @throws IOException */ public static void load(BufferedImage bi, String txtPath) throws IOException { try { int width = bi.getWidth(); int height = bi.getHeight(); boolean flag = false; String result = ""; for (int i = 0; i < height; i += 2) { for (int j = 0; j < width; j++) { int pixel = bi.getRGB(j, i); // 下面三行程式碼將一個數字轉換為RGB數字 int red = (pixel & 0xff0000) >> 16; int green = (pixel & 0xff00) >> 8; int blue = (pixel & 0xff); float gray = 0.299f * red + 0.578f * green + 0.114f * blue; int index = Math.round(gray * (base.length() + 1) / 255); result += index >= base.length() ? " " : String.valueOf(base.charAt(index)); } result += "\r\n"; } flag = writeTxtFile(result,txtPath);//儲存字元到文字檔案 System.out.println(flag?"圖片轉字元儲存成功":"圖片轉字元儲存失敗"); } catch (Exception e) { System.out.println("圖片轉字元異常"+e.getMessage()); } } /** * 字元儲存到txt檔案中 * @param imageStr 字元 * @param txtPath txt檔案 * @return boolean * @throws Exception */ private static boolean writeTxtFile(String imageStr, String txtPath) throws Exception{ // 先讀取原有檔案內容,然後進行寫入操作 boolean flag = false; String filein = imageStr; String temp = ""; FileInputStream fis = null; InputStreamReader isr = null; BufferedReader br = null; FileOutputStream fos = null; PrintWriter pw = null; try { // 檔案路徑 File file = new File(txtPath); if (!file.exists()) { file.createNewFile(); } // 將檔案讀入輸入流 fis = new FileInputStream(file); isr = new InputStreamReader(fis); br = new BufferedReader(isr); StringBuffer buf = new StringBuffer(); // 儲存該檔案原有的內容 for (int j = 1; (temp = br.readLine()) != null; j++) { buf = buf.append(temp); } buf.append(filein); fos = new FileOutputStream(file); pw = new PrintWriter(fos); pw.write(buf.toString().toCharArray()); pw.flush(); flag = true; } catch (IOException e) { System.out.println("檔案儲存失敗"+e.getMessage()); } finally { if (pw != null) { pw.close(); } if (fos != null) { fos.close(); } if (br != null) { br.close(); } if (isr != null) { isr.close(); } if (fis != null) { fis.close(); } } return flag; } }
非閃圖圖片轉字元畫返回BASE64
直接儲存為圖片也可以。
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import sun.misc.BASE64Encoder;
/**
* Image2ASCII
* @author 小帥丶
* 2018年8月14日
*/
public class Image2ASCII{
static String ascii = " [email protected]%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\\\"^`'.";
static String base = "@#&$%*o!;.";//小帥丶使用這個字元
/** 圖片型別 */
private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_RGB;
/**
* 圖片轉字元再儲存為圖片 只返回圖片的base64
* @param bi 原圖
* @param outPutPath
* @return String
*/
public static String txtToImageByBase64(BufferedImage bi) {
System.out.println("進來的時間"+System.currentTimeMillis());
int width = bi.getWidth();
int height = bi.getHeight();
int minx = bi.getMinX();
int miny = bi.getMinY();
int speed = 7;
BufferedImage bufferedImage = new BufferedImage(width,height,IMAGE_TYPE);
// 獲取影象上下文
Graphics g = createGraphics(bufferedImage, width, height, speed);
// 圖片中文字行高
final int Y_LINEHEIGHT = speed;
int lineNum = 1;
for (int i = miny; i < height; i += speed) {
for (int j = minx; j < width; j += speed) {
int pixel = bi.getRGB(j, i); // 下面三行程式碼將一個數字轉換為RGB數字
int red = (pixel & 0xff0000) >> 16;
int green = (pixel & 0xff00) >> 8;
int blue = (pixel & 0xff);
float gray = 0.299f * red + 0.578f * green + 0.114f * blue;
int index = Math.round(gray * (base.length() + 1) / 255);
String c = index >= base.length() ? " " : String.valueOf(base.charAt(index));
g.drawString(String.valueOf(c), j, i);
}
lineNum++;
}
g.dispose();
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
ImageIO.write(bufferedImage,"jpg",out);
BASE64Encoder base64Encoder = new BASE64Encoder();
String base64 =base64Encoder.encode(out.toByteArray());
return base64;
} catch (IOException e) {
System.out.println("ImageIO.write異常" + e.getMessage());
}finally{
if(null!=out){
try {
out.close();
} catch (IOException e) {
System.out.println("out.close()異常" + e.getMessage());
}
}
}
return null;
}
/**
* 畫板預設一些引數設定
* @param image 圖片
* @param width 圖片寬
* @param height 圖片高
* @param size 字型大小
* @return
*/
private static Graphics createGraphics(BufferedImage image, int width,
int height, int size) {
Graphics g = image.createGraphics();
g.setColor(null); // 設定背景色
g.fillRect(0, 0, width, height);// 繪製背景
g.setColor(Color.BLACK); // 設定前景色
g.setFont(new Font("微軟雅黑", Font.PLAIN, size)); // 設定字型
return g;
}
}
效果圖
方法返回的為圖片的base64資料。格式為jpg。加頭資訊即可在img標籤的src中顯示圖片哦。
線上轉base64為圖片 需要加頭資訊 data:image/jpg;base64,
閃圖圖片轉字元畫返回圖片
package com.xs.util.image;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.FileImageInputStream;
import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.imageio.plugins.gif.GIFImageReader;
import com.sun.imageio.plugins.gif.GIFImageReaderSpi;
import sun.misc.BASE64Encoder;
/**
* Image2ASCII
* @author 小帥丶
* 2018年8月14日
*/
public class Image2ASCII{
static String ascii = "[email protected]%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\\\"^`'.";
static String base = "@#&$%*o!;.";//小帥丶使用這個字元
/** 圖片型別 */
private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_RGB;
/**
* gif圖片轉gif字元圖
* @param imagePath 原圖路徑
* @param outPath 輸出圖片的資料夾路徑
* @throws IOException
*/
public static void loadGif(String imagePath, String outPath)
throws IOException {
File imageFile = new File(imagePath);
FileImageInputStream in = new FileImageInputStream(imageFile);
ImageReaderSpi readerSpi = new GIFImageReaderSpi();
GIFImageReader gifImageReader = new GIFImageReader(readerSpi);
gifImageReader.setInput(in);
int num = gifImageReader.getNumImages(true);
System.out.println(num);
BufferedImage[] bufferedImages = new BufferedImage[num];
for (int i = 0; i < num; i++) {
BufferedImage bi = gifImageReader.read(i);
bufferedImages[i] = txtToImage(bi, outPath + "out" + i + ".jpeg"); //每一幀都儲存為圖片
}
jpgToGif(bufferedImages,outPath + imagePath.substring(imagePath.length() - 6)+ "outGif.gif", 200);
}
/**
* 圖片轉字元再儲存為圖片
* @param bi 原圖
* @param outPutPath
* @return BufferedImage
*/
public static BufferedImage txtToImage(BufferedImage bi, String outPutPath) {
File imageFile = new File(outPutPath);
if (!imageFile.exists()) {
try {
imageFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
int width = bi.getWidth();
int height = bi.getHeight();
int minx = bi.getMinX();
int miny = bi.getMinY();
System.out.println(width + " " + height);
int speed = 7;
BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
// 獲取影象上下文
Graphics g = createGraphics(bufferedImage, width, height, speed);
// 圖片中文字行高
final int Y_LINEHEIGHT = speed;
int lineNum = 1;
for (int i = miny; i < height; i += speed) {
for (int j = minx; j < width; j += speed) {
int pixel = bi.getRGB(j, i); // 下面三行程式碼將一個數字轉換為RGB數字
int red = (pixel & 0xff0000) >> 16;
int green = (pixel & 0xff00) >> 8;
int blue = (pixel & 0xff);
float gray = 0.299f * red + 0.578f * green + 0.114f * blue;
int index = Math.round(gray * (base.length() + 1) / 255);
// char c = ascii.charAt((int) (gray / 255 * ascii.length()));
// char c = toChar((int) gray);
// char c = toChar(index);
String c = index >= base.length() ? " " : String.valueOf(base.charAt(index));
g.drawString(String.valueOf(c), j, i);
}
lineNum++;
}
g.dispose();
// 儲存為jpg圖片
FileOutputStream fos;
try {
fos = new FileOutputStream(imageFile);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(fos);
OutputStream out = encoder.getOutputStream();
BASE64Encoder base64Encoder = new BASE64Encoder();
encoder.encode(bufferedImage);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ImageFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bufferedImage;
}
/**
* 畫板預設一些引數設定
* @param image 圖片
* @param width 圖片寬
* @param height 圖片高
* @param size 字型大小
* @return
*/
private static Graphics createGraphics(BufferedImage image, int width,
int height, int size) {
Graphics g = image.createGraphics();
g.setColor(null); // 設定背景色
g.fillRect(0, 0, width, height);// 繪製背景
g.setColor(Color.BLACK); // 設定前景色
g.setFont(new Font("微軟雅黑", Font.PLAIN, size)); // 設定字型
return g;
}
/**
* n張jpg轉gif方法
* @param bufferedImages
* @param newPic
* @param playTime
*/
private static void jpgToGif(BufferedImage[] bufferedImages, String newPic,
int playTime) {
try {
AnimatedGifEncoder e = new AnimatedGifEncoder();
e.setRepeat(0);
e.start(newPic);
for (int i = 0; i < bufferedImages.length; i++) {
e.setDelay(playTime); // 設定播放的延遲時間
e.addFrame(bufferedImages[i]); // 新增到幀中
}
e.finish();
} catch (Exception e) {
System.out.println("jpgToGif Failed:");
}
}
}
呼叫程式碼
public static void main(String[] args) throws Exception {
loadGif("C:/Users/Administrator/Desktop/頁面錄屏顯示.gif", "F:/gif/");//動圖轉為動態的字元圖片
}
返回的圖片效果原圖為小程式演示閃圖